The custom SideTreeLayout defined and used in that sample makes use of the “Bus” alignment, which lays out the assistants in two columns on either side of “the aisle of a bus”. So if you had implemented your assistant-adding functionality in the following manner:
function addAssistant() {
myDiagram.model.commit(function(m) {
m.addNodeData({ name: "new person", title: "something fancy", isAssistant: true, parent: 1 });
}, "added assistant");
}
you would have found that the assistants would alternate sides rather than stay on just the right side. The natural inclination would be to change that TreeVertex.alignment from go.TreeLayout.AlignmentBus
to go.TreeLayout.AlignmentBottomRightBus
in the override of assignTreeVertexValues. However that would make all of the children be aligned on the right, which happens to be something like what you show in your screenshot.
In your situation the cause of the link coming in on the right side rather than the (shorter, more natural left side) is due to the code that implements “Bus” alignment. It’s thinking that that node really belongs on the left side, which is why the link is coming into the node’s right side.
But if you are using a TreeVertex.alignment of go.TreeLayout.AlignmentBottomRightBus
in the override of assignTreeVertexValues, then you don’t need to worry about having dummy vertexes in the LayoutNetwork to pretend to be on the left side of the bus. So you can change the override of makeNetwork not create any dummy vertexes.
SideTreeLayout.prototype.makeNetwork = function(coll) {
var net = go.TreeLayout.prototype.makeNetwork.call(this, coll);
// copy the collection of TreeVertexes, because we will modify the network
var vertexcoll = new go.Set(/*go.TreeVertex*/);
vertexcoll.addAll(net.vertexes);
for (var it = vertexcoll.iterator; it.next();) {
var parent = it.value;
// count the number of assistants
var acount = 0;
var ait = parent.destinationVertexes;
while (ait.next()) {
if (isAssistant(ait.value.node)) acount++;
}
// if a vertex has some number of children that should be assistants
if (acount > 0) {
// remember the assistant edges and the regular child edges
var asstedges = new go.Set(/*go.TreeEdge*/);
var childedges = new go.Set(/*go.TreeEdge*/);
var eit = parent.destinationEdges;
while (eit.next()) {
var e = eit.value;
if (isAssistant(e.toVertex.node)) {
asstedges.add(e);
} else {
childedges.add(e);
}
}
// first remove all edges from PARENT
eit = asstedges.iterator;
while (eit.next()) { parent.deleteDestinationEdge(eit.value); }
eit = childedges.iterator;
while (eit.next()) { parent.deleteDestinationEdge(eit.value); }
// now PARENT should get all of the assistant children
eit = asstedges.iterator;
while (eit.next()) {
parent.addDestinationEdge(eit.value);
}
// create substitute vertex to be new parent of all regular children
var subst = net.createVertex();
net.addVertex(subst);
// reparent regular children to the new substitute vertex
eit = childedges.iterator;
while (eit.next()) {
var ce = eit.value;
ce.fromVertex = subst;
subst.addDestinationEdge(ce);
}
// finally can add substitute vertex as the final odd child,
// to be positioned at the end of the PARENT's immediate subtree.
var newedge = net.linkVertexes(parent, subst, null);
}
}
return net;
};
SideTreeLayout.prototype.assignTreeVertexValues = function(v) {
// if a vertex has any assistants, use Bus alignment
var any = false;
var children = v.children;
for (var i = 0; i < children.length; i++) {
var c = children[i];
if (isAssistant(c.node)) {
any = true;
break;
}
}
if (any) {
// this is the parent for the assistant(s)
v.alignment = go.TreeLayout.AlignmentBottomRightBus; // this is required
v.nodeSpacing = 50; // control the distance of the assistants from the parent's main links
} else if (v.node == null && v.childrenCount > 0) {
// found the substitute parent for non-assistant children
v.alignment = go.TreeLayout.AlignmentStart;
v.nodeIndent = -200;
v.layerSpacing = 0;
}
};
I’m not sure about trying to line up the left side of the parent node with the left side of the first non-assistant child node. My first attempt was to set v.nodeIndent
of the dummy parent node for the non-assistant children, but that didn’t work – it doesn’t accept negative values, such as the -200 that I tried.