流程圖控件GoJS教程:面板項(xiàng)目數(shù)組(下)
GoJS是一款功能強(qiáng)大,快速且輕量級(jí)的流程圖控件,可幫助你在JavaScript 和HTML5 Canvas程序中創(chuàng)建流程圖,且極大地簡(jiǎn)化您的JavaScript / Canvas 程序。
GoJS現(xiàn)已更新至最新版本2.0.16發(fā)布,修復(fù)了一些bug,增強(qiáng)用戶(hù)體驗(yàn),趕快下載試試吧~
不同的面板類(lèi)型
盡管具有項(xiàng)數(shù)組的Panel通常類(lèi)型為Panel.Vertical,但是您可以使用其他支持可變數(shù)量元素的面板類(lèi)型。最常見(jiàn)的類(lèi)型是Panel.Vertical,Panel.Horizontal,Panel.Table和Panel.Position。使用Panel.Viewbox面板沒(méi)有意義,因?yàn)樵撁姘孱?lèi)型僅支持單個(gè)元素。
如果面板類(lèi)型為Panel.Spot,Panel.Auto或Panel.Link,則假定面板的第一個(gè)子元素是“主要”對(duì)象,除創(chuàng)建的所有嵌套面板之外,第一個(gè)子元素將保留為第一個(gè)子元素。用于Panel.itemArray中的值。
這是一個(gè)水平面板的示例:
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" }
]
}
);
當(dāng)使用面板類(lèi)型的Panel.Table作為容器,它是司空見(jiàn)慣的使用項(xiàng)模板即類(lèi)型的Panel.TableRow或Panel.TableColumn。這是為模板中的元素指定單獨(dú)的列或行索引的唯一方法。
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" }
]
}
);
請(qǐng)注意,在這種情況下,項(xiàng)目模板具有TableRow Panel的Panel.background屬性到項(xiàng)目數(shù)據(jù)的“ back”屬性的數(shù)據(jù)綁定。
有時(shí)有人想要獲取特定項(xiàng)目的行,或者有人想要具有屬性值取決于行索引。您始終可以依賴(lài)Panel.itemIndex的值來(lái)獲取該屬性。如果項(xiàng)Panel的類(lèi)型為Panel.TableRow,則項(xiàng)Panel的GraphObject.row屬性也將設(shè)置為從零開(kāi)始的行號(hào),因此您可以通過(guò)找到該P(yáng)anel的代碼來(lái)訪(fǎng)問(wèn)它。如果itemTemplate是Panel.TableColumn Panel ,則GraphObject.column也是如此。
因?yàn)樵跒锳rray項(xiàng)數(shù)據(jù)創(chuàng)建項(xiàng)面板時(shí)設(shè)置了該屬性,所以您可以創(chuàng)建Binding,其中源是該“ row”屬性:new go.Binding("targetProperty", "row", function(i) { return ...; }).ofObject()。下面的示例演示如果行是偶數(shù),則將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" }
] }
]
}
);
項(xiàng)目模板中的“按鈕”面板還演示了如何獲取特定的行索引以及項(xiàng)目面板綁定到的數(shù)據(jù)。
為表面板具有不同標(biāo)題的自然方法是讓第一行(即第一項(xiàng))保存標(biāo)題的數(shù)據(jù),但是要采用不同的樣式。如果您想要這種行為,則需要使用多個(gè)模板-請(qǐng)參見(jiàn)“ 模板映射”中的示例。
相反,如果您希望表標(biāo)題是“固定的”并且不依賴(lài)于項(xiàng)Array數(shù)據(jù),則可以在“表”面板中只有一個(gè)“ 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" }
] }
]
}
);
在這種情況下,常量頭元素(即節(jié)點(diǎn)模板中的文字“ TableRow” Panel)將具有一個(gè)GraphObject.row == 0和一個(gè)NaN 的Panel.itemIndex。與第一個(gè)項(xiàng)目數(shù)據(jù)相對(duì)應(yīng)的“ TableRow”面板panel.itemArray[0]將具有GraphObject.row == 1,與它在Panel.elements列表中的位置匹配。但是它將具有Panel.itemIndex == 0,與它在itemArray中的位置匹配。
模型中的數(shù)組
復(fù)制數(shù)據(jù)綁定的Part時(shí),也必須復(fù)制Part的Part.data(必須是JavaScript對(duì)象)。正常的復(fù)制方法Model.copyNodeData會(huì)對(duì)原始數(shù)據(jù)對(duì)象進(jìn)行淺表復(fù)制。
但是,這可能不是數(shù)組的預(yù)期行為。使用項(xiàng)目數(shù)組時(shí),通常不希望在節(jié)點(diǎn)的副本之間共享這些數(shù)組。如果未正確復(fù)制節(jié)點(diǎn)數(shù)據(jù),則可能會(huì)發(fā)生意外行為。因此,當(dāng)您使用項(xiàng)目數(shù)組并允許用戶(hù)復(fù)制節(jié)點(diǎn)時(shí),需要確保復(fù)制了此類(lèi)數(shù)組及其對(duì)象。對(duì)于最簡(jiǎn)單的情況,將Model.copiesArrays和Model.copiesArrayObjects設(shè)置為true 可能就足夠了。更一般而言,您可能需要實(shí)現(xiàn)自己的節(jié)點(diǎn)數(shù)據(jù)復(fù)印機(jī)功能并將其分配給Model.copyNodeDataFunction。
動(dòng)態(tài)端口示例證明了這一點(diǎn),該示例不僅需要復(fù)制每個(gè)節(jié)點(diǎn)數(shù)據(jù)所保存的四個(gè)項(xiàng)數(shù)組,而且還需要復(fù)制每個(gè)數(shù)組中的每個(gè)對(duì)象。在該示例中,在加載到圖中的模型的JSON格式表示中,將Model.copiesArrays和Model.copiesArrayObjects屬性設(shè)置為true。
對(duì)于GraphLinksModel,鏈接數(shù)據(jù)也有一個(gè)類(lèi)似的成員:GraphLinksModel.copyLinkData方法和GraphLinksModel.copyLinkDataFunction屬性。
如果您需要?jiǎng)討B(tài)修改項(xiàng)目數(shù)據(jù)的屬性值,請(qǐng)調(diào)用Model.setDataProperty,就像處理節(jié)點(diǎn)數(shù)據(jù)或鏈接數(shù)據(jù)一樣。如果您需要添加或刪除項(xiàng)目數(shù)組中的項(xiàng)目,請(qǐng)調(diào)用Model.insertArrayItem或Model.removeArrayItem方法。=====================================================
想要購(gòu)買(mǎi)GoJS正版授權(quán)的朋友可以咨詢(xún)慧都官方客服。
更多精彩內(nèi)容,歡迎關(guān)注下方的微信公眾號(hào),及時(shí)獲取產(chǎn)品最新資訊▼▼▼