-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgojsfieldmapper.html
308 lines (294 loc) · 11.2 KB
/
gojsfieldmapper.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
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
<html>
<head>
<!-- use go-debug.js when developing and go.js when deploying -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/gojs/2.0.2/go-debug.js"></script>
</head>
<body onload="init()">
<div
id="myDiagramDiv"
style="border: solid 1px black; width:100%; height:100%"
></div>
</body>
<script>
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
function makeButton(text, action, visiblePredicate) {
return $("ContextMenuButton",
$(go.TextBlock, text),
{ click: action },
// don't bother with binding GraphObject.visible if there's no predicate
visiblePredicate ? new go.Binding("visible", "", function(o, e) { return o.diagram ? visiblePredicate(o, e) : false; }).ofObject() : {});
}
myDiagram = $(go.Diagram, "myDiagramDiv", {
initialContentAlignment: go.Spot.Center,
validCycle: go.Diagram.CycleNotDirected, // don't allow loops
// For this sample, automatically show the state of the diagram's model on the page
ModelChanged: function(e) {
},
"undoManager.isEnabled": true
});
// This template is a Panel that is used to represent each item in a Panel.itemArray.
// The Panel is data bound to the item object.
var fieldTemplate = $(
go.Panel,
"TableRow", // this Panel is a row in the containing Table
new go.Binding("portId", "name"), // this Panel is a "port"
{
background: "transparent", // so this port's background can be picked by the mouse
fromSpot: go.Spot.LeftRightSides, // links only go from the right side to the left side
toSpot: go.Spot.LeftRightSides,
// allow drawing links from or to this port:
fromLinkable: true,
toLinkable: true
},
{
// allow the user to select items -- the background color indicates whether "selected"
//?? maybe this should be more sophisticated than simple toggling of selection
click: function(e, item) {
// assume "transparent" means not "selected", for items
var oldskips = item.diagram.skipsUndoManager;
item.diagram.skipsUndoManager = true;
if (item.background === "transparent") {
item.background = "dodgerblue";
} else {
item.background = "transparent";
}
item.diagram.skipsUndoManager = oldskips;
}
},
$(
go.TextBlock,
{
margin: new go.Margin(0, 2),
column: 1,
font: "bold 13px sans-serif",
editable: true,
// and disallow drawing links from or to this text:
fromLinkable: false,
toLinkable: false
},
new go.Binding("text", "name").makeTwoWay()
),
$(
go.TextBlock,
{ margin: new go.Margin(0, 2), column: 2, font: "13px sans-serif" },
new go.Binding("text", "info")
)
);
// This template represents a whole "record".
myDiagram.nodeTemplate = $(
go.Node,
"Auto",
new go.Binding("location", "loc", go.Point.parse).makeTwoWay(
go.Point.stringify
),
// this rectangular shape surrounds the content of the node
$(go.Shape, { fill: "#EEEEEE" }),
// the content consists of a header and a list of items
$(go.Panel,
"Vertical",
// this is the header for the whole node
$(go.Panel,
"Auto",
{ stretch: go.GraphObject.Horizontal }, // as wide as the whole node
$(go.Shape, { fill: "#1570A6", stroke: null }),
$(go.TextBlock, {
alignment: go.Spot.Center,
editable: true,
margin: 3,
stroke: "white",
textAlign: "center",
font: "bold 12pt sans-serif"
}, new go.Binding("text", "key")
)
),
// this Panel holds a Panel for each item object in the itemArray;
// each item Panel is defined by the itemTemplate to be a TableRow in this Table
$(go.Panel,
"Table",
{
name: "TABLE",
padding: 2,
minSize: new go.Size(100, 10),
defaultStretch: go.GraphObject.Horizontal,
itemTemplate: fieldTemplate
},
new go.Binding("itemArray", "fields")
),
{
contextMenu: $("ContextMenu", makeButton("New Field", function(e, obj){
var currentDiagram = e.targetDiagram;
var currentNode = obj.part.adornedPart;
currentDiagram.startTransaction("addnewfield")
currentDiagram.model.addArrayItem(currentNode.data.fields, { "name":"field5" })
currentDiagram.commitTransaction("addnewfield")
}))
} // end Table Panel of items
), // end Vertical Panel
); // end Node
myDiagram.contextMenu = $(
"ContextMenu",
$("ContextMenuButton", $(go.TextBlock, "New DataSet"), {
click: function(e, obj) {
e.diagram.commit(function(d) {
var data = { key: "New DataSet", fields: [] };
d.model.addNodeData(data);
part = d.findPartForData(data); // must be same data reference, not a new {}
// set location to saved mouseDownPoint in ContextMenuTool
part.location = d.toolManager.contextMenuTool.mouseDownPoint;
}, "new node");
}
}),
$("ContextMenuButton", $(go.TextBlock, "New Rule"), {
click: function(e, obj) {
e.diagram.commit(function(d) {
var data = { key: "New Rule", fields: [] };
d.model.addNodeData(data);
part = d.findPartForData(data); // must be same data reference, not a new {}
// set location to saved mouseDownPoint in ContextMenuTool
part.location = d.toolManager.contextMenuTool.mouseDownPoint;
}, "new rule");
}
})
);
myDiagram.linkTemplate = $(
go.Link,
{ relinkableFrom: true, relinkableTo: true, toShortLength: 4 }, // let user reconnect links
$(go.Shape, { strokeWidth: 1.5 }),
$(go.Shape, { toArrow: "Standard", stroke: null })
);
myDiagram.model = $(go.GraphLinksModel, {
linkFromPortIdProperty: "fromPort",
linkToPortIdProperty: "toPort",
nodeDataArray: [
{
key: "DataModel",
fields: [
{ name: "field1", info: "", color: "#F7B84B", figure: "Ellipse" },
{
name: "field2",
info: "the second one",
color: "#F25022",
figure: "Ellipse"
},
{ name: "fieldThree", info: "3rd", color: "#00BCF2" }
],
loc: "0 0"
},
{
key: "CAT",
fields: [
{ name: "fieldA", info: "", color: "#FFB900", figure: "Diamond" },
{
name: "fieldB",
info: "",
color: "#F25022",
figure: "Rectangle"
},
{ name: "fieldC", info: "", color: "#7FBA00", figure: "Diamond" },
{
name: "fieldD",
info: "fourth",
color: "#00BCF2",
figure: "Rectangle"
}
],
loc: "200 0"
},
{
key: "FIS",
fields: [
{ name: "fieldA", info: "", color: "#FFB900", figure: "Diamond" },
{
name: "fieldB",
info: "",
color: "#F25022",
figure: "Rectangle"
},
{ name: "fieldC", info: "", color: "#7FBA00", figure: "Diamond" },
{
name: "fieldD",
info: "fourth",
color: "#00BCF2",
figure: "Rectangle"
}
],
loc: "0 250"
}
],
linkDataArray: [
{
from: "DataModel",
fromPort: "field1",
to: "CAT",
toPort: "fieldA"
},
{
from: "DataModel",
fromPort: "field2",
to: "CAT",
toPort: "fieldD"
},
{
from: "DataModel",
fromPort: "fieldThree",
to: "CAT",
toPort: "fieldB"
}
]
});
// this is a bit inefficient, but should be OK for normal-sized graphs with reasonable numbers of items per node
function findAllSelectedItems() {
var items = [];
for (var nit = myDiagram.nodes; nit.next(); ) {
var node = nit.value;
var table = node.findObject("TABLE");
if (table) {
for (var iit = table.elements; iit.next(); ) {
var itempanel = iit.value;
if (itempanel.background !== "transparent") items.push(itempanel);
}
}
}
return items;
}
// Override the standard CommandHandler deleteSelection behavior.
// If there are any selected items, delete them instead of deleting any selected nodes or links.
myDiagram.commandHandler.canDeleteSelection = function() {
// true if there are any selected deletable nodes or links,
// or if there are any selected items within nodes
return (
go.CommandHandler.prototype.canDeleteSelection.call(
myDiagram.commandHandler
) || findAllSelectedItems().length > 0
);
};
myDiagram.commandHandler.deleteSelection = function() {
var items = findAllSelectedItems();
if (items.length > 0) {
// if there are any selected items, delete them
myDiagram.startTransaction("delete items");
for (var i = 0; i < items.length; i++) {
var panel = items[i];
var nodedata = panel.part.data;
var itemarray = nodedata.fields;
var itemdata = panel.data;
var itemindex = itemarray.indexOf(itemdata);
myDiagram.model.removeArrayItem(itemarray, itemindex);
}
myDiagram.commitTransaction("delete items");
} else {
// otherwise just delete nodes and/or links, as usual
go.CommandHandler.prototype.deleteSelection.call(
myDiagram.commandHandler
);
}
};
// showModel(); // show the diagram's initial model
// function showModel() {
// document.getElementById("mySavedModel").textContent = myDiagram.model.toJson();
// }
}
</script>
</html>