Here’s my code for the linkTemplate:
myDiagram.linkTemplate =
$$(go.Link,
{ routing: go.Link.AvoidsNodes, curve: go.Link.JumpGap, corner: 5, fromEndSegmentLength: 20, toEndSegmentLength: 20 },
$$(go.Shape, { strokeWidth: 3, stroke: "#555", strokeDashArray: [10, 5] }, // this shape is the link itself
new go.Binding("strokeDashArray", "ownership_strokedash")
),
$$(go.Shape, { toArrow: "" }, // this shape is the arrowhead
new go.Binding("toArrow", "to_arrow"), // to_arrow = "Standard"
new go.Binding("fill", "arrow_fill_color"),
),
$$(go.Panel, "Auto", { }, // this whole Panel is a link label
$$(go.Shape, "RoundedRectangle", { fill: "lightgray", stroke: "gray" },
new go.Binding("fill", "ownership_fill_color"),
new go.Binding("stroke", "ownership_border_color"),
new go.Binding("strokeWidth", "ownership_border_thickness"),
),
$$(go.TextBlock, { margin: 3 },
new go.Binding("text", "amount"),
new go.Binding("stroke", "ownership_font_color"),
new go.Binding("font", "ownership_font"),)
)
);
Here’s my code for the diagram, which determines the location of the link panel based on how many links are coming out of / going into the node:
myDiagram =
$$(go.Diagram, "myDiagramDiv",
{
initialContentAlignment: go.Spot.Center,
initialAutoScale: go.Diagram.UniformToFill,
layout: $$(go.LayeredDigraphLayout,
{ direction: 90, layerSpacing: 100, layeringOption: go.LayeredDigraphLayout.LayerLongestPathSource }),
"LayoutCompleted": function(e) {
// Push all link panels to the very beginning of the link (close to the bottom of the parent) as a starting point to be adjusted below
e.diagram.links.each(function(l) { l.elt(1).segmentIndex = -Infinity; });
// loop through every node on the diagram
e.diagram.nodes.each(function(n) {
// get all of the links that leave from the node
var outLinks = n.findLinksOutOf();
// count the number of links leaving the node
var numOuts = outLinks.count
// if there are any links leaving the node, style the link based on the following cases:
if (numOuts > 0) {
outLinks.each(function(link) {
// follow the link to it's destination node and determine how many total links are entering this destination node
var subsNumOfIns = link.toNode.findLinksInto().count
if(numOuts === 1 && subsNumOfIns === 1) {
// if the link is the only one out of the parent and the only one into the sub, put the label halfway along the link
link.elt(1).segmentIndex = NaN;
link.elt(1).segmentFraction = 0.5;
} else if (numOuts === 1 && subsNumOfIns > 1) {
// if the link is the only one out of the parent but one of many into the sub, put the label right below the parent
link.elt(1).segmentIndex = 1;
} else if (numOuts > 1 && subsNumOfIns === 1) {
// if the link is one of many out of the parent but the only one into the sub, put the label right above the sub
link.elt(1).segmentIndex = -2;
} else if (numOuts > 1 && subsNumOfIns > 1) {
// if the link is one of many out of the parent and one of many into the sub:
if(link.toNode.position.y - link.fromNode.position.y < 225) {
// if only one row apart (i.e. less than 175 points on the coordinate plane apart)
// make the links straight lines (e.g. "Normal") instead of orthagonal
link.routing = go.Link.Normal
// remove the end segment lenths (the vertical portions of the links immediately above/below nodes)
link.fromEndSegmentLength = 0;
link.toEndSegmentLength = 0;
// have the link label appear 1/4 of the way along the straight line or 40% along if there are more than 3 outs from the entity (to give more space)
link.elt(1).segmentIndex = NaN;
if(numOuts <= 3) {
link.elt(1).segmentFraction = 0.25;
} else {
link.elt(1).segmentFraction = 0.4;
}
} else {
// if more than one row apart (i.e. more than 175 points on the coordinate plane apart)
// style this differently - for now just leave it as orthagonal
}
}
});
}
});
},
"undoManager.isEnabled": true
}
);
Here’s how it is showing:
How can I position the arrows at the very end of each link (closest to the “To” node) without messing up the positioning of the link panels, which is working as I’d like? Thank you!