I suspect the problem is that using legacy JavaScript overriding of methods won’t work for the Group.layout because groups are copied. In other words, you may have set properties that are methods on an instance of a layout for the Group.layout, but it won’t get copied when the group template is copied in order to instantiate the Group for a node data in the model.
If you define a subclass instead of doing what the Arranging Layout sample does, it seems to work OK when the layout is of a group’s members:
<!DOCTYPE html>
<html><body>
<div id="myDiagramDiv" style="border: solid 1px black; width:100%; height:800px; min-width: 200px"></div>
<script src="https://unpkg.com/gojs"></script>
<script src="https://unpkg.com/gojs/extensions/ArrangingLayout.js"></script>
<script id="code">
class CustomArrangingLayout extends ArrangingLayout {
constructor() {
super();
// additional custom properties for use by preparePrimaryLayout
this._colors = ["red", "orange", "yellow", "lime", "cyan"]; // possible node colors
this._colorIndex = 0; // cycle through the given colors
}
// called for each separate connected subgraph
// color all of the nodes in each subgraph
preparePrimaryLayout(lay, coll) { // method override requires function, not =>
var root = null; // find the root node in this subgraph
coll.each(node => {
if (node instanceof go.Node && node.findLinksInto().count === 0) root = node;
});
var color = "white"; // determine the color for the nodes in this subgraph
if (root !== null) {
// root.key will be the name of the class that this node represents
// Special case: "LayoutNetwork", "LayoutVertex", and "LayoutEdge" classes are "violet"
if (root.key.indexOf("Layout") === 0 && root.key.length > "Layout".length) {
color = "violet";
} else { // otherwise cycle through the Array of colors
color = this._colors[this._colorIndex++ % this._colors.length];
}
}
coll.each(node => { // assign the fill color for all of the nodes in the subgraph
if (node instanceof go.Node) {
var shape = node.findObject("SHAPE");
if (shape !== null) shape.fill = color;
}
});
}
// called once for the sideLayout
prepareSideLayout(lay, coll, b) { // method override requires function, not =>
// adjust how wide the GridLayout lays out
lay.wrappingWidth = b.width;
}
}
const $ = go.GraphObject.make;
function makeLayout() {
return $(CustomArrangingLayout,
{ // create a circular arrangement of circular layouts
primaryLayout: $(go.CircularLayout), // must specify the primaryLayout
arrangingLayout: $(go.CircularLayout, { nodeDiameterFormula: go.CircularLayout.Circular, spacing: 30 }),
sideLayout: $(go.GridLayout, { wrappingWidth: 1000 }),
// Uncommenting this filter will force all of the nodes and links to go into the main subset and thus
// will cause all those nodes to be arranged by this.arrangingLayout, here a CircularLayout,
// rather than by the this.sideLayout, which by default is a GridLayout.
//filter: part => true,
});
}
myDiagram =
$(go.Diagram, "myDiagramDiv", // create a Diagram for the DIV HTML element
{
initialAutoScale: go.Diagram.Uniform,
layout: makeLayout()
});
myDiagram.nodeTemplate =
$(go.Node, go.Panel.Auto,
$(go.Shape, { name: "SHAPE", figure: "RoundedRectangle", fill: "lightgray" },
new go.Binding("fill", "color")),
$(go.TextBlock, { margin: 2, textAlign: "center" },
new go.Binding("text", "key", s => {
// insert newlines between lowercase followed by uppercase characters
var arr = s.split("");
for (var i = 1; i < arr.length-1; i++) {
var a = arr[i-1];
var b = arr[i];
if (a === a.toLowerCase() && b === b.toUpperCase()) {
arr.splice(i, 0, "\n");
i += 2;
}
}
return arr.join("");
})));
myDiagram.groupTemplate =
$(go.Group, "Auto",
{ layout: makeLayout() },
$(go.Shape, { fill: null }),
$(go.Placeholder)
);
myDiagram.linkTemplate =
$(go.Link,
{ layerName: "Background" },
$(go.Shape));
// Collect all of the data for the model of the class hierarchy
const nda = [ { key: "GROUP", isGroup: true }];
const lda = [];
// Iterate over all of the classes in "go"
for (var k in go) {
var cls = go[k];
if (!cls) continue;
var proto = cls.prototype;
if (!proto) continue;
proto.constructor.className = k; // remember name
// find base class constructor
var base = Object.getPrototypeOf(proto).constructor;
if (base === Object) { // "root" node?
nda.push({ key: k, group: "GROUP" });
} else {
// add a node for this class and a tree-parent reference to the base class name
nda.push({ key: k, group: "GROUP" });
lda.push({ from: base.className, to: k });
}
}
// Create the model for the hierarchy diagram
myDiagram.model = new go.GraphLinksModel(nda, lda);
</script>
</body></html>