gojs
Version:
Interactive diagrams, charts, and graphs, such as trees, flowcharts, orgcharts, UML, BPMN, or business diagrams
177 lines (162 loc) • 7.52 kB
HTML
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>GoJS SubGraphs -- 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>Groups as SubGraphs</h2>
<p>
There are some common ways of treating the nodes and links that are the members of a group as if it were its own graph.
A <a>Group</a> has its own <a>Group.layout</a> that is responsible for the positioning of member <a>Node</a>s
and the routing of member <a>Link</a>s.
One way to declutter a diagram is to "collapse" a <a>Group</a> to hide the subgraph that it holds.
</p>
<p>
Keep in mind that subgraphs are not separate Diagrams and that Groups are just one way of organizing Parts.
</p>
<h3>Layouts of SubGraphs</h3>
<p>
You can specify a <a>Layout</a> that applies to a group's subgraph by setting the <a>Group.layout</a> property.
This operates on the group's member nodes and links as if it were its own diagram.
A diagram layout of nodes that include groups with their own layout will treat those groups
as if they were simple nodes, albeit probably larger than normal nodes.
</p>
<p>
In this example the group has a different layout than the layout for the whole diagram.
In this case the only difference is the direction in which the layout works,
but you could use a completely different layout algorithm.
</p>
<p>
For simplicity these examples use the default templates for nodes and links.
</p>
<pre data-language="javascript" id="layouts">
diagram.groupTemplate =
$(go.Group, "Auto",
// declare the Group.layout:
{ layout: $(go.LayeredDigraphLayout,
{ direction: 0, columnSpacing: 10 }) },
$(go.Shape, "RoundedRectangle", // surrounds everything
{ parameter1: 10, fill: "rgba(128,128,128,0.33)" }),
$(go.Panel, "Vertical", // position header above the subgraph
$(go.TextBlock, // group title near top, next to button
{ font: "Bold 12pt Sans-Serif" },
new go.Binding("text", "key")),
$(go.Placeholder, // represents area for all member parts
{ padding: 5, background: "white" })
)
);
// declare the Diagram.layout:
diagram.layout = $(go.LayeredDigraphLayout,
{ direction: 90, layerSpacing: 10 });
diagram.initialContentAlignment = go.Spot.Center;
var nodeDataArray = [
{ key: "Alpha" },
{ key: "Omega", isGroup: true },
{ key: "Beta", group: "Omega" },
{ key: "Gamma", group: "Omega" },
{ key: "Epsilon", group: "Omega" },
{ key: "Zeta", group: "Omega" },
{ key: "Delta" }
];
var linkDataArray = [
{ from: "Alpha", to: "Omega" }, // from a Node to the Group
{ from: "Beta", to: "Gamma" }, // this link is a member of the Group
{ from: "Beta", to: "Epsilon" }, // this link is a member of the Group
{ from: "Gamma", to: "Zeta" }, // this link is a member of the Group
{ from: "Epsilon", to: "Zeta" }, // this link is a member of the Group
{ from: "Omega", to: "Delta" } // from the Group to a Node
];
diagram.model = new go.GraphLinksModel(nodeDataArray, linkDataArray);
</pre>
<script>goCode("layouts", 600, 250)</script>
<p>
The default layout for a Group is an instance of <a>Layout</a>, just as it is for <a>Diagram</a>.
So if you do not specify a value for <a>Group.layout</a>, the default layout for the group will position
all member nodes that do not have a real <a>Part.location</a>.
</p>
<p>
If you explicitly set <a>Group.layout</a> to null, the Diagram will be responsible for laying out all of
Nodes and Links as if the Group did not exist.
This is possible because a subgraph is not another <a>Diagram</a>.
</p>
<h3>Collapsing and Expanding Groups</h3>
<p>
One common technique to visually simplify a diagram is to hide parts of them by "collapsing" them.
In the case of <a>Group</a>s, it may make sense to be able to hide the subgraph.
</p>
<p>
To collapse a group, set <a>Group.isSubGraphExpanded</a> to false; to make sure it is expanded,
set that property to true.
</p>
<p>
It is commonplace to provide a button on a group to allow users to collapse and expand groups as they wish.
<b>GoJS</b> makes this easy to implement by providing a predefined kind of <a>Panel</a>, named "SubGraphExpanderButton",
that acts as a button to collapse and expand <a>Group</a>s.
This button changes the visibility of the member nodes and links but does not change
the visibility of the group itself.
When the group's visual tree includes a <a>Placeholder</a>, the placeholder will automatically
shrink when the member parts become invisible and will inflate when the member parts become visible again.
</p>
<p>
Click on the expander button to collapse or expand the group.
Changing the size of the group also invalidates the layout that is responsible for positioning the group as a single node.
Often the size of the group changes greatly, so a layout usually needs to be performed again.
</p>
<pre data-language="javascript" id="collapseExpand">
diagram.groupTemplate =
$(go.Group, "Auto",
{ layout: $(go.LayeredDigraphLayout,
{ direction: 0, columnSpacing: 10 }) },
$(go.Shape, "RoundedRectangle", // surrounds everything
{ parameter1: 10, fill: "rgba(128,128,128,0.33)" }),
$(go.Panel, "Vertical", // position header above the subgraph
{ defaultAlignment: go.Spot.Left },
$(go.Panel, "Horizontal", // the header
{ defaultAlignment: go.Spot.Top },
$("SubGraphExpanderButton"), // this Panel acts as a Button
$(go.TextBlock, // group title near top, next to button
{ font: "Bold 12pt Sans-Serif" },
new go.Binding("text", "key"))
),
$(go.Placeholder, // represents area for all member parts
{ padding: new go.Margin(0, 10), background: "white" })
)
);
diagram.layout = $(go.LayeredDigraphLayout,
{ direction: 90, layerSpacing: 10 });
diagram.initialContentAlignment = go.Spot.Center;
var nodeDataArray = [
{ key: "Alpha" },
{ key: "Omega", isGroup: true },
{ key: "Beta", group: "Omega" },
{ key: "Gamma", group: "Omega" },
{ key: "Epsilon", group: "Omega" },
{ key: "Zeta", group: "Omega" },
{ key: "Delta" }
];
var linkDataArray = [
{ from: "Alpha", to: "Omega" }, // from a Node to the Group
{ from: "Beta", to: "Gamma" }, // this link is a member of the Group
{ from: "Beta", to: "Epsilon" }, // this link is a member of the Group
{ from: "Gamma", to: "Zeta" }, // this link is a member of the Group
{ from: "Epsilon", to: "Zeta" }, // this link is a member of the Group
{ from: "Omega", to: "Delta" } // from the Group to a Node
];
diagram.model = new go.GraphLinksModel(nodeDataArray, linkDataArray);
</pre>
<script>goCode("collapseExpand", 600, 250)</script>
<p>
If you do not want a layout to be performed again when the group changes size,
you can set the <a>Part.layoutConditions</a> property to control the circumstances under which
the layout will be invalidated.
</p>
</div>
</div>
</body>
</html>