流程图控件GoJS教程:面板项目数组(下)
GoJS是一款功能强大,快速且轻量级的流程图控件,可帮助你在JavaScript 和HTML5 Canvas程序中创建流程图,且极大地简化您的JavaScript / Canvas 程序。
GoJS现已更新至最新版本2.0.16发布,修复了一些bug,增强用户体验,赶快下载试试吧~
不同的面板类型
尽管具有项数组的Panel通常类型为Panel.Vertical,但是您可以使用其他支持可变数量元素的面板类型。最常见的类型是Panel.Vertical,Panel.Horizontal,Panel.Table和Panel.Position。使用Panel.Viewbox面板没有意义,因为该面板类型仅支持单个元素。
如果面板类型为Panel.Spot,Panel.Auto或Panel.Link,则假定面板的第一个子元素是“主要”对象,除创建的所有嵌套面板之外,第一个子元素将保留为第一个子元素。用于Panel.itemArray中的值。
这是一个水平面板的示例:
diagram.nodeTemplate =
$(go.Node, "Auto",
$(go.Shape, "RoundedRectangle",
{ fill: "gold" }),
$(go.Panel, "Horizontal",
{ margin: 4 }, new go.Binding("itemArray", "a"),
{ itemTemplate:
$(go.Panel, "Auto",
{ margin: 2 },
$(go.Shape, "RoundedRectangle",
{ fill: "white" }),
$(go.TextBlock, new go.Binding("text", ""),
{ margin: 2 })
) // end of itemTemplate
})
);
diagram.model =
$(go.GraphLinksModel,
{ nodeDataArray: [
{ key: "n1", a: [ 23, 17, 45, 21 ] },
{ key: "n2", a: [ 1, 2, 3, 4, 5 ] }
], linkDataArray: [
{ from: "n1", to: "n2" }
]
}
);
当使用面板类型的Panel.Table作为容器,它是司空见惯的使用项模板即类型的Panel.TableRow或Panel.TableColumn。这是为模板中的元素指定单独的列或行索引的唯一方法。
diagram.nodeTemplate =
$(go.Node, "Auto",
$(go.Shape, { fill: "lightgray" }),
$(go.Panel, "Table", new go.Binding("itemArray", "people"),
{ margin: 4, defaultAlignment: go.Spot.Left, itemTemplate:
$(go.Panel, "TableRow", new go.Binding("background", "back"),
$(go.TextBlock, new go.Binding("text", "name"),
{ column: 0, margin: 2, font: "bold 10pt sans-serif" }),
$(go.TextBlock, new go.Binding("text", "phone"),
{ column: 1, margin: 2 }),
$(go.TextBlock, new go.Binding("text", "loc"),
{ column: 2, margin: 2 })
) // end of itemTemplate
})
);
diagram.model =
$(go.GraphLinksModel,
{ nodeDataArray: [
{ key: "group1", people: [
{ name: "Alice", phone: "2345", loc: "C4-E18" },
{ name: "Bob", phone: "9876", loc: "E1-B34", back: "red" },
{ name: "Carol", phone: "1111", loc: "C4-E23" },
{ name: "Ted", phone: "2222", loc: "C4-E197" }
] },
{ key: "group2", people: [
{ name: "Robert", phone: "5656", loc: "B1-A27" },
{ name: "Natalie", phone: "5698", loc: "B1-B6" }
] }
], linkDataArray: [
{ from: "group1", to: "group2" }
]
}
);
请注意,在这种情况下,项目模板具有TableRow Panel的Panel.background属性到项目数据的“ back”属性的数据绑定。
有时有人想要获取特定项目的行,或者有人想要具有属性值取决于行索引。您始终可以依赖Panel.itemIndex的值来获取该属性。如果项Panel的类型为Panel.TableRow,则项Panel的GraphObject.row属性也将设置为从零开始的行号,因此您可以通过找到该Panel的代码来访问它。如果itemTemplate是Panel.TableColumn Panel ,则GraphObject.column也是如此。
因为在为Array项数据创建项面板时设置了该属性,所以您可以创建Binding,其中源是该“ row”属性:new go.Binding("targetProperty", "row", function(i) { return ...; }).ofObject()。下面的示例演示如果行是偶数,则将Panel.background属性绑定为浅绿色。
diagram.nodeTemplate =
$(go.Node, "Auto",
$(go.Shape, { fill: "white" }),
$(go.Panel, "Table", new go.Binding("itemArray", "people"),
{ defaultAlignment: go.Spot.Left, itemTemplate:
$(go.Panel, "TableRow", new go.Binding("background", "row", function(i) { return i%2 === 0 ? "lightgreen" : "transparent" })
.ofObject(),
$(go.TextBlock, new go.Binding("text", "name"),
{ column: 0, margin: 2, font: "bold 10pt sans-serif" }),
$(go.TextBlock, new go.Binding("text", "phone"),
{ column: 1, margin: 2 }),
$(go.TextBlock, new go.Binding("text", "loc"),
{ column: 2, margin: 2 }),
$("Button",
{ column: 3, margin: new go.Margin(0, 1, 0, 0), click: function(e, obj) { // OBJ is this Button Panel;
// find the TableRow Panel containing it
var itempanel = obj.panel;
alert("Clicked on row " + itempanel.row + " for " + itempanel.data.name);
}
},
$(go.Shape, "FivePointedStar",
{ desiredSize: new go.Size(8, 8) })
)
) // end of itemTemplate
})
);
diagram.model =
$(go.GraphLinksModel,
{ nodeDataArray: [
{ key: "group1", people: [
{ name: "Alice", phone: "2345", loc: "C4-E18" },
{ name: "Bob", phone: "9876", loc: "E1-B34" },
{ name: "Carol", phone: "1111", loc: "C4-E23" },
{ name: "Ted", phone: "2222", loc: "C4-E197" },
{ name: "Robert", phone: "5656", loc: "B1-A27" },
{ name: "Natalie", phone: "5698", loc: "B1-B6" }
] }
]
}
);
项目模板中的“按钮”面板还演示了如何获取特定的行索引以及项目面板绑定到的数据。
为表面板具有不同标题的自然方法是让第一行(即第一项)保存标题的数据,但是要采用不同的样式。如果您想要这种行为,则需要使用多个模板-请参见“ 模板映射”中的示例。
相反,如果您希望表标题是“固定的”并且不依赖于项Array数据,则可以在“表”面板中只有一个“ TableRow”(或“ TableColumn”)面板,如果使用Panel.isPanelMain,则保留该面板是真的。
diagram.nodeTemplate =
$(go.Node, "Auto",
$(go.Shape, { fill: "white" }),
$(go.Panel, "Table", new go.Binding("itemArray", "people"),
{ defaultAlignment: go.Spot.Left, defaultColumnSeparatorStroke: "black", itemTemplate: // the row created for each item in the itemArray
$(go.Panel, "TableRow",
$(go.TextBlock, new go.Binding("text", "name"),
{ column: 0, margin: 2, font: "bold 10pt sans-serif" }),
$(go.TextBlock, new go.Binding("text", "phone"),
{ column: 1, margin: 2 }),
$(go.TextBlock, new go.Binding("text", "loc"),
{ column: 2, margin: 2 })
)
}, // define the header as a literal row in the table,
// not bound to any item, but bound to Node data
$(go.Panel, "TableRow",
{ isPanelMain: true }, // needed to keep this element when itemArray gets an Array
$(go.TextBlock, "Person",
{ column: 0, margin: new go.Margin(2, 2, 0, 2), font: "bold 10pt sans-serif" }),
$(go.TextBlock, "Phone",
{ column: 1, margin: new go.Margin(2, 2, 0, 2), font: "bold 10pt sans-serif" }),
$(go.TextBlock, "Location",
{ column: 2, margin: new go.Margin(2, 2, 0, 2), font: "bold 10pt sans-serif" })
),
$(go.RowColumnDefinition,
{ row: 0, background: "lightgray" }),
$(go.RowColumnDefinition,
{ row: 1, separatorStroke: "black" })
)
);
diagram.model =
$(go.GraphLinksModel,
{ nodeDataArray: [
{ key: "group1", people: [
{ name: "Alice", phone: "2345", loc: "C4-E18" },
{ name: "Bob", phone: "9876", loc: "E1-B34" },
{ name: "Carol", phone: "1111", loc: "C4-E23" },
{ name: "Ted", phone: "2222", loc: "C4-E197" },
{ name: "Robert", phone: "5656", loc: "B1-A27" },
{ name: "Natalie", phone: "5698", loc: "B1-B6" }
] }
]
}
);
在这种情况下,常量头元素(即节点模板中的文字“ TableRow” Panel)将具有一个GraphObject.row == 0和一个NaN 的Panel.itemIndex。与第一个项目数据相对应的“ TableRow”面板panel.itemArray[0]将具有GraphObject.row == 1,与它在Panel.elements列表中的位置匹配。但是它将具有Panel.itemIndex == 0,与它在itemArray中的位置匹配。
模型中的数组
复制数据绑定的Part时,也必须复制Part的Part.data(必须是JavaScript对象)。正常的复制方法Model.copyNodeData会对原始数据对象进行浅表复制。
但是,这可能不是数组的预期行为。使用项目数组时,通常不希望在节点的副本之间共享这些数组。如果未正确复制节点数据,则可能会发生意外行为。因此,当您使用项目数组并允许用户复制节点时,需要确保复制了此类数组及其对象。对于最简单的情况,将Model.copiesArrays和Model.copiesArrayObjects设置为true 可能就足够了。更一般而言,您可能需要实现自己的节点数据复印机功能并将其分配给Model.copyNodeDataFunction。
动态端口示例证明了这一点,该示例不仅需要复制每个节点数据所保存的四个项数组,而且还需要复制每个数组中的每个对象。在该示例中,在加载到图中的模型的JSON格式表示中,将Model.copiesArrays和Model.copiesArrayObjects属性设置为true。
对于GraphLinksModel,链接数据也有一个类似的成员:GraphLinksModel.copyLinkData方法和GraphLinksModel.copyLinkDataFunction属性。
如果您需要动态修改项目数据的属性值,请调用Model.setDataProperty,就像处理节点数据或链接数据一样。如果您需要添加或删除项目数组中的项目,请调用Model.insertArrayItem或Model.removeArrayItem方法。=====================================================
想要购买GoJS正版授权的朋友可以。
更多精彩内容,欢迎关注下方的微信公众号,及时获取产品最新资讯▼▼▼