Changing Shape Properties in Javascript

I have some server-side logic that parses the diagram and based on logic choices, will disable certain logic branches and items on that branch.

This information is available to me in a JSON object on web page, keyed by goJS key id.
The best scenario would be to iterate all the items that as disabled, and set the Shape disabled property to true. However, it appears this “disabled” property does not exist, so I can simulate it by changing the color and perhaps other properties to indicate the shape has been disabled.

This is as far as I got for some test code:

var nodeData = myDiagram.model.findNodeDataForKey(’-5’);
myDiagram.model.setDataProperty(nodeData, “fill”, “#000000”);
myDiagram.model.setDataProperty(nodeData, “text”, “this has been updated”);

I can set the text but changing the color has no effect. I believe i need to get the shape object somehow. How do I go about doing this?


If there is a Binding on some Shape.fill in your node template(s), your code would cause the shape’s fill color to become black (#000000).

Another way of organizing your app might be to have a “disabled” property on each node data object, and to have Bindings of whatever you want in your node template(s) based on that property. Something like:

    $(go.Shape, ...
        { fill: "green", ... },
        new go.Binding("fill", "disabled", function(d) { return d ? "black" : "green"; })

Basically this would allow each template to decide how to display the fact that the node is “disabled”.

Thanks for the reply, but I seem to be missing something. The host page does some AJAX stuff which will effect the state of the diagram after it is loaded on the page. This will change as the user interacts with the diagram. The AJAX request gets back something like this:
{ “Items”: { “Item”: [ {“Color”: “#EFFAB4”, “IsDisabled”: “0”, “IsHighlighted”: “false”, “Key”: “-2”, “WorkflowItemID”: “202” }, {“Color”: “#70706F”, “IsDisabled”: “0”, “IsHighlighted”: “false”, “Key”: “-3”, “WorkflowItemID”: “203” }, {“Color”: “#70706F”, “IsDisabled”: “0”, “IsHighlighted”: “false”, “Key”: “-4”, “WorkflowItemID”: “204” }, {“Color”: “#EFFAB4”, “IsDisabled”: “0”, “IsHighlighted”: “false”, “Key”: “-9”, “WorkflowItemID”: “205” }, {“Color”: “#EFFAB4”, “IsDisabled”: “0”, “IsHighlighted”: “false”, “Key”: “-6”, “WorkflowItemID”: “206” }, {“Color”: “#EFFAB4”, “IsDisabled”: “0”, “IsHighlighted”: “false”, “Key”: “-5”, “WorkflowItemID”: “207” }, {“Color”: “#009900”, “IsDisabled”: “0”, “IsHighlighted”: “false”, “Key”: “-7”, “WorkflowItemID”: “208” }, {“Color”: “#79C900”, “IsDisabled”: “0”, “IsHighlighted”: “false”, “Key”: “-1”, “WorkflowItemID”: “209” }, {“Color”: “#DC3C00”, “IsDisabled”: “0”, “IsHighlighted”: “false”, “Key”: “-8”, “WorkflowItemID”: “210” } ] }}

Which I parse into a JSON object. The Key is the goJS key.I will enumerate this JSON object, and all I want to do is get the shape and set a couple properties based on the data in the JSON object.

It appears that this binding method only works when the diagram is first loaded?

So you do have Bindings whose sources are “Color”, “IsDisabled”, and “IsHighlighted”?

If so, then those bindings will be evaluated not only when the node is created and added to the diagram, but also whenever the model is told that the property value has changed on the node data. That is done by calling Model.setDataProperty.

As far as I can tell, the code that you posted at the beginning of this topic should work, assuming that you have the proper bindings in your node template, and if you fix the property names to be the ones that you actually seem to be using, such as “Color” instead of “fill”.

By the way, beware using strings when numbers or booleans are needed. You have the “IsDisabled” and the “IsHighlighted” properties set to strings instead of booleans. If you really want to use strings there, that’s OK but you need to use conversion functions to account for the fact that JavaScript thinks that “0” and “false” (the strings) are truthy, not falsy. Whereas 0 (the number) and false (the boolean) are falsy.

OK, once I got my head around the fact that I cannot access the objects properties directly (need to databind first), it started making sense.

I have it working now, thanks for the help.


Actually, you can access the GraphObjects directly, but it’s more work for you to do so and that code would be more fragile if you change the style or implementation of the template(s). See for some explanation.

Furthermore if you want the state to be persisted, you need to have the state be in the model, on each node data.

On the other hand, going directly can be faster (lower overhead) if you can make all of the needed assumptions. But that’s a rare situation. I suppose it’s not so rare when the state is meant to be transient or ephemeral.