-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathSpringGraphMorph.class.st
More file actions
92 lines (82 loc) · 2.75 KB
/
Copy pathSpringGraphMorph.class.st
File metadata and controls
92 lines (82 loc) · 2.75 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
Class {
#name : #SpringGraphMorph,
#superclass : #GraphMorph,
#category : #'Mathematics-Graphs-Morphic'
}
{ #category : #'event handling' }
SpringGraphMorph >> allowSubmorphExtraction [
" allow extraction so submorphs can be grabbed and dragged to a new position.
usefull to rearrange the vertices manually"
^ true
]
{ #category : #stepping }
SpringGraphMorph >> approachComponents [
| componentsDesiredDistance |
(components isNil or: [components size < 2])
ifTrue: [^ self].
componentsDesiredDistance := 1.
components do: [:each|
components do: [:other|
each == other
ifFalse:
[| source target f currentDistance diff delta |
source := each atRandom.
target := other atRandom.
(currentDistance := (diff := source x + source dx - target x - target dx) norm) > componentsDesiredDistance
ifTrue:
[f := (componentsDesiredDistance - currentDistance) asFloat / (currentDistance * 4).
delta := diff * f / 2.
"target dx: target dx - delta."
source dx: source dx + (delta/other size)]]]]
]
{ #category : #stepping }
SpringGraphMorph >> aproachConnectedNodes [
self edgesDo: [:each| each approachNodes]
]
{ #category : #accessing }
SpringGraphMorph >> desiredDistance: aNumber [
^ self edgesDo: [:each| each desiredDistance: aNumber]
]
{ #category : #private }
SpringGraphMorph >> edgeClass [
^ SpringEdgeMorph
]
{ #category : #accessing }
SpringGraphMorph >> graph: aGraph [
| morph desiredDistance |
super graph: aGraph.
(aGraph isKindOf: RootedDigraph)
ifTrue: [morph := nodeToMorph at: aGraph rootNode.
morph morphAlign: morph morphBounds center with: self morphExtent // 2].
aGraph size < 100
ifTrue: [desiredDistance := (self morphLocalBounds area / (aGraph radius min: 10) / 2) sqrt.
components := graph components asArray collect: [:each| each asArray collect: [:node| nodeToMorph at: node]]]
ifFalse:
[desiredDistance := 10.
components := nil].
self edgesDo: [:each| each desiredDistance: desiredDistance "/ each source node degree sqrt"]
]
{ #category : #private }
SpringGraphMorph >> nodeClass [
^ SpringNodeMorph
]
{ #category : #'event handling' }
SpringGraphMorph >> scaleEdgesBy: aNumber [
self edgesDo: [:each| each desiredDistance: each desiredDistance * aNumber].
self startStepping
]
{ #category : #stepping }
SpringGraphMorph >> separateAllNodes [
self nodesDo: [:each | each separateFromAllNodes]
]
{ #category : #stepping }
SpringGraphMorph >> step [
| maxDelta |
self nodesDo: [:each| each dampBy: 1.1]. "damping"
self aproachConnectedNodes; separateAllNodes; "approachComponents;" alignToCenter.
maxDelta := 0.
self nodesDo: [:each| maxDelta := maxDelta max: each doMove].
self edgesDo: [:each| each adjustBounds].
self redrawNeeded.
maxDelta < 0.1 ifTrue: [self stopStepping]
]