Conditionally change link color?

I am attempting to change link colors in my GoJS tree depending on a key / value pair in my model data (color, in this case). I am attempting to call my method to change the link color by doing the following:

  myDiagram.linkTemplate =
    $(go.Link,
      { routing: go.Link.Orthogonal, corner: 5, toShortLength: -2, fromShortLength: -2 },
      $(go.Shape, { strokeWidth: 2, stroke: colors["gray"] },
      new go.Binding("geometry", "color", setLinkColor))); // the link shape and color

However, my setLinkColor method is never called. Here it is for reference:

  function setLinkColor(color) {

    console.log("value of color: ", color);

    switch(color) {

      case "critical":
        link = go.Shape.stroke(colors["orange"]);
        break;
      
        
      default:
        link = go.Shape.stroke(colors["white"]);

    } 
    return link;   
  }

How can I conditionally color my Links depending on the value of color?

go.Shape.stroke is not a static function defined on the Shape class by GoJS. So I have no idea of what you are doing.

The name “color” would imply to me that the value would be a CSS color string. That is not a valid value for the Shape.geometry property, which expects a value of type Geometry, and is not what appears to be returned from the setLinkColor binding conversion function.

You might want to read GraphObject Manipulation.

^This is a non-answer. color is not actually a CSS string, just a normal string / arbitrary flag for determining what color link to use. I am already conditionally changing node icons by doing the following:

$(go.TextBlock, {text:"Text",width:300,height:90,textAlign:"center",alignment:go.Spot.BottomCenter, wrap: go.TextBlock.WrapDesiredSize},new go.Binding("text", "geo")),
      $(go.Shape, { margin: 3, fill: colors["white"], strokeWidth: 0 },
      new go.Binding("fill", "color"),
      new go.Binding("geometry", "color", setIcon)),
      $("TreeExpanderButton",
      { alignment: go.Spot.Bottom, alignmentFocus: go.Spot.Bottom },
      { visible: true })

And my setIcon method:

  function setIcon(color) {

    switch(color) {
      case "#C8DA2B": 
        // lab
        geo = go.Geometry.parse("M29.884 25.14l-9.884-16.47v-6.671h1c0.55 0 1-0.45 1-1s-0.45-1-1-1h-10c-0.55 0-1 0.45-1 1s0.45 1 1 1h1v6.671l-9.884 16.47c-2.264 3.773-0.516 6.86 3.884 6.86h20c4.4 0 6.148-3.087 3.884-6.86zM7.532 20l6.468-10.779v-7.221h4v7.221l6.468 10.779h-16.935z", true);
        break;
      
      case "#800080": 
        // cogs
        geo = go.Geometry.parse("M11.366 22.564l1.291-1.807-1.414-1.414-1.807 1.291c-0.335-0.187-0.694-0.337-1.071-0.444l-0.365-2.19h-2l-0.365 2.19c-0.377 0.107-0.736 0.256-1.071 0.444l-1.807-1.291-1.414 1.414 1.291 1.807c-0.187 0.335-0.337 0.694-0.443 1.071l-2.19 0.365v2l2.19 0.365c0.107 0.377 0.256 0.736 0.444 1.071l-1.291 1.807 1.414 1.414 1.807-1.291c0.335 0.187 0.694 0.337 1.071 0.444l0.365 2.19h2l0.365-2.19c0.377-0.107 0.736-0.256 1.071-0.444l1.807 1.291 1.414-1.414-1.291-1.807c0.187-0.335 0.337-0.694 0.444-1.071l2.19-0.365v-2l-2.19-0.365c-0.107-0.377-0.256-0.736-0.444-1.071zM7 27c-1.105 0-2-0.895-2-2s0.895-2 2-2 2 0.895 2 2-0.895 2-2 2zM32 12v-2l-2.106-0.383c-0.039-0.251-0.088-0.499-0.148-0.743l1.799-1.159-0.765-1.848-2.092 0.452c-0.132-0.216-0.273-0.426-0.422-0.629l1.219-1.761-1.414-1.414-1.761 1.219c-0.203-0.149-0.413-0.29-0.629-0.422l0.452-2.092-1.848-0.765-1.159 1.799c-0.244-0.059-0.492-0.109-0.743-0.148l-0.383-2.106h-2l-0.383 2.106c-0.251 0.039-0.499 0.088-0.743 0.148l-1.159-1.799-1.848 0.765 0.452 2.092c-0.216 0.132-0.426 0.273-0.629 0.422l-1.761-1.219-1.414 1.414 1.219 1.761c-0.149 0.203-0.29 0.413-0.422 0.629l-2.092-0.452-0.765 1.848 1.799 1.159c-0.059 0.244-0.109 0.492-0.148 0.743l-2.106 0.383v2l2.106 0.383c0.039 0.251 0.088 0.499 0.148 0.743l-1.799 1.159 0.765 1.848 2.092-0.452c0.132 0.216 0.273 0.426 0.422 0.629l-1.219 1.761 1.414 1.414 1.761-1.219c0.203 0.149 0.413 0.29 0.629 0.422l-0.452 2.092 1.848 0.765 1.159-1.799c0.244 0.059 0.492 0.109 0.743 0.148l0.383 2.106h2l0.383-2.106c0.251-0.039 0.499-0.088 0.743-0.148l1.159 1.799 1.848-0.765-0.452-2.092c0.216-0.132 0.426-0.273 0.629-0.422l1.761 1.219 1.414-1.414-1.219-1.761c0.149-0.203 0.29-0.413 0.422-0.629l2.092 0.452 0.765-1.848-1.799-1.159c0.059-0.244 0.109-0.492 0.148-0.743l2.106-0.383zM21 15.35c-2.402 0-4.35-1.948-4.35-4.35s1.948-4.35 4.35-4.35 4.35 1.948 4.35 4.35c0 2.402-1.948 4.35-4.35 4.35z", true);
        break;
        
      default:
        geo = go.Geometry.parse("M8 10c0-4.418 3.582-8 8-8s8 3.582 8 8c0 4.418-3.582 8-8 8s-8-3.582-8-8zM24 20h-16c-4.418 0-8 3.582-8 8v2h32v-2c0-4.418-3.582-8-8-8z", true);

    } 

    return geo;   

  }

