I have a Link template that includes a binding for the stroke property of the Shape used to display the link.
go.Link,
{
selectable: false,
},
// use `Normal` routing except for links within a single table
new go.Binding('routing', '', (linkData: IERDGraphLink) => {
return linkData.from === linkData.to
? go.Link.AvoidsNodes
: go.Link.Normal;
}),
new go.Binding('fromEndSegmentLength'),
new go.Binding('toEndSegmentLength'),
make(
go.Shape,
{
fill: '#FFF',
},
new go.Binding('stroke', '', (linkData: IERDGraphLink) => {
return linkData.isConnectedToHoveredTable ||
linkData.isConnectedToSelectedTable
? HIGHLIGHTED_COLOR
: DARK_BORDER_COLOR;
}),
...
The stroke will appear correctly based on the initial value of the linkData but when that value is updated in the model, the stroke will not change. When I tried logging the value of the linkData it is still showing the initial values, not the updated values. I confirmed that the values are updating in the model by using the debugger.
Why is the updated linkData not being used in this binding?
Did you call Model.set (a.k.a. Model.setDataProperty) within a transaction? Something like:
myDiagram.model.commit(function(m) {
m.set(link.data, "isConnectedToSelectedTable", !link.data.isConnectedToSelectedTable");
}, "changed link color");
Hmmm, if you are making this change within a Part.selectionChanged event handler, you do not need to execute a transaction. But you still need to call Model.set.
The reason I am confused is that I am doing something very similar within a Node template and it works fine. Is there any difference between doing this type of binding in a Node template versus a Link template?
I also should mention that I’m using a React component with the react-gojs package’s GojsDiagram as a child component. The model is part of the React component state. When the state is updated it re-renders, passing in the update model as a prop.
Basically, i am just updating the model in my component and the GojsDiagram component should be handling things from there. Do you see anything in there that could be causing this issue?
There’s no reason it should work for nodes but not links.
What is the value of this.props.model.linkDataArray being passed in as modifiedLinkData
to the applyIncrementalJson method when you are making your updates? I imagine this could be where the problem lies.
One thing that looks like it may be a problem is that my linkData objects don’t have a key property. Since linkKeyProperty is set to key, I’m guessing that might be causing a problem. I will try adding a key property to the linkData when I get a chance to see if that makes a difference.
In fact, the GojsDiagram component in react-gojs doesn’t even have a key property in the LinkModel. I tried adding it, just as I did in my own project, but it did not help.
Would you be able to send us a reproducible sample? It may be a bug in the package, but we’d still like to take a look to see if there’s anything on the GoJS end.
I took the react-gojs sample code and made some changes to demonstrate the problem I am running into. In this case, when you click the button to add a new child node, it marks the new link as new using an isNew property. When you add a another new node, it will also update existing links to have isNew be false. The links that are marked with isNew as true should show up red and the others should be black. However you will see that the links that are created with the isNew property set to true will never change to black, even after their isNew property has been changed to false.
I also added in a key property for links, which was missing in the original react-gojs sample code.
Ok got it. The model’s linkKeyProperty wasn’t actually set at initialization of your GojsDiagram component. This means that the model can’t get the key of the new link data passed in and so it can’t match the new data with existing model data. If you change render in your MyDiagram class to this, it should work as expected:
render() {
return (
<GojsDiagram
diagramId="myDiagramDiv"
model={this.props.model}
linkKeyProperty="key" // added this line
createDiagram={this.createDiagram}
className="myDiagram"
onModelChange={this.props.onModelChange}
/>
);
}