Created
June 13, 2020 15:36
-
-
Save addshore/ef380319f97dc87adeebbd64d5f40ad8 to your computer and use it in GitHub Desktop.
Wikidata & WIkibase, Vision Diagram
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<script src=" https://gojs.net/latest/release/go-debug.js"></script> | |
<div id="sample"> | |
<div id="myDiagramDiv" style="border: solid 1px black; width:100%; height:800px;"></div> | |
<button id="SaveButton" onclick="save()">Save</button> | |
<button onclick="load()">Load</button> | |
<button onclick="layoutAll()">Layout</button> | |
Diagram Model saved in JSON format (to persist you must copy this back into the pen): | |
<br /> | |
<textarea id="mySavedModel" style="width:100%;height:400px"> | |
{ "class": "TreeModel", | |
"nodeDataArray": [ | |
{"key":0, "text":"Wikidata & Wikibase", "brush":"gainsboro", "loc":"0 0", "font":"bold 13px sans-serif"}, | |
{"key":3, "parent":0, "text":"For Wikimedia", "brush":"palevioletred", "dir":"left", "loc":"-20 -267.375", "font":"bold 13px sans-serif"}, | |
{"key":32, "parent":3, "text":"Scaling", "brush":"palevioletred", "dir":"left", "loc":"-128.73388671875 -309.625"}, | |
{"text":"UI", "brush":"palegreen", "dir":"right", "parent":0, "key":-56, "loc":"146.19140625 -222.35768543342272", "font":"bold 13px sans-serif"}, | |
{"text":"APIs", "brush":"aquamarine", "dir":"right", "parent":0, "key":-57, "loc":"146.19140625 -98.85768543342272", "font":"bold 13px sans-serif"}, | |
{"text":"For 3rd Parties", "brush":"darkblue", "dir":"left", "parent":0, "key":-54, "loc":"-20 -10.625", "font":"bold 13px sans-serif"}, | |
{"text":"Vue only UI", "brush":"palegreen", "dir":"right", "parent":-56, "key":-60, "loc":"196.19140625 -254.85768543342272"}, | |
{"text":"Component system", "brush":"palegreen", "dir":"right", "parent":-56, "key":-61, "loc":"196.19140625 -228.85768543342272"}, | |
{"text":"Entities", "brush":"palegreen", "dir":"right", "parent":-56, "key":-62, "loc":"196.19140625 -189.85768543342272"}, | |
{"text":"Compact UI", "brush":"palegreen", "dir":"right", "parent":-62, "key":-63, "loc":"258.822265625 -202.85768543342272"}, | |
{"text":"Faster editing", "brush":"palegreen", "dir":"right", "parent":-62, "key":-64, "loc":"258.822265625 -176.85768543342272"}, | |
{"text":"MediaWiki Extensions", "brush":"lightcoral", "parent":0, "key":-52, "loc":"146.19140625 5.357685433422716", "font":"bold 13px sans-serif"}, | |
{"text":"Use modern MW Concepts", "brush":"lightcoral", "parent":-52, "key":-53, "loc":"302.60888671875 -40.142314566577284"}, | |
{"text":"REST", "brush":"aquamarine", "dir":"right", "parent":-57, "key":-55, "loc":"196.19140625 -163.85768543342272"}, | |
{"text":"GraphQL", "brush":"aquamarine", "dir":"right", "parent":-57, "key":-70, "loc":"196.19140625 -137.85768543342272"}, | |
{"text":"Batch", "brush":"aquamarine", "dir":"right", "parent":-57, "key":-71, "loc":"196.19140625 -111.85768543342272"}, | |
{"text":"Deferred", "brush":"aquamarine", "dir":"right", "parent":-57, "key":-72, "loc":"196.19140625 -85.85768543342272"}, | |
{"text":"Extension Registration", "brush":"lightcoral", "parent":-53, "key":-46, "loc":"478.65966796875 -79.14231456657728"}, | |
{"text":"Service Containers", "brush":"lightcoral", "parent":-53, "key":-47, "loc":"478.65966796875 -53.142314566577284"}, | |
{"text":"Modern Services", "brush":"lightcoral", "parent":-53, "key":-50, "loc":"478.65966796875 -27.142314566577284"}, | |
{"text":"Modern Values", "brush":"lightcoral", "parent":-53, "key":-58, "loc":"478.65966796875 -1.1423145665772836"}, | |
{"text":"Consistent structure", "brush":"lightcoral", "parent":-52, "key":-59, "loc":"302.60888671875 24.857685433422716"}, | |
{"text":"PSR4", "brush":"lightcoral", "parent":-59, "key":-73, "loc":"438.21240234375 24.857685433422716"}, | |
{"text":"Libraries", "brush":"goldenrod", "parent":0, "key":-38, "loc":"146.19140625 128.85768543342272", "font":"bold 13px sans-serif"}, | |
{"text":"Consistent tooling", "brush":"goldenrod", "parent":-38, "key":-39, "loc":"221.10498046875 76.85768543342272"}, | |
{"text":"Easier releases", "brush":"goldenrod", "parent":-38, "key":-42, "loc":"221.10498046875 102.85768543342272"}, | |
{"text":"Operation", "brush":"darkblue", "dir":"left", "parent":-54, "key":-44, "loc":"-131.75537109375 -160.125"}, | |
{"text":"Docker images v2", "brush":"darkblue", "dir":"left", "parent":-44, "key":-51, "loc":"-208.84619140625 -199.125"}, | |
{"text":"Documented releases", "brush":"darkblue", "dir":"left", "parent":-44, "key":-78, "loc":"-208.84619140625 -173.125"}, | |
{"text":"Website home for the software", "brush":"darkblue", "dir":"left", "parent":-44, "key":-79, "loc":"-208.84619140625 -147.125"}, | |
{"text":"Entity save resources", "brush":"palevioletred", "dir":"left", "parent":32, "key":-65, "loc":"-191.37109375 -342.125"}, | |
{"text":"Visibility of sub graphs", "brush":"palevioletred", "dir":"left", "parent":32, "key":-43, "loc":"-191.37109375 -277.125"}, | |
{"text":"AbuseFilter", "brush":"palevioletred", "dir":"left", "parent":-65, "key":-66, "loc":"-335.6455078125 -355.125"}, | |
{"text":"Processes", "brush":"lightseagreen", "parent":0, "key":-67, "loc":"146.19140625 232.85768543342272", "font":"bold 13px sans-serif"}, | |
{"text":"Dispatch using jobs", "brush":"lightseagreen", "parent":-67, "key":-68, "loc":"231.2421875 206.85768543342272"}, | |
{"text":"Some processes disabled by default", "brush":"lightseagreen", "parent":-67, "key":-69, "loc":"231.2421875 232.85768543342272"}, | |
{"text":"wb_changes", "brush":"lightseagreen", "parent":-69, "key":-80, "loc":"460.08642578125 232.85768543342272"}, | |
{"text":"PropertySuggestor automation", "brush":"lightseagreen", "parent":-67, "key":-81, "loc":"231.2421875 258.8576854334227"}, | |
{"text":"Recent Changes", "brush":"palevioletred", "dir":"left", "parent":-43, "key":-83, "loc":"-340.47607421875 -303.125"}, | |
{"text":"Search", "brush":"palevioletred", "dir":"left", "parent":-43, "key":-84, "loc":"-340.47607421875 -277.125"}, | |
{"text":"etc.", "brush":"palevioletred", "dir":"left", "parent":-43, "key":-85, "loc":"-340.47607421875 -251.125"}, | |
{"text":"Abstract MediaWiki binding", "brush":"lightcoral", "parent":-52, "key":-86, "loc":"302.60888671875 50.857685433422716"}, | |
{"text":"Better rate control", "brush":"aquamarine", "dir":"right", "parent":-57, "key":-87, "loc":"196.19140625 -59.857685433422716"}, | |
{"text":"Wikibase Core", "brush":"darkblue", "dir":"left", "parent":-54, "key":-74, "loc":"-131.75537109375 -56.125"}, | |
{"text":"Federation", "brush":"darkblue", "dir":"left", "parent":-74, "key":-75, "loc":"-236.28076171875 -95.125"}, | |
{"text":"Include Gadgets", "brush":"darkblue", "dir":"left", "parent":-74, "key":-88, "loc":"-236.28076171875 -69.125"}, | |
{"text":"More Data types", "brush":"darkblue", "dir":"left", "parent":-74, "key":-89, "loc":"-236.28076171875 -43.125"}, | |
{"text":"Non Commons Media", "brush":"darkblue", "dir":"left", "parent":-89, "key":-90, "loc":"-351.654296875 -43.125"}, | |
{"text":"Other Services", "brush":"darkblue", "dir":"left", "parent":-54, "key":-77, "loc":"-131.75537109375 47.875"}, | |
{"text":"Generic Query Service UI", "brush":"darkblue", "dir":"left", "parent":-77, "key":-91, "loc":"-237.72802734375 8.875"}, | |
{"text":"Well Defined", "brush":"goldenrod", "parent":-38, "key":-76, "loc":"221.10498046875 128.85768543342272"}, | |
{"text":"More libraries extracted", "brush":"goldenrod", "parent":-38, "key":-82, "loc":"221.10498046875 154.85768543342272"}, | |
{"text":"Automated management", "brush":"goldenrod", "parent":-38, "key":-92, "loc":"221.10498046875 180.85768543342272"}, | |
{"text":"Wikibase Stack Sandbox", "brush":"darkblue", "dir":"left", "parent":-77, "key":-93, "loc":"-237.72802734375 34.875"}, | |
{"text":"Better defaults", "brush":"darkblue", "dir":"left", "parent":-74, "key":-94, "loc":"-236.28076171875 -17.125"}, | |
{"text":"For Developers", "brush":"gainsboro", "dir":"left", "parent":0, "key":-95, "loc":"-20 288.375", "font":"bold 13px sans-serif"}, | |
{"text":"Development Environment", "brush":"gainsboro", "dir":"left", "parent":-95, "key":-96, "loc":"-134.6435546875 216.875"}, | |
{"text":"Fast", "brush":"gainsboro", "dir":"left", "parent":-96, "key":-97, "loc":"-307.83154296875 190.875"}, | |
{"text":"Featured", "brush":"gainsboro", "dir":"left", "parent":-96, "key":-98, "loc":"-307.83154296875 216.875"}, | |
{"text":"Documentation", "brush":"gainsboro", "dir":"left", "parent":-95, "key":-99, "loc":"-134.6435546875 294.875"}, | |
{"text":"Wikibase Hub", "brush":"gainsboro", "dir":"left", "parent":-99, "key":-100, "loc":"-242.08251953125 268.875"}, | |
{"text":"Versioned", "brush":"gainsboro", "dir":"left", "parent":-99, "key":-101, "loc":"-242.08251953125 294.875"}, | |
{"text":"Diagramed", "brush":"gainsboro", "dir":"left", "parent":-99, "key":-102, "loc":"-242.08251953125 320.875"}, | |
{"text":"Documented optimized configurations", "brush":"darkblue", "dir":"left", "parent":-44, "key":-103, "loc":"-208.84619140625 -121.125"}, | |
{"text":"Misc Triple store support", "brush":"darkblue", "dir":"left", "parent":-77, "key":-104, "loc":"-237.72802734375 60.875"}, | |
{"text":"Granular entity alterations", "brush":"palevioletred", "dir":"left", "parent":-65, "key":-105, "loc":"-335.6455078125 -329.125"}, | |
{"text":"Versioning", "brush":"aquamarine", "dir":"right", "parent":-57, "key":-106, "loc":"196.19140625 -33.857685433422716"}, | |
{"text":"Wikidata developed \"tools\"", "brush":"darkblue", "dir":"left", "parent":-77, "key":-107, "loc":"-237.72802734375 86.875"}, | |
{"text":"Wikibase as a service", "brush":"darkblue", "dir":"left", "parent":-93, "key":-108, "loc":"-401.521484375 34.875"}, | |
{"text":"\"Wikimedia\" as a service", "brush":"darkblue", "dir":"left", "parent":-108, "key":-109, "loc":"-547.23046875 34.875"}, | |
{"text":"Micro contributions", "brush":"palevioletred", "dir":"left", "parent":3, "key":-110, "loc":"-128.73388671875 -251.125"}, | |
{"text":"MediaWiki Extension", "brush":"darkblue", "dir":"left", "parent":-54, "key":-111, "loc":"-131.75537109375 138.875"}, | |
{"text":"Better Authentication", "brush":"darkblue", "dir":"left", "parent":-111, "key":-112, "loc":"-272.41162109375 112.875"}, | |
{"text":"Spam Protection", "brush":"darkblue", "dir":"left", "parent":-111, "key":-113, "loc":"-272.41162109375 138.875"}, | |
{"text":"Seeded data", "brush":"gainsboro", "dir":"left", "parent":-96, "key":-114, "loc":"-307.83154296875 242.875"}, | |
{"text":"Advocacy", "brush":"gainsboro", "dir":"left", "parent":-95, "key":-115, "loc":"-134.6435546875 359.875"}, | |
{"text":"Outreach (Blogs etc)", "brush":"gainsboro", "dir":"left", "parent":-115, "key":-116, "loc":"-211.00439453125 346.875"}, | |
{"text":"SDK / Client libraries", "brush":"gainsboro", "dir":"left", "parent":-115, "key":-117, "loc":"-211.00439453125 372.875"}, | |
{"text":"Inter Project Reconciliation", "brush":"palevioletred", "dir":"left", "parent":3, "key":-118, "loc":"-128.73388671875 -225.125"}, | |
{"text":"Faster imports", "brush":"darkblue", "dir":"left", "parent":-111, "key":-119, "loc":"-272.41162109375 164.875"} | |
]} | |
</textarea> | |
</div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var $ = go.GraphObject.make; | |
myDiagram = $(go.Diagram, "myDiagramDiv", { | |
// when the user drags a node, also move/copy/delete the whole subtree starting with that node | |
"commandHandler.copiesTree": true, | |
"commandHandler.copiesParentKey": true, | |
"commandHandler.deletesTree": true, | |
"draggingTool.dragsTree": true, | |
"undoManager.isEnabled": true | |
}); | |
// when the document is modified, add a "*" to the title and enable the "Save" button | |
myDiagram.addDiagramListener("Modified", function (e) { | |
var button = document.getElementById("SaveButton"); | |
if (button) button.disabled = !myDiagram.isModified; | |
var idx = document.title.indexOf("*"); | |
if (myDiagram.isModified) { | |
if (idx < 0) document.title += "*"; | |
} else { | |
if (idx >= 0) document.title = document.title.substr(0, idx); | |
} | |
}); | |
// a node consists of some text with a line shape underneath | |
myDiagram.nodeTemplate = $( | |
go.Node, | |
"Vertical", | |
{ selectionObjectName: "TEXT" }, | |
$( | |
go.TextBlock, | |
{ | |
name: "TEXT", | |
minSize: new go.Size(30, 15), | |
editable: true | |
}, | |
// remember not only the text string but the scale and the font in the node data | |
new go.Binding("text", "text").makeTwoWay(), | |
new go.Binding("scale", "scale").makeTwoWay(), | |
new go.Binding("font", "font").makeTwoWay() | |
), | |
$( | |
go.Shape, | |
"LineH", | |
{ | |
stretch: go.GraphObject.Horizontal, | |
strokeWidth: 3, | |
height: 3, | |
// this line shape is the port -- what links connect with | |
portId: "", | |
fromSpot: go.Spot.LeftRightSides, | |
toSpot: go.Spot.LeftRightSides | |
}, | |
new go.Binding("stroke", "brush"), | |
// make sure links come in from the proper direction and go out appropriately | |
new go.Binding("fromSpot", "dir", function (d) { | |
return spotConverter(d, true); | |
}), | |
new go.Binding("toSpot", "dir", function (d) { | |
return spotConverter(d, false); | |
}) | |
), | |
// remember the locations of each node in the node data | |
new go.Binding("location", "loc", go.Point.parse).makeTwoWay( | |
go.Point.stringify | |
), | |
// make sure text "grows" in the desired direction | |
new go.Binding("locationSpot", "dir", function (d) { | |
return spotConverter(d, false); | |
}) | |
); | |
// selected nodes show a button for adding children | |
myDiagram.nodeTemplate.selectionAdornmentTemplate = $( | |
go.Adornment, | |
"Spot", | |
$( | |
go.Panel, | |
"Auto", | |
// this Adornment has a rectangular blue Shape around the selected node | |
$(go.Shape, { fill: null, stroke: "dodgerblue", strokeWidth: 3 }), | |
$(go.Placeholder, { margin: new go.Margin(4, 4, 0, 4) }) | |
), | |
// and this Adornment has a Button to the right of the selected node | |
$( | |
"Button", | |
{ | |
alignment: go.Spot.Right, | |
alignmentFocus: go.Spot.Left, | |
click: addNodeAndLink // define click behavior for this Button in the Adornment | |
}, | |
$( | |
go.TextBlock, | |
"+", // the Button content | |
{ font: "bold 8pt sans-serif" } | |
) | |
) | |
); | |
// the context menu allows users to change the font size and weight, | |
// and to perform a limited tree layout starting at that node | |
myDiagram.nodeTemplate.contextMenu = $( | |
"ContextMenu", | |
$("ContextMenuButton", $(go.TextBlock, "Bigger"), { | |
click: function (e, obj) { | |
changeTextSize(obj, 1.1); | |
} | |
}), | |
$("ContextMenuButton", $(go.TextBlock, "Smaller"), { | |
click: function (e, obj) { | |
changeTextSize(obj, 1 / 1.1); | |
} | |
}), | |
$("ContextMenuButton", $(go.TextBlock, "Bold/Normal"), { | |
click: function (e, obj) { | |
toggleTextWeight(obj); | |
} | |
}), | |
$("ContextMenuButton", $(go.TextBlock, "Copy"), { | |
click: function (e, obj) { | |
e.diagram.commandHandler.copySelection(); | |
} | |
}), | |
$("ContextMenuButton", $(go.TextBlock, "Delete"), { | |
click: function (e, obj) { | |
e.diagram.commandHandler.deleteSelection(); | |
} | |
}), | |
$("ContextMenuButton", $(go.TextBlock, "Undo"), { | |
click: function (e, obj) { | |
e.diagram.commandHandler.undo(); | |
} | |
}), | |
$("ContextMenuButton", $(go.TextBlock, "Redo"), { | |
click: function (e, obj) { | |
e.diagram.commandHandler.redo(); | |
} | |
}), | |
$("ContextMenuButton", $(go.TextBlock, "Layout"), { | |
click: function (e, obj) { | |
var adorn = obj.part; | |
adorn.diagram.startTransaction("Subtree Layout"); | |
layoutTree(adorn.adornedPart); | |
adorn.diagram.commitTransaction("Subtree Layout"); | |
} | |
}) | |
); | |
// a link is just a Bezier-curved line of the same color as the node to which it is connected | |
myDiagram.linkTemplate = $( | |
go.Link, | |
{ | |
curve: go.Link.Bezier, | |
fromShortLength: -2, | |
toShortLength: -2, | |
selectable: false | |
}, | |
$( | |
go.Shape, | |
{ strokeWidth: 3 }, | |
new go.Binding("stroke", "toNode", function (n) { | |
if (n.data.brush) return n.data.brush; | |
return "black"; | |
}).ofObject() | |
) | |
); | |
// the Diagram's context menu just displays commands for general functionality | |
myDiagram.contextMenu = $( | |
"ContextMenu", | |
$( | |
"ContextMenuButton", | |
$(go.TextBlock, "Paste"), | |
{ | |
click: function (e, obj) { | |
e.diagram.commandHandler.pasteSelection( | |
e.diagram.toolManager.contextMenuTool.mouseDownPoint | |
); | |
} | |
}, | |
new go.Binding("visible", "", function (o) { | |
return ( | |
o.diagram && | |
o.diagram.commandHandler.canPasteSelection( | |
o.diagram.toolManager.contextMenuTool.mouseDownPoint | |
) | |
); | |
}).ofObject() | |
), | |
$( | |
"ContextMenuButton", | |
$(go.TextBlock, "Undo"), | |
{ | |
click: function (e, obj) { | |
e.diagram.commandHandler.undo(); | |
} | |
}, | |
new go.Binding("visible", "", function (o) { | |
return o.diagram && o.diagram.commandHandler.canUndo(); | |
}).ofObject() | |
), | |
$( | |
"ContextMenuButton", | |
$(go.TextBlock, "Redo"), | |
{ | |
click: function (e, obj) { | |
e.diagram.commandHandler.redo(); | |
} | |
}, | |
new go.Binding("visible", "", function (o) { | |
return o.diagram && o.diagram.commandHandler.canRedo(); | |
}).ofObject() | |
), | |
$("ContextMenuButton", $(go.TextBlock, "Save"), { | |
click: function (e, obj) { | |
save(); | |
} | |
}), | |
$("ContextMenuButton", $(go.TextBlock, "Load"), { | |
click: function (e, obj) { | |
load(); | |
} | |
}) | |
); | |
myDiagram.addDiagramListener("SelectionMoved", function (e) { | |
var rootX = myDiagram.findNodeForKey(0).location.x; | |
myDiagram.selection.each(function (node) { | |
if (node.data.parent !== 0) return; // Only consider nodes connected to the root | |
var nodeX = node.location.x; | |
if (rootX < nodeX && node.data.dir !== "right") { | |
updateNodeDirection(node, "right"); | |
} else if (rootX > nodeX && node.data.dir !== "left") { | |
updateNodeDirection(node, "left"); | |
} | |
layoutTree(node); | |
}); | |
}); | |
// read in the predefined graph using the JSON format data held in the "mySavedModel" textarea | |
load(); | |
////} | |
function spotConverter(dir, from) { | |
if (dir === "left") { | |
return from ? go.Spot.Left : go.Spot.Right; | |
} else { | |
return from ? go.Spot.Right : go.Spot.Left; | |
} | |
} | |
function changeTextSize(obj, factor) { | |
var adorn = obj.part; | |
adorn.diagram.startTransaction("Change Text Size"); | |
var node = adorn.adornedPart; | |
var tb = node.findObject("TEXT"); | |
tb.scale *= factor; | |
adorn.diagram.commitTransaction("Change Text Size"); | |
} | |
function toggleTextWeight(obj) { | |
var adorn = obj.part; | |
adorn.diagram.startTransaction("Change Text Weight"); | |
var node = adorn.adornedPart; | |
var tb = node.findObject("TEXT"); | |
// assume "bold" is at the start of the font specifier | |
var idx = tb.font.indexOf("bold"); | |
if (idx < 0) { | |
tb.font = "bold " + tb.font; | |
} else { | |
tb.font = tb.font.substr(idx + 5); | |
} | |
adorn.diagram.commitTransaction("Change Text Weight"); | |
} | |
function updateNodeDirection(node, dir) { | |
myDiagram.model.setDataProperty(node.data, "dir", dir); | |
// recursively update the direction of the child nodes | |
var chl = node.findTreeChildrenNodes(); // gives us an iterator of the child nodes related to this particular node | |
while (chl.next()) { | |
updateNodeDirection(chl.value, dir); | |
} | |
} | |
function addNodeAndLink(e, obj) { | |
var adorn = obj.part; | |
var diagram = adorn.diagram; | |
diagram.startTransaction("Add Node"); | |
var oldnode = adorn.adornedPart; | |
var olddata = oldnode.data; | |
// copy the brush and direction to the new node data | |
var newdata = { | |
text: "idea", | |
brush: olddata.brush, | |
dir: olddata.dir, | |
parent: olddata.key | |
}; | |
diagram.model.addNodeData(newdata); | |
layoutTree(oldnode); | |
diagram.commitTransaction("Add Node"); | |
// if the new node is off-screen, scroll the diagram to show the new node | |
var newnode = diagram.findNodeForData(newdata); | |
if (newnode !== null) diagram.scrollToRect(newnode.actualBounds); | |
} | |
function layoutTree(node) { | |
if (node.data.key === 0) { | |
// adding to the root? | |
layoutAll(); // lay out everything | |
} else { | |
// otherwise lay out only the subtree starting at this parent node | |
var parts = node.findTreeParts(); | |
layoutAngle(parts, node.data.dir === "left" ? 180 : 0); | |
} | |
} | |
function layoutAngle(parts, angle) { | |
var layout = go.GraphObject.make(go.TreeLayout, { | |
angle: angle, | |
arrangement: go.TreeLayout.ArrangementFixedRoots, | |
nodeSpacing: 5, | |
layerSpacing: 20, | |
setsPortSpot: false, // don't set port spots since we're managing them with our spotConverter function | |
setsChildPortSpot: false | |
}); | |
layout.doLayout(parts); | |
} | |
function layoutAll() { | |
var root = myDiagram.findNodeForKey(0); | |
if (root === null) return; | |
myDiagram.startTransaction("Layout"); | |
// split the nodes and links into two collections | |
var rightward = new go.Set(/*go.Part*/); | |
var leftward = new go.Set(/*go.Part*/); | |
root.findLinksConnected().each(function (link) { | |
var child = link.toNode; | |
if (child.data.dir === "left") { | |
leftward.add(root); // the root node is in both collections | |
leftward.add(link); | |
leftward.addAll(child.findTreeParts()); | |
} else { | |
rightward.add(root); // the root node is in both collections | |
rightward.add(link); | |
rightward.addAll(child.findTreeParts()); | |
} | |
}); | |
// do one layout and then the other without moving the shared root node | |
layoutAngle(rightward, 0); | |
layoutAngle(leftward, 180); | |
myDiagram.commitTransaction("Layout"); | |
} | |
// Show the diagram's model in JSON format | |
function save() { | |
document.getElementById("mySavedModel").value = myDiagram.model.toJson(); | |
myDiagram.isModified = false; | |
} | |
function load() { | |
myDiagram.model = go.Model.fromJson( | |
document.getElementById("mySavedModel").value | |
); | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment