My question is, how should I be accessing the “actualCenter” attribute of the primary layout inside of the “LayoutCompleted” DiagramEvent listener. Alternatively, if there is a better/different method I should use to implement the desired node layout.
layout: $(ArrangingLayout,
{ // create a circular arrangement of circular layouts
primaryLayout: $(go.CircularLayout, {
}), // must specify the primaryLayout
arrangingLayout: $(go.CircularLayout, {
spacing: 50,
aspectRatio: .7,
arrangement: go.CircularLayout.ConstantDistance,
nodeDiameterFormula: go.CircularLayout.Circular,
direction: go.CircularLayout.Counterclockwise,
sorting: go.CircularLayout.Forwards
}),
// 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: function (part) { return true; },
// called for each separate connected subgraph
preparePrimaryLayout: function (lay, coll) { // color all of the nodes in each subgraph
var root = null; // find the root node in this subgraph
coll.each(function (node) {
if (node instanceof go.Node && node.findLinksInto().count === 0) {
root = node;
}
});
},
prepareSideLayout: function (lay, coll, b) { // called once for the sideLayout
// adjust how wide the GridLayout lays out
lay.wrappingWidth = Math.max(b.width, this.diagram.viewportBounds.width);
},
}),
// define a DiagramEvent listener
"LayoutCompleted": function (e) {
// now that the CircularLayout has finished, we know where its center is
var cntr = dia.findNodeForKey("Center");
cntr.location = dia.layout.actualCenter;
}
If your situation is like the Arrowheads sample, there is a particular node, which I will call the “root” node, in each subnetwork that is laid out by the ArrangingLayout.primaryLayout. You don’t want that root node to be put in the circle, but you want to put that node at the center of the circle.
So the first step is to make sure the root node is not positioned by the CircularLayout in the ArrangingLayout.preparePrimaryLayout function:
We save the reference to that “root” node on the layout so that at the end of the layout we can put it at the center. That can be accomplished in an override of CircularLayout.commitNodes:
I think I understand, how would I extend just the primary layout’s CircularLayout? I imagine that we dont want to override the arrangingLayout’s commitNodes function.
So I extended the Circular layout class and created an override of the commitNodes class. The only thing that is confusing me is how I should pass the definition of root into the new override class that I have created.
export class CustomCircularLayout extends go.CircularLayout {
// new data properties (fields) get declared and initialized here
constructor() {
super();
// other initializations can be done here
}
public commitNodes() {
if (this.root) this.root.location = this.actualCenter;
}
}
Ok, that resolved my issue to where the website is compiling and loading successfully again. However, when the graph loads in I get:
I think now my issue is that the commitNodes function isnt being called or that I removed the “LayoutCompleted” DiagramEvent listener. Either way, the root nodes of the two sub graphs arent being placed correctly resulting in this.
Any Ideas?
Thanks!
EDIT: What appears to be happening is that the root nodes of the Primary layout are being laid out but the rest of the nodes are being ignored.
Odd, you don’t have any links at all? So basically everything should be laid out by the ArrangingLayout.sideLayout (which defaults to a GridLayout)?
But in that case I don’t understand why all of those pink nodes were arranged in a circle, presumably by a CircularLayout. Unless you set ArrangingLayout.filter to always return true in order to avoid using the sideLayout. In which case the ArrangingLayout.primaryLayout is basically useless, because it would always be operating on a single node each time.
And in that case I don’t understand why there is a gap in your circle and the orange and yellow nodes are located up at the top-left. Unless those are the “root” nodes that you have moved?
I did set ArrangingLayout.filter to true so that all of the primary nodes would be laid out in a circle even if I had not added in the sub node data yet. Should I attach my code to here so that you can get a better look at whats happening.
Those are the “root” nodes that have their layoutposition frozen with:
lay.root.isLayoutPositioned = false;
Here is what it looks like before I switch to using the custom layout with the previous flag commented again.
Isn’t this what you wanted? Hmmm, a CircularLayout of only three nodes doesn’t work so well when moving one of the nodes to the center of the two-node layout. But it seems to work well with five or more nodes.
Yeah, this is exactly what I was trying to achieve. I am using most of the code from that example but with different Node/Link data. Rather could the issue be from me defining specific links instead of using the {key: parent:} data format from the example?
However, the type of model has no effect on layouts, since layouts only operate on Parts (Nodes and Links). Of course using a TreeModel means you cannot have any non-tree-structured graphs, but that doesn’t matter to the layout.
I can’t explain that. Check your code to make sure that when it sets this.root.location = this.actualCenter that it is not setting the wrong node’s location.
Also, note the bug fix I added to my implementation of commitNodes, above.