Split a single linkline in half and apply styles to each half

Does GOJS provide the ability to split a single linkline in half and apply styles to each half? I want to implement barker notation when displaying ERDs.

I think this will do what you want. You can simplify the code by not supporting distinct stroke colors, if they will always be the same:

<!DOCTYPE html>
<html><body>
  <div id="sample">
    <div id="myDiagramDiv" style="border: solid 1px black; width:100%; height:400px; background: #444"></div>
  </div>

  <script src="https://unpkg.com/gojs"></script>
  <script id="code">
// Draw a Link with two colors and with optional dashes.
// Assume the link template has two Shapes each with isPanelMain: true.
// This is hard-coded to look for data.fromDash and data.toDash,
// which are boolean properties that control whether that half of the stroke
// is drawn with a [6, 4] strokeDashArray.
class TwoColorDashedLink extends go.Link {
  makeGeometry() {
    const geo = super.makeGeometry();
    let first = null;
    let second = null;
    this.elements.each(elt => {
      if (elt.isPanelMain && elt instanceof go.Shape) {
        if (first === null) first = elt;
        else if (second === null) second = elt;
      }
    });
    if (first && second) {
      const seclen = geo.flattenedTotalLength / 2;  // length of each color section
      if (this.data.fromDash) {
        const a = [];
        for (let i = 0; i < seclen; i+=6+4) { a.push(6); a.push(4); }
        a.push(0); a.push(seclen);
        first.strokeDashArray = a;
      } else {
        first.strokeDashArray = [0, 0, seclen, 99999];
      }
      if (this.data.toDash) {
        const a = [0, seclen];
        for (let i = 0; i < seclen; i+=6+4) { a.push(6); a.push(4); }
        second.strokeDashArray = a;
      } else {
        second.strokeDashArray = [0, seclen, seclen, 99999];
      }
    }
    return geo;
  }
}
// end of TwoColorLink class

// Since 2.2 you can also author concise templates with method chaining instead of GraphObject.make
// For details, see https://gojs.net/latest/intro/buildingObjects.html
const $ = go.GraphObject.make;

myDiagram =
  new go.Diagram("myDiagramDiv",
    {
      layout: $(go.TreeLayout, { layerSpacing: 200 }),
      "undoManager.isEnabled": true
    });

myDiagram.nodeTemplate =
  $(go.Node, "Auto",
    { fromSpot: go.Spot.AllSides, toSpot: go.Spot.AllSides },
    $(go.Shape,
      { fill: "white", strokeWidth: 0 },
      new go.Binding("fill", "color")),
    $(go.TextBlock,
      { margin: 12 },
      new go.Binding("text"))
  );

myDiagram.linkTemplate =
  $(TwoColorDashedLink,
    { routing: go.Link.AvoidsNodes, corner: 10 },
    $(go.Shape, { isPanelMain: true, strokeWidth: 3 },
      new go.Binding("stroke", "fromColor")),
    $(go.Shape, { isPanelMain: true, strokeWidth: 3 },
      new go.Binding("stroke", "toColor"))
  );

myDiagram.model = new go.GraphLinksModel([
  {"key":1, "text":"Alpha", "color":"lightblue"},
  {"key":2, "text":"Beta", "color":"orange"},
  {"key":3, "text":"Gamma", "color":"lightgreen"},
],
[
  {"from":1, "to":2, "fromColor": "gold", "toColor": "green", "fromDash": true},
  {"from":2, "to":3, "fromColor": "green", "toColor": "red", "toDash": true},
]);
  </script>
</body></html>
1 Like

This is exactly what I needed. Thanks. I love you