forked from NorthwoodsSoftware/GoJS
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgrouping.html
147 lines (140 loc) · 6.25 KB
/
grouping.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
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Grouping</title>
<meta name="description" content="A diagram holding groups that incrementally grow the diagram as groups are expanded." />
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Copyright 1998-2019 by Northwoods Software Corporation. -->
<script src="../release/go.js"></script>
<script src="../assets/js/goSamples.js"></script> <!-- this is only for the GoJS Samples framework -->
<script id="code">
function init() {
if (window.goSamples) goSamples(); // init for these samples -- you don't need to call this
var $ = go.GraphObject.make; // for conciseness in defining templates
myDiagram =
$(go.Diagram, "myDiagramDiv", // Diagram refers to its DIV HTML element by id
{
layout: $(go.TreeLayout, // the layout for the entire diagram
{
angle: 90,
arrangement: go.TreeLayout.ArrangementHorizontal,
isRealtime: false
})
});
// define the node template for non-groups
myDiagram.nodeTemplate =
$(go.Node, "Auto",
$(go.Shape, "Rectangle",
{ stroke: null, strokeWidth: 0 },
new go.Binding("fill", "key")),
$(go.TextBlock,
{ margin: 7, font: "Bold 14px Sans-Serif" },
//the text, color, and key are all bound to the same property in the node data
new go.Binding("text", "key"))
);
myDiagram.linkTemplate =
$(go.Link,
{ routing: go.Link.Orthogonal, corner: 10 },
$(go.Shape, { strokeWidth: 2 }),
$(go.Shape, { toArrow: "OpenTriangle" })
);
// define the group template
myDiagram.groupTemplate =
$(go.Group, "Auto",
{ // define the group's internal layout
layout: $(go.TreeLayout,
{ angle: 90, arrangement: go.TreeLayout.ArrangementHorizontal, isRealtime: false }),
// the group begins unexpanded;
// upon expansion, a Diagram Listener will generate contents for the group
isSubGraphExpanded: false,
// when a group is expanded, if it contains no parts, generate a subGraph inside of it
subGraphExpandedChanged: function(group) {
if (group.memberParts.count === 0) {
randomGroup(group.data.key);
}
}
},
$(go.Shape, "Rectangle",
{ fill: null, stroke: "gray", strokeWidth: 2 }),
$(go.Panel, "Vertical",
{ defaultAlignment: go.Spot.Left, margin: 4 },
$(go.Panel, "Horizontal",
{ defaultAlignment: go.Spot.Top },
// the SubGraphExpanderButton is a panel that functions as a button to expand or collapse the subGraph
$("SubGraphExpanderButton"),
$(go.TextBlock,
{ font: "Bold 18px Sans-Serif", margin: 4 },
new go.Binding("text", "key"))
),
// create a placeholder to represent the area where the contents of the group are
$(go.Placeholder,
{ padding: new go.Margin(0, 10) })
) // end Vertical Panel
); // end Group
// generate the initial model
randomGroup();
}
// Generate a random number of nodes, including groups.
// If a group's key is given as a parameter, put these nodes inside it
function randomGroup(group) {
// all modification to the diagram is within this transaction
myDiagram.startTransaction("addGroupContents");
var addedKeys = []; // this will contain the keys of all nodes created
var groupCount = 0; // the number of groups in the diagram, to determine the numbers in the keys of new groups
myDiagram.nodes.each(function(node) {
if (node instanceof go.Group) groupCount++;
});
// create a random number of groups
// ensure there are at least 10 groups in the diagram
var groups = Math.floor(Math.random() * 2);
if (groupCount < 10) groups += 1;
for (var i = 0; i < groups; i++) {
var name = "group" + (i + groupCount);
myDiagram.model.addNodeData({ key: name, isGroup: true, group: group });
addedKeys.push(name);
}
var nodes = Math.floor(Math.random() * 3) + 2;
// create a random number of non-group nodes
for (var i = 0; i < nodes; i++) {
var color = go.Brush.randomColor();
// make sure the color, which will be the node's key, is unique in the diagram before adding the new node
if (myDiagram.findPartForKey(color) === null) {
myDiagram.model.addNodeData({ key: color, group: group });
addedKeys.push(color);
}
}
// add at least one link from each node to another
// this could result in clusters of nodes unreachable from each other, but no lone nodes
var arr = [];
for (var x in addedKeys) arr.push(addedKeys[x]);
arr.sort(function(x, y) { return Math.random(2) - 1; });
for (var i = 0; i < arr.length; i++) {
var from = Math.floor(Math.random() * (arr.length - i)) + i;
if (from !== i) {
myDiagram.model.addLinkData({ from: arr[from], to: arr[i] });
}
}
myDiagram.commitTransaction("addGroupContents");
}
</script>
</head>
<body onload="init()">
<div id="sample">
<div id="myDiagramDiv" style="height:600px;width:100%;border:1px solid black"></div>
<p>
This sample demonstrates subgraphs that are created only as groups are expanded.
</p>
<p>
The model is initially a random number of nodes, including some groups, in a tree layout.
When a group is expanded, the <a>Group.subGraphExpandedChanged</a> event handler calls a function to generate a random number of nodes
in a tree layout inside the group if it did not contain none any.
Each non-group node added has a unique random color, and links are added by giving each node one link to another node.
</p>
<p>
The addition of nodes and links is performed within a transaction to ensure that the diagram updates itself properly.
The diagram's tree layout and the tree layouts within each group are performed again when a sub-graph is expanded or collapsed.
</p>
</div>
</body>
</html>