Hi again,
I’ve worked on a new example in order to illustrate the desired behavior that we want:
<!DOCTYPE html>
<html>
<head>
<title>Model and node data binding</title>
<meta charset="UTF-8">
</head>
<body onload="init()">
<div id="app">
<div id="diagram" style="border: solid 1px black; width:100%; height:300px"></div>
<div style="display: flex; border: 1px solid black; padding: 10px;">
<div style="width: 50%">
<h3 style="margin-top: 0px;">NodeData</h3>
<table>
<tr><td>Key</td><td>color1</td><td>color2</td><td>color3</td></tr>
<tr>
<td>Alpha</td>
<td>
<select id="alphaColor1" onchange="updateColor('alpha', 'color1', document.getElementById('alphaColor1').value)">
<option>red</option>
<option>green</option>
<option>blue</option>
</select>
</td>
<td>
<select id="alphaColor2" onchange="updateColor('alpha', 'color2', document.getElementById('alphaColor2').value)">
<option>red</option>
<option>green</option>
<option>blue</option>
</select>
</td>
<td>
<select id="alphaColor3" onchange="updateColor('alpha', 'color3', document.getElementById('alphaColor3').value)">
<option>red</option>
<option>green</option>
<option>blue</option>
</select>
</td>
</tr>
<tr>
<td>Bravo</td>
<td>
<select id="bravoColor1" onchange="updateColor('bravo', 'color1', document.getElementById('bravoColor1').value)">
<option>red</option>
<option>green</option>
<option>blue</option>
</select>
</td>
<td>
<select id="bravoColor2" onchange="updateColor('bravo', 'color2', document.getElementById('bravoColor2').value)">
<option>red</option>
<option>green</option>
<option>blue</option>
</select>
</td>
<td>
<select id="bravoColor3" onchange="updateColor('bravo', 'color3', document.getElementById('bravoColor3').value)">
<option>red</option>
<option>green</option>
<option>blue</option>
</select>
</td>
</tr>
<tr>
<td>Charlie</td>
<td>
<select id="charlieColor1" onchange="updateColor('charlie', 'color1', document.getElementById('charlieColor1').value)">
<option>red</option>
<option>green</option>
<option>blue</option>
</select>
</td>
<td>
<select id="charlieColor2" onchange="updateColor('charlie', 'color2', document.getElementById('charlieColor2').value)">
<option>red</option>
<option>green</option>
<option>blue</option>
</select>
</td>
<td>
<select id="charlieColor3" onchange="updateColor('charlie', 'color3', document.getElementById('charlieColor3').value)">
<option>red</option>
<option>green</option>
<option>blue</option>
</select>
</td>
</tr>
</table>
</div>
<div style="width: 50%;">
<h3 style="margin-top: 0px;">Visualization settings</h3>
Which color property to use as node color:
<select onchange="updateColorVisualizationSettings()" id="colorVisualizationSetting">
<option>color1</option>
<option>color2</option>
<option>color3</option>
</select>
</div>
</div>
<pre style="border: 1px solid black; padding: 10px" id="modelData">
</pre>
</div>
<script src="https://unpkg.com/gojs"></script>
<script id="code">
function init() {
var $ = go.GraphObject.make; // for conciseness in defining templates
myDiagram = $(go.Diagram, "diagram", {
"undoManager.isEnabled": true
});
// define a simple Node template
myDiagram.nodeTemplate = $(go.Node, "Auto",
$(go.Shape, "RoundedRectangle", { strokeWidth: 0 },
new go.Binding("fill", "", (value, target) => {
return value[target.diagram.model.modelData.colorVisualizationSetting]
}),
new go.Binding("fill", "colorVisualizationSetting", (value, target) => {
return target.part.data[value]
}).ofModel(),
),
$(go.TextBlock,
{ margin: 8, font: "bold 14px sans-serif", stroke: '#333' },
new go.Binding("text", "key")
)
);
myDiagram.model = new go.GraphLinksModel(
[
{ key: "alpha", color1: 'red', color2: 'blue', color3: 'green' },
{ key: "bravo", color1: 'green', color2: 'red', color3: 'blue' },
{ key: "charlie", color1: 'blue', color2: 'green', color3: 'red' },
]
);
myDiagram.model.modelData = {
colorVisualizationSetting: 'color1'
}
myDiagram.model.linkKeyProperty = 'key'
myDiagram.addModelChangedListener((e) => {
if (e.isTransactionFinished) {
document.getElementById('modelData').innerHTML = myDiagram.model.toJson();
document.getElementById('colorVisualizationSetting').value = myDiagram.model.modelData.colorVisualizationSetting
document.getElementById('alphaColor1').value = myDiagram.model.findNodeDataForKey('alpha').color1
document.getElementById('alphaColor2').value = myDiagram.model.findNodeDataForKey('alpha').color2
document.getElementById('alphaColor3').value = myDiagram.model.findNodeDataForKey('alpha').color3
document.getElementById('bravoColor1').value = myDiagram.model.findNodeDataForKey('bravo').color1
document.getElementById('bravoColor2').value = myDiagram.model.findNodeDataForKey('bravo').color2
document.getElementById('bravoColor3').value = myDiagram.model.findNodeDataForKey('bravo').color3
document.getElementById('charlieColor1').value = myDiagram.model.findNodeDataForKey('charlie').color1
document.getElementById('charlieColor2').value = myDiagram.model.findNodeDataForKey('charlie').color2
document.getElementById('charlieColor3').value = myDiagram.model.findNodeDataForKey('charlie').color3
}
})
}
function updateColor(key, prop, value) {
myDiagram.model.startTransaction('updateColor');
myDiagram.model.setDataProperty(myDiagram.model.findNodeDataForKey(key), prop, value);
myDiagram.model.commitTransaction('updateColor');
}
function updateColorVisualizationSettings() {
const value = document.getElementById("colorVisualizationSetting").value;
myDiagram.model.skipsUndoManager = true;
myDiagram.model.startTransaction('colorVisualizationSettingUpdate');
myDiagram.model.set(myDiagram.model.modelData, 'colorVisualizationSetting', value);
myDiagram.model.commitTransaction('colorVisualizationSettingUpdate');
myDiagram.model.skipsUndoManager = false;
}
</script>
</body>
</html>
On the left you can configure the node data array and on the right the visualization settings. We don’t want to track visualization settings in the undo manager since it is a user setting and it should be persistent.
Please execute the following sequence:
- Change the node data key color1 to red for alpha, bravo an charlie: the node colors will update since the visualization setting is set to color1 and we are changing color1
- Now change the visualization setting to color2: the node colors update to all colors that are set in the color2 column of the node data
- Focus on the diagram and undo your history: As can be seen, the model data gets reverted nicely without altering the visualization setting. However, the diagram gets out of sync with the model data.
The desired behavior would be that the node data gets reverted (as is happening) but that the diagram node colors stay the same (since we have set the visualization setting to color2).
Does this clear things up? We are looking for a solution or a direction to implement this behavior.