Search code examples
cssgojs

Changing goShapes fill colors based on condition


I am using GoJS and I want to color the circle inside my node based on certain condition. if the status is "will retire" then color of the circle will be red, if the status is "millenial" then color of the circle will be green, otherwise it will be white. I've made it looked like this

var colors = {
  black: "#000000",
  white: "#ffffff",
  red: "#ff0000",
  green: "#00cc00"
}
var fill1 = null;

if (status == "milenial") {
  fill1 = colors["green"];
} else if (status == "akan pensiun") {
  fill1 = colors["red"];
} else {
  fill1 = colors["white"];
}

and in the diagram, by using go.shapes it looked like this

$(go.Shape, "Circle", {
  row: 0,
  column: 1,
  rowSpan: 4,
  margin: 3,
  fill: fill1,
  stroke: colors["white"],
  strokeWidth: 1,
  width: 25,
  height: 25
 },
new go.Binding("fill", "color")

I got the status value in the condition by using ajax. In my code, the shape color fill will stay white/null (I don't really understand which one), while the stroke works fine. I've tried to console.log(fill1), and it showed the colors[] value. But I don't get it why the shape color won't change in the shape. Please, can anyone explain why this happens and how to get the output I want? I am new and would appreciate any of your help. Thank you


Solution

  • The problem here is that although you are setting the fill when the node is created fill: fill1 the underlying model will not be update when you later update fill1 as its is set to the objects value rather than a reference to the object.

    In this case the solution is to use a Binding to create a property you can update in a transaction, for example

              GO(go.Shape, "Trapezoid1",
                {
                  name: "SHAPE",
                  angle: 270,
                  strokeWidth: 2,
                  fill: "pink",
                  minSize: new go.Size(50, 50),
                },
                new go.Binding("fill", "status", function(type) {
                    switch (type) {
                    case "milenial":
                        return "#00cc00";
                    case "will retire":
                        return "#ff0000";
                    default:
                        return "#ffffff";
                }})              
              );
    

    Here we are binding "fill" to "status" and using a function to embed your logic into the node.

    Elsewhere in you code (where you are using ajax) update the status

    function update(key, status) {
        // all model changes should happen in a transaction
        myDiagram.model.commit(function(m) {
            console.log("Finding Node " + key) 
            var data = m.findNodeDataForKey(key);
            m.set(data, "status", status);
        }, "update " + status + " for " + key);
    };
    
    update("RASP1","will retire" );
    update("RASP2","milenial" );
    

    In this example two of my nodes are identified as RASP1 and RASP1 and I'm setting the status to "will retire" and "milenial" respectively. The other two nodes are pink as this is the default colour

    enter image description here