一、一个简单的数据绑定(go.Binding)看注释为绑定
diagram.nodeTemplate =
$(go.Node, "Auto",
$(go.Shape, "RoundedRectangle",
{ fill: "white" },
new go.Binding("fill", "color")), // shape.fill = data.color
$(go.TextBlock,
{ margin: 5 },
new go.Binding("text", "key")) // textblock.text = data.key
);
diagram.linkTemplate =
$(go.Link,
$(go.Shape,
new go.Binding("stroke", "color"), // shape.stroke = data.color
new go.Binding("strokeWidth", "thick")), // shape.strokeWidth = data.thick
$(go.Shape,
{ toArrow: "OpenTriangle", fill: null },
new go.Binding("stroke", "color"), // shape.stroke = data.color
new go.Binding("strokeWidth", "thick")) // shape.strokeWidth = data.thick
);
var nodeDataArray = [
{ key: "Alpha", color: "lightblue" },
{ key: "Beta", color: "pink" }
];
var linkDataArray = [
{ from: "Alpha", to: "Beta", color: "blue", thick: 2 }
];
diagram.model = new go.GraphLinksModel(nodeDataArray, linkDataArray);
显示如图:
二、绑定对象属性,如部件位置
还可以对具有对象值的数据绑定属性。例如,数据绑定 Part.location 属性是很常见的。
Part.location 的值是一个点,因此在此示例中,数据属性必须是点。
diagram.nodeTemplate =
$(go.Node, "Auto",
new go.Binding("location", "loc"), // 绑定的属性值为location,绑定的值为nodeDataArray里的loc值
$(go.Shape, "RoundedRectangle",
{ fill: "white" },
new go.Binding("fill", "color")),
$(go.TextBlock,
{ margin: 5 },
new go.Binding("text", "key"))
);
var nodeDataArray = [
// for each node specify the location using Point values
{ key: "Alpha", color: "lightblue", loc: new go.Point(0, 0) },
{ key: "Beta", color: "pink", loc: new go.Point(100, 50) }
];
var linkDataArray = [
{ from: "Alpha", to: "Beta" }
];
diagram.model = new go.GraphLinksModel(nodeDataArray, linkDataArray);
生成的图:
三、转换函数(类似自定义值)
Point 类包含一个静态函数 Point.parse,可用于将字符串转换为 Point 对象。它期望输入字符串中有两个数字,表示 Point.x 和 Point.y 值。它返回具有这些值的 Point 对象。
可以将转换函数作为第三个参数传递给 Binding 构造函数。在本例中,它是 Point.parse。这允许以字符串 (“100 50”) 的形式指定位置,而不是作为返回 Point 的表达式指定。对于模型对象上的数据属性,您通常需要使用字符串作为点s、大小s、矩形s、边距s 和点s 的表示形式,而不是对这些类对象的引用。字符串很容易在JSON和XML中读写。尝试读取/写入对象的类会占用额外的空间,并且需要编写器和读取器的额外合作。
举例简洁:
diagram.nodeTemplate =
$(go.Node, "Auto",
new go.Binding("location", "loc", go.Point.parse), // 关键代码
$(go.Shape, "RoundedRectangle",
{ fill: "white" },
new go.Binding("fill", "color")),
$(go.TextBlock,
{ margin: 5 },
new go.Binding("text", "key"))
);
var nodeDataArray = [
{ key: "Alpha", color: "lightblue", loc: "0 0" }, // 值以“0 0”的形式
{ key: "Beta", color: "pink", loc: "100 50" }
];
var linkDataArray = [
{ from: "Alpha", to: "Beta" }
];
diagram.model = new go.GraphLinksModel(nodeDataArray, linkDataArray);
生成图:与上图一致
正文:
下面是一个示例,该示例将多个 Shape 属性数据绑定到名为“highlight”的同一布尔数据属性。每个转换函数都采用布尔值,并为数据绑定的属性返回适当的值。
注:请注意,转换函数只能返回属性值。不能返回图形对象来替换部件的可视树中的对象。如果需要基于绑定数据显示不同的 GraphObjects,可以绑定 GraphObject.visible 或 GraphObject.opacity 属性。如果你真的想要不同的视觉结构,你可以使用多个模板(模板地图)。
diagram.nodeTemplate =
$(go.Node, "Auto",
new go.Binding("location", "loc", go.Point.parse),
$(go.Shape, "RoundedRectangle",
{ // 这边的highlight使用了函数返回的形式
fill: "yellow", stroke: "orange", strokeWidth: 2 },
new go.Binding("fill", "highlight", function(v) { return v ? "pink" : "lightblue"; }),
// 这边的highlight使用了函数返回的形式
new go.Binding("stroke", "highlight", function(v) { return v ? "red" : "blue"; }),
new go.Binding("strokeWidth", "highlight", function(v) { return v ? 3 : 1; })),
$(go.TextBlock,
{ margin: 5 },
new go.Binding("text", "key"))
);
var nodeDataArray = [
{ key: "Alpha", loc: "0 0", highlight: false },// 定义的highlight值为布尔值用来判断执行自定义
{ key: "Beta", loc: "100 50", highlight: true },
{ key: "Gamma", loc: "0 100" } // 这边的highlight值为空,用来判断为控制的情况下
];
var linkDataArray = [
{ from: "Alpha", to: "Beta" }
];
diagram.model = new go.GraphLinksModel(nodeDataArray, linkDataArray);
生成的图:
四、更改数据值
上述示例都取决于创建部件时要评估的数据绑定,并且其 Panel.data 属性设置为引用相应的节点或链接数据。当关系图在设置 Diagram.model 时为模型中的数据创建图表部件时,这些操作会自动发生。
对于大多数数据属性,即模型不专门处理但绑定数据的属性,只需调用 Model.setDataProperty。
官方例子:
diagram.nodeTemplate =
$(go.Node, "Auto",
{ locationSpot: go.Spot.Center },
$(go.Shape, "RoundedRectangle",
{ // 自定义highlight
fill: "yellow", stroke: "orange", strokeWidth: 2 },
new go.Binding("fill", "highlight", function(v) { return v ? "pink" : "lightblue"; }),
new go.Binding("stroke", "highlight", function(v) { return v ? "red" : "blue"; }),
new go.Binding("strokeWidth", "highlight", function(v) { return v ? 3 : 1; })),
$(go.TextBlock,
{ margin: 5 },
new go.Binding("text", "key"))
);
diagram.model.nodeDataArray = [
{ key: "Alpha", highlight: false } // just one node, and no links
];
function flash() {
// 所有模型更改都应该发生在事务中
diagram.model.commit(function(m) {
var data = m.nodeDataArray[0]; // 获取第一个数组node的值
m.set(data, "highlight", !data.highlight);//设置data值里的highlight为!data.highlight
}, "flash");
}
function loop() {
//每0.5秒执行一次修改
setTimeout(function() { flash(); loop(); }, 500);
}
loop();
第会动
假设500毫秒了:
五、更改图形结构
对于模型知道的数据属性(如链接数据的“to”或“from”),必须调用相应的模型方法才能修改数据属性。直接修改数据属性而不调用相应的模型方法可能会导致不一致或未定义的行为。
例子(官方的连接,更改“to”连接的属性)getToKeyForLinkData和setToKeyForLinkData的使用
diagram.nodeTemplate =
$(go.Node, "Auto",
{ locationSpot: go.Spot.Center },
$(go.Shape, "RoundedRectangle",
{ fill: "yellow", stroke: "orange", strokeWidth: 2 }),
$(go.TextBlock,
{ margin: 5 },
new go.Binding("text", "key"))
);
var nodeDataArray = [
{ key: "Alpha" },
{ key: "Beta" },
{ key: "Gamma" }
];
var linkDataArray = [
{ from: "Alpha", to: "Beta" }
];
diagram.model = new go.GraphLinksModel(nodeDataArray, linkDataArray);
function switchTo() {
// 所有的操作都在方法内执行
diagram.model.commit(function(m) {
var data = m.linkDataArray[0]; // 获取第一个linkDataArray得node值
if (m.getToKeyForLinkData(data) === "Beta")
m.setToKeyForLinkData(data, "Gamma");
else
m.setToKeyForLinkData(data, "Beta");
}, "reconnect link");
}
function loop() {
setTimeout(function() { switchTo(); loop(); }, 1000);
}
loop();
示例图:原本指向Beta,1秒后指向Gamma
六、绑定到图形对象源
Shape.fill 绑定到 Part.isSelected 属性。选择或取消选择节点时,属性将更改值,因此将评估绑定。转换函数获取布尔值,并返回要用作形状填充的所需画笔颜色。本示例还关闭选定装饰,以便通过形状的填充颜色来判断节点是否被选中的唯一直观方法。isSelected:isSelected
diagram.nodeTemplate =
$(go.Node, "Auto",
{ selectionAdorned: false }, // 显示选中边框
$(go.Shape, "RoundedRectangle",
//isSelected默认fasle,true(操作型属性无法在模板定义,只能在节点生成后操作)例如,节点或线对象.isSelected=true;
new go.Binding("fill", "isSelected", function(sel) {
return sel ? "dodgerblue" : "lightgray";
}).ofObject()), // no name means bind to the whole Part
$(go.TextBlock,
{ margin: 5 },
new go.Binding("text", "descr"))
);
diagram.model.nodeDataArray = [
{ descr: "Select me!" },
{ descr: "I turn blue when selected." }
];
点击按钮后使图形变颜色
七、绑定到共享模型.模型数据源
绑定源对象可以是第三种源,除了 Panel.data 或面板中的某些 GraphObject 之外。它也可以是 JavaScript 对象,即共享的 Model.modelData 对象。这允许将节点或链接元素属性绑定到模型中将存在的共享属性,即使模型中不存在节点或链接,也可以对其进行修改。
eg:Shape.fill 绑定到 Model.modelData 对象上的“color”属性。单击该按钮时,函数通过调用 Model.setDataProperty 来修改对象。changeColor
modelData
diagram.nodeTemplate =
$(go.Node, "Auto",
$(go.Shape, "RoundedRectangle",
{ fill: "white" }, // 默认给的颜色,如果nodeDataArray没有color属性
new go.Binding("fill", "color").ofModel()), // model.modelData的属性
$(go.TextBlock,
{ margin: 5 },
new go.Binding("text"))
);
// 设置刚开始默认颜色为黄色
diagram.model.modelData.color = "yellow";
diagram.model.nodeDataArray = [
{ text: "Alpha" },
{ text: "Beta" }
];
//支持 Ctrl-Z 和 Ctrl-Y 操作 (撤回和复原)
diagram.undoManager.isEnabled = true;
changeColor = function() { // 定义一个名为"changeColor"的函数,可通过button.onclick调用
diagram.model.commit(function(m) {
// alternate between lightblue and lightgreen colors
var oldcolor = m.modelData.color;
var newcolor = (oldcolor === "lightblue" ? "lightgreen" : "lightblue");
m.set(m.modelData, "color", newcolor);
}, "changed shared color");
}
官网图例:数据绑定 |GoJS
八、双向数据绑定
希望能够将值从 GraphObject传输回模型数据,以使模型数据与图表保持同步。这可以通过使用双向绑定来实现,该绑定不仅可以将值从源传递到目标,还可以从目标对象传递回源数据。
eg:单击按钮以移动节点。效果基本上是用户拖动节点时发生的情况。在此示例中,节点位置上的双向绑定将更新节点数据的“loc”属性,该节点数据是节点的部件数据。
diagram.nodeTemplate =
$(go.Node, "Auto",
{ locationSpot: go.Spot.Center },
new go.Binding("location", "loc").makeTwoWay(), // 双向绑定makeTwoWay Binding
$(go.Shape, "RoundedRectangle",
{ fill: "lightblue", stroke: "blue", strokeWidth: 2 }),
$(go.TextBlock,
{ margin: 5 },
new go.Binding("text", "key"))
);
var nodeDataArray = [
{ key: "Alpha", loc: new go.Point(0, 0) }
];
diagram.model = new go.GraphLinksModel(nodeDataArray);
shiftNode = (function() { // 定义一个名为“shiftNode”的函数,可通过button.onclick调用
// 所有模型更改都应该发生在事务中
diagram.commit(function(d) {
var data = d.model.nodeDataArray[0]; // get the first node data
var node = d.findNodeForData(data); // find the corresponding Node
var p = node.location.copy(); // 复制位置,一个点
p.x += 10;
if (p.x > 200) p.x = 0;
// 修改节点。位置也会改变数据。loc属性由于双向绑定
node.location = p;
// 显示节点数据的"loc"属性所持有的更新位置
document.getElementById("bindTwoWayData").textContent = data.loc.toString();
}, "shift node");
});
shiftNode(); // initialize everything
图例:
您可以向 Binding.makeTwoWay 提供转换函数以从目标转到源。例如,要将位置表示为模型数据中的字符串而不是点,请执行以下操作:
// 点/大小/矩形/边距/点的存储表示是字符串,而不是对象:
new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify)
注:不得在节点数据属性(即“键”属性)上具有 TwoWay 绑定。(默认为名称“key”,但实际上是Model.nodeKeyProperty的值。该属性值在模型内的所有节点数据中必须始终唯一,并且由模型已知。双向绑定可能会更改值,从而导致许多问题。同样,Node.key 属性是只读的,以防止意外更改键值。
官网建议不要使用双向绑定,至于原因,应该属于性能问题吧。