Binding a brush values to model

In the Shape I use for my node template I try to bind the ‘from’ value’ to a ‘color’ property :

 fill: $(go.Brush, 'Linear',  new go.Binding('0.0', 'color'), {1.0: 'green' }),

This does not even compile; I can’t figure out how to bind brush values to my node data model.

Sorry, only GraphObjects (and to a limited extent RowColumnDefinitions) support Bindings.

[EDIT: I misinterpreted what you are trying to do – here’s the fixed code]
The normal solution is to have your data like:

{ color: "yellow", . . . }

and your binding like:

new go.Binding("fill", "color", function(c) {
    var b = new go.Brush(go.Brush.Linear);
    b.addColorStop(0, c);
    b.addColorStop(1, "green");
    return b;
  })

I hope I don’t have any typos in that…

PS, don’t call GraphObject.make in frequently called code.

ok, that works.

Now suppose in my model, I have two properties called color1 and color2 instead of just ‘color’.

How do I create the brush ? I cannot have a single binding since we now have two color properties. In other words, instead of hardcoding ‘green’, how to I bind the second color stop to my model ?

Ha! that was what I originally solved, but then I realized you were asking for parameterizing just one color. So I changed the solution.

OK, if your data is:

{ color0: "yellow", color1: "green",. . . }

your binding could be like:

$(go.Shape, ...,
  new go.Binding("fill", "color0", convertLinearBrush),
  new go.Binding("fill", "color1", convertLinearBrush)
)

which depends on:

    function convertLinearBrush(c, shape) {
      var data = shape.part.data;
      var b = new go.Brush(go.Brush.Linear);
      b.addColorStop(0, data.color0);
      b.addColorStop(1, data.color1);
      return b;
    }

Alternatively, you could do:

$(go.Shape, . . .,
  new go.Binding("fill", "", convertLinearBrush)
),

and now:

    function convertLinearBrush(data) {
      var b = new go.Brush(go.Brush.Linear);
      b.addColorStop(0, data.color0);
      b.addColorStop(1, data.color1);
      return b;
    }

This depends on the source property being the empty string, which causes the source value to be the whole data object. But it has the disadvantage of being called whenever any data property changes. Often that’s not too bad, but constructing and replacing a whole Brush each time involves more overhead, so it’s unclear if that’s OK or not.

Thanks for that code:

Just a couple of questions. Here :

$(go.Shape, . . .,
  new go.Binding("stroke", "", convertLinearBrush)
),

I suppose you meant

$(go.Shape, . . .,
  new go.Binding("fill", "", convertLinearBrush)
),

right ?

And in both approaches, you are using data.color0 and data.color1. So even though in the first approach you are passing ‘c’, it is not being used. Is this intended ?

To me the second approach seems to make more sense, especially since the function only gets called once.

The target property doesn’t matter for this discussion.
The first argument to the converter is ignored only in the first approach.
The problem is that in the second approach that converter may be called very many times, not just when “color0” or “color1” change, but when any other property changes.

ok, got it.
Thanks !