I would imagine I should be able to conditionally change the link color between nodes using very similar logic?

Yes, use a (different) binding conversion function for the Binding of the “stroke” property on the Link’s main Shape. The return value must be a CSS color string or a Brush.

UPDATE

I have tried implementing @walter’s suggestion as follows:

  var linkColors = {true: colors["orange"], false: colors["white"]};

  myDiagram.linkTemplate =
  $(go.Link,
    $(go.Shape, { strokeWidth: 2 },
      new go.Binding("stroke", "critical", function(c) { return linkColors[c] || colors["orange"]; })),
    $(go.Shape, { toArrow: "OpenTriangle", strokeWidth: 2 },
      new go.Binding("stroke", "critical", function(c) { return linkColors[c] || colors["orange"]; })),



 myDiagram.model = new go.GraphLinksModel(
        [
          { key: 2, geo: "thing1", color: colors["white"], critical: false },
          { key: 3, geo: "thing2", color: "#F47321", critical: true },
          { key: 4, geo: "thing3", color: colors["white"], critical: false },
          { key: 5, geo: "thing4", color: colors["white"], critical: false },

However this still is not coloring the links, what am I doing wrong?

What is the value of colors?

  // a collection of colors
  var colors = {
    blue: "#00B5CB",
    orange: "#F47321",
    green: "#C8DA2B",
    gray: "#888",
    white: "#F5F5F5"
  }

FWIW, even changing linkColors to var linkColors = {true: "#F47321", false: "#F5F5F5"}; doesn’t work.

That seems to work well for me. Here’s the complete app:

<!DOCTYPE html>
<html>
<head>
<title>Minimal GoJS Sample</title>
<!-- Copyright 1998-2019 by Northwoods Software Corporation. -->
<meta charset="UTF-8">
<script src="go.js"></script>
<script id="code">
  function init() {
    var $ = go.GraphObject.make;

    myDiagram =
      $(go.Diagram, "myDiagramDiv",
          { "undoManager.isEnabled": true });

    myDiagram.nodeTemplate =
      $(go.Node, "Auto",
        $(go.Shape,
          { fill: "white", portId: "" },
          new go.Binding("fill", "color")),
        $(go.TextBlock,
          { margin: 8 },
          new go.Binding("text"))
      );

    var colors = {
      blue: "#00B5CB",
      orange: "#F47321",
      green: "#C8DA2B",
      gray: "#888",
      white: "#F5F5F5"
    }

    var linkColors = { true: colors["orange"], false: colors["white"] };

    myDiagram.linkTemplate =
      $(go.Link,
        $(go.Shape, { strokeWidth: 2 },
          new go.Binding("stroke", "critical", function(c) { return linkColors[c] || colors["orange"]; })),
        $(go.Shape, { toArrow: "OpenTriangle", strokeWidth: 2 },
          new go.Binding("stroke", "critical", function(c) { return linkColors[c] || colors["orange"]; }))
      );

    myDiagram.model = new go.GraphLinksModel(
    [
      { key: 1, text: "Alpha", color: "lightblue" },
      { key: 2, text: "Beta", color: "orange" },
      { key: 3, text: "Gamma", color: "lightgreen" },
      { key: 4, text: "Delta", color: "pink" }
    ],
    [
      { from: 1, to: 2, critical: false },
      { from: 1, to: 3 },
      { from: 2, to: 2 },
      { from: 3, to: 4 },
      { from: 4, to: 1, critical: true }
    ]);
  }
</script>
</head>
<body onload="init()">
  <div id="myDiagramDiv" style="border: solid 1px black; width:100%; height:600px; background: lightgray"></div>
</body>
</html>

Note how when you do not set the critical property on the link data, the link path gets the default stroke, which is “black”.

image