Hello,
Your component is just amazing.
I’m sorry for my looooong topic (and for my bad english) but I have some newbie questions :
If understand, each item in the nodeDataArray correspond to a node (a group or a non link part). We can use binding to link an attribute value to an object property (like the fill color).
[
{ key: "123", attribute1: 'A', attribute2: 'B' },
{ key: "234", attribute1: 'A', attribute2: 'B' }
]
When we use an itemArray to create children components, binding in the itemTemplate it refers to the child attribute (so only the attribute3).
[
{ key: "123", attribute1: 'A', attribute2: 'B' , children: [ { key: '1123', attribute3: 'C' ]},
{ key: "234", attribute1: 'A', attribute2: 'B' , children: [ { key: '1123', attribute3: 'C' ]}
]
Add properties dynamically
Imagine, each node child is a port and we want to add some properties dynamically (to simplify the initial model). How do add this properties from the itemTemplate or another place to the model (I know I can listen a changedEvent to add this properties but is it the correct way) ? My itemtemplate is like this…
itemTemplate() {
const circle = this.go(go.Shape, 'Rectangle',
{
strokeWidth: 0,
desiredSize: new go.Size(12, 12),
cursor: 'pointer',
fromSpot: go.Spot.Left,
toSpot: go.Spot.Right,
},
new go.Binding('fromLinkable', 'fromLinkable'),
new go.Binding('toLinkable', 'toLinkable'),
new go.Binding('portId', 'portId'),
);
const panel = this.go(go.Panel, 'Horizontal', {
alignment: go.Spot.Left,
margin: new go.Margin(2, 2),
});
panel.add(circle);
return panel;
}
I tried to add new data property like this :
model.setDataProperty(circle, 'acustomproperty', false);
But I receive a “GraphLinksModel.setDataProperty is modifying a GraphObject, “Shape(Rectangle)#488” Is that really your intent?” message and the corresponding parts in the node.data are not updated. So at this time, is use a binding to add this values, but it’s probably not the correct way to do it :
this.go(go.Panel, 'Vertical',
this.addProperties(),
{
itemTemplate: this.itemTemplate(),
},
),
...
addProperties() {
const bind = new go.Binding('itemArray', 'ports');
bind.converter = (ports, target) => {
const value = ports.map((port) => {
port.acustomproperty = null;
return port;
});
if (value === undefined) return target.itemArray;
return value;
};
return bind;
}
#2 Update child property from events
Now imagine a link is created (or relinked, or deleted) between two nodes port. I listen the LinkDrawn, LinkRelinked or SelectionDeleted events. I can retrieve the from/to Node and from/to Port but how to update the corresponding “acustomproperty” of each port in the model for the selected node. Once time again I tried with :
model.setDataProperty(e.subject.fromPort, 'acustomproperty', true);
I have the same message "GraphLinksModel.setDataProperty is modifying a GraphObject, “Shape(Rectangle)#488”.
At this time (and it’s a workaround), I change (the code is more complex) the data property like this :
onLinked(e) {
const fromNode = e.subject.fromNode;
const index = fromNode.data.ports.findIndex((port) => {
return port.portId === portId;
});
fromNode.data.ports[index].acustomproperty = true;
...
#3 Colored link
On the onLinked method above, I “compute” the color link (and other properties) from properties retrieves on each port. At this time (and it’s allways a workaround), I get this value like this :
onLinked(e) {
...
const ret = toNode.data.ports.filter((port) => {
return port.portId === portId;
});
let toAnotherproperty = null;
if (ret.length !== 0) {
toAnotherproperty = ret[0].anotherproperty;
}
...
if (fromAnotherProperty === 1 && toAnotherProperty === 1) linkColor = '#FF0000';
...
Two questions in one :
1. How to get this value (the are no getDataProperty)
2. That work’s perfectly for a new link but not for links created from the linkDataArray. In this case, how to modify properties of each links created by the linkDataArray before it draw them ? I can add a listener on addModelChangedListener and modify each link when the transaction is finished but is this the correct method ?
#2 Mapping
It’s my last question :) How to create a mapping to retrieve from a child a parent attribute ?
Thanks you !