UNPKG

gojs

Version:

Interactive diagrams, charts, and graphs, such as trees, flowcharts, orgcharts, UML, BPMN, or business diagrams

147 lines (140 loc) 6.54 kB
<!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-2020 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>