I really don’t know UML, so pardon me if I am making some invalid assumptions or conclusions.
I do not think that what you are asking for is well-specified. After all, Students can have a bunch of Courses too. Perhaps you are thinking about the “composition” relationship, which this sample does not bother to implement.
TreeLayout cannot do exactly what you are asking for, if I understand you correctly, at least not without some effort. However it is relatively easy to get part of the way there.
function TwoWayTreeLayout() {
go.TreeLayout.call(this);
}
go.Diagram.inherit(TwoWayTreeLayout, go.TreeLayout);
TwoWayTreeLayout.prototype.assignTreeVertexValues = function(v) {
var pedge = v.destinationEdges.first();
v.angle = (pedge && pedge.link.data.relationship === "aggregation") ? 0 : 90;
};
TwoWayTreeLayout.prototype.commitLayout = function() {
go.TreeLayout.prototype.commitLayout.call(this);
var fdlay = new TwoWayForceDirectedLayout();
fdlay.doLayout(this.diagram);
};
function TwoWayForceDirectedLayout() {
go.ForceDirectedLayout.call(this);
}
go.Diagram.inherit(TwoWayForceDirectedLayout, go.ForceDirectedLayout);
TwoWayForceDirectedLayout.prototype.isFixed = function(v) {
return v.edges.any(function(e) { return e.link.data.relationship === "generalization"; });
};
TwoWayForceDirectedLayout.prototype.electricalCharge = function(v) {
return (v.edgesCount === 0) ? 5 : 25;
};
This is a custom TreeLayout that arranges subtrees of “generalization” related nodes with angle 90 and subtrees of “aggregation” related nodes with angle 0. But it does not arrange the root of an “aggregation” tree to be immediately to the right of a node that was laid out in a tree related by “generalization”.
Furthermore, after the TreeLayout is done it uses a custom ForceDirectedLayout to leave the nodes connected by “generalization” alone and move the other nodes so that they are closer to what they are related to, because there might be multiple “aggregation” relationships for any node.
I installed the custom layout in the Diagram initialization as follows:
layout: $(TwoWayTreeLayout,
{
path: go.TreeLayout.PathSource, // links go from child to parent
setsPortSpot: false, // keep Spot.AllSides for link connection spot
setsChildPortSpot: false, // keep Spot.AllSides
// nodes not connected by "generalization" links are laid out horizontally
arrangement: go.TreeLayout.ArrangementVertical
})
I also removed the Binding of Link.isLayoutPositioned:
//new go.Binding("isLayoutPositioned", "relationship", convertIsTreeLink),
Then I deleted the “BankAccount” node and added some simple nodes and aggregation links:
},
{ key: 15, name: "CoursePart1" },
{ key: 16, name: "CoursePart2" },
{ key: 17, name: "CoursePiece" }
];
var linkdata = [
{ from: 12, to: 11, relationship: "generalization" },
{ from: 13, to: 11, relationship: "generalization" },
{ from: 14, to: 13, relationship: "aggregation" },
{ from: 14, to: 12, relationship: "aggregation" },
{ from: 15, to: 14, relationship: "aggregation" },
{ from: 16, to: 14, relationship: "aggregation" },
{ from: 17, to: 15, relationship: "aggregation" }
];
The result is:
