-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathconnectionPoints.html
293 lines (264 loc) · 9.79 KB
/
connectionPoints.html
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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>GoJS Link Connection Points on Nodes -- Northwoods Software</title>
<!-- Copyright 1998-2016 by Northwoods Software Corporation. -->
<script src="go.js"></script>
<script src="goIntro.js"></script>
</head>
<body onload="goIntro()">
<div id="container" class="container-fluid">
<div id="content">
<h2>Link Connection Points on Nodes</h2>
<p>
There is flexibility in controlling exactly how and where a link connects to a node.
In the previous examples the link has always ended at the edge of the node.
But you can specify the <a>Spot</a> on a node at which a link terminates.
</p>
<h3>Non-rectangular Nodes</h3>
<p>
When a <a>Node</a> does not have a rectangular shape, by default links will end
where the line toward the center of the node intersects with the edge of the node.
</p>
<p>
Here is a demonstration of that -- drag one of the nodes around and watch how the link always
connects to the nearest intersection or to the center of the node.
This example includes arrowheads at both ends of the link, to make it clear that the link route
really ends right at the edge of the node.
</p>
<pre data-language="javascript" id="nonRectangular">
diagram.nodeTemplate =
$(go.Node, "Auto",
{ width: 90, height: 90,
selectionAdorned: false },
new go.Binding("location", "loc", go.Point.parse),
$(go.Shape, "FivePointedStar", { fill: "lightgray" }),
$(go.TextBlock,
new go.Binding("text", "key"))
);
diagram.linkTemplate =
$(go.Link,
$(go.Shape),
$(go.Shape, // the "from" end arrowhead
{ fromArrow: "Chevron" }),
$(go.Shape, // the "to" end arrowhead
{ toArrow: "StretchedDiamond", fill: "red" })
);
var nodeDataArray = [
{ key: "Alpha", loc: "0 0" },
{ key: "Beta", loc: "100 50" }
];
var linkDataArray = [
{ from: "Alpha", to: "Beta" }
];
diagram.model = new go.GraphLinksModel(nodeDataArray, linkDataArray);
</pre>
<script>goCode("nonRectangular", 600, 150)</script>
<h3>ToSpot and FromSpot</h3>
<p>
You can easily require links to end at a particular point within the bounds of the node,
rather than at the nearest edge intersection.
Set the <a>GraphObject.toSpot</a> to a <a>Spot</a> value other than <a>Spot.None</a>
to cause links coming into the node to end at that spot within the node.
Similarly, set the <a>GraphObject.fromSpot</a> for the ends of links coming out of the node.
</p>
<p>
The following examples all display the same graph but use different templates
to demonstrate how links can connect to nodes.
They all call this common function to define some nodes and links.
</p>
<pre data-language="javascript" id="makeGraph">
function makeGraph(diagram) {
var $ = go.GraphObject.make;
diagram.layout =
$(go.LayeredDigraphLayout, // this will be discussed in a later section
{ columnSpacing: 5,
setsPortSpots: false });
var nodeDataArray = [
{ key: "Alpha" }, { key: "Beta" }, { key: "Gamma" }, { key: "Delta" },
{ key: "Epsilon" }, { key: "Zeta" }, { key: "Eta" }, { key: "Theta" }
];
var linkDataArray = [
{ from: "Beta", to: "Alpha" },
{ from: "Gamma", to: "Alpha" },
{ from: "Delta", to: "Alpha" },
{ from: "Alpha", to: "Epsilon" },
{ from: "Alpha", to: "Zeta" },
{ from: "Alpha", to: "Eta" },
{ from: "Alpha", to: "Theta" }
];
diagram.model = new go.GraphLinksModel(nodeDataArray, linkDataArray);
}
</pre>
<script>eval(document.getElementById("makeGraph").textContent)</script>
<p>
Let us specify that links coming into a node connect at the middle of the left side, and that links going out
of a node connect at the middle of the right side. Such a convention is appropriate for diagrams that have
a general sense of direction to them, such as the following one which goes from left to right.
</p>
<pre data-language="javascript" id="leftright">
diagram.nodeTemplate =
$(go.Node, "Auto",
{ fromSpot: go.Spot.Right, // coming out from middle-right
toSpot: go.Spot.Left }, // going into at middle-left
$(go.Shape, "Rectangle", { fill: "lightgray" }),
$(go.TextBlock,
{ margin: 5},
new go.Binding("text", "key"))
);
diagram.linkTemplate =
$(go.Link,
$(go.Shape),
$(go.Shape, { toArrow: "Standard" })
);
makeGraph(diagram);
</pre>
<script>goCode("leftright", 600, 150)</script>
<p>
You can also specify that the links go into a node not at a single spot but spread out along one side.
Instead of <a>Spot.Right</a> use <a>Spot.RightSide</a>, and similarly for the left side.
</p>
<pre data-language="javascript" id="leftrightSides">
diagram.nodeTemplate =
$(go.Node, "Auto",
{ fromSpot: go.Spot.RightSide, // coming out from right side
toSpot: go.Spot.LeftSide }, // going into at left side
$(go.Shape, "Rectangle", { fill: "lightgray" }),
$(go.TextBlock,
{ margin: 5},
new go.Binding("text", "key"))
);
diagram.linkTemplate =
$(go.Link,
$(go.Shape),
$(go.Shape, { toArrow: "Standard" })
);
makeGraph(diagram);
</pre>
<script>goCode("leftrightSides", 600, 150)</script>
<p>
Of course this only looks good when the nodes are basically rectangular.
</p>
<p>
You can use a different kind of <a>Link.routing</a>:
</p>
<pre data-language="javascript" id="leftrightSidesOrthogonal">
diagram.nodeTemplate =
$(go.Node, "Auto",
{ fromSpot: go.Spot.RightSide, // coming out from right side
toSpot: go.Spot.LeftSide }, // going into at left side
$(go.Shape, "Rectangle", { fill: "lightgray" }),
$(go.TextBlock,
{ margin: 5},
new go.Binding("text", "key"))
);
diagram.linkTemplate =
$(go.Link,
{ routing: go.Link.Orthogonal, // Orthogonal routing
corner: 10 }, // with rounded corners
$(go.Shape),
$(go.Shape, { toArrow: "Standard" })
);
makeGraph(diagram);
</pre>
<script>goCode("leftrightSidesOrthogonal", 600, 150)</script>
<p>
Or you can use a different kind of <a>Link.curve</a>:
</p>
<pre data-language="javascript" id="leftrightSidesBezier">
diagram.nodeTemplate =
$(go.Node, "Auto",
{ fromSpot: go.Spot.RightSide, // coming out from right side
toSpot: go.Spot.LeftSide }, // going into at left side
$(go.Shape, "Rectangle", { fill: "lightgray" }),
$(go.TextBlock,
{ margin: 5},
new go.Binding("text", "key"))
);
diagram.linkTemplate =
$(go.Link,
{ curve: go.Link.Bezier }, // Bezier curve
$(go.Shape),
$(go.Shape, { toArrow: "Standard" })
);
makeGraph(diagram);
</pre>
<script> goCode("leftrightSidesBezier", 600, 150)</script>
<p>
But you need to be careful to specify sensible spots for how the graph is arranged.
</p>
<pre data-language="javascript" id="leftrightSidesBad">
diagram.nodeTemplate =
$(go.Node, "Auto",
{ fromSpot: go.Spot.TopSide, // coming out from top side -- BAD!
toSpot: go.Spot.RightSide }, // going into at right side -- BAD!
$(go.Shape, "Rectangle", { fill: "lightgray" }),
$(go.TextBlock,
{ margin: 5},
new go.Binding("text", "key"))
);
diagram.linkTemplate =
$(go.Link,
$(go.Shape),
$(go.Shape, { toArrow: "Standard" })
);
makeGraph(diagram);
diagram.add($(go.Part, // this is just a comment
{ location: new go.Point(300, 50) },
$(go.TextBlock, "Bad Spots",
{ font: "16pt bold", stroke: "red" })
));
</pre>
<script>goCode("leftrightSidesBad", 600, 150)</script>
<h3>Spots for Individual Links</h3>
<p>
Setting the <a>GraphObject.fromSpot</a> and <a>GraphObject.toSpot</a> properties specifies
the default link connection point for all links connected to the node.
What if you want some links to go to the middle-top spot but some other links to go to the middle-left spot of the same node?
You can achieve this by setting the <a>Link.fromSpot</a> and <a>Link.toSpot</a> properties,
which take precedence over the correspondingly named properties of what the link connects with.
</p>
<pre data-language="javascript" id="customSpots">
diagram.nodeTemplate =
$(go.Node, "Auto",
$(go.Shape, "Rectangle", { fill: "lightgray" }),
$(go.TextBlock,
{ margin: 5},
new go.Binding("text", "key"))
);
diagram.linkTemplate =
$(go.Link,
// get the link spots from the link data
new go.Binding("fromSpot", "fromSpot", go.Spot.parse),
new go.Binding("toSpot", "toSpot", go.Spot.parse),
$(go.Shape),
$(go.Shape, { toArrow: "Standard" })
);
var nodeDataArray = [
{ key: "Alpha" }, { key: "Beta" }, { key: "Gamma" }, { key: "Delta" }
];
var linkDataArray = [
{ from: "Alpha", to: "Beta", fromSpot: "TopRight", toSpot: "Left" },
{ from: "Alpha", to: "Gamma", fromSpot: "Left", toSpot: "Left" },
{ from: "Alpha", to: "Delta", fromSpot: "None", toSpot: "Top" }
];
diagram.model = new go.GraphLinksModel(nodeDataArray, linkDataArray);
</pre>
<script>goCode("customSpots", 600, 150)</script>
<h4>Some Layouts set Link Spots</h4>
<p>
Some of the predefined <a>Layout</a>s automatically set <a>Link.fromSpot</a> and <a>Link.toSpot</a>
when the nature of the layout implies a natural direction.
So, for example, a <a>TreeLayout</a> with a <a>TreeLayout.angle</a> <code>== 0</code> will set each Link's
fromSpot to be <a>Spot.Bottom</a> and each Link's toSpot to be <a>Spot.Top</a>.
</p>
<p>
You can disable the setting of Link spots for TreeLayout by setting <a>TreeLayout.setsPortSpot</a> and/or <a>TreeLayout.setsChildPortSpot</a> to false.
For LayeredDigraphLayout, set <a>LayeredDigraphLayout.setsPortSpots</a> to false.
For ForceDirectedLayout, set <a>ForceDirectedLayout.setsPortSpots</a> to false, although this is rarely needed.
</p>
</div>
</div>
</body>
</html>