翻譯|使用教程|編輯:吳園園|2019-09-12 14:36:45.630|閱讀 758 次
概述:GoJS是一款功能強大,快速且輕量級的流程圖控件,可幫助你在JavaScript 和HTML5 Canvas程序中創(chuàng)建流程圖。本教程將為您介紹如何使用使用模型和模板。
# 界面/圖表報表/文檔/IDE等千款熱門軟控件火熱銷售中 >>
GoJS是一款功能強大,快速且輕量級的流程圖控件,可幫助你在JavaScript 和HTML5 Canvas程序中創(chuàng)建流程圖,且極大地簡化您的JavaScript / Canvas 程序。
您可以以編程方式構(gòu)建節(jié)點和鏈接圖。但GoJS提供了一種以更具說明性的方式構(gòu)建圖表的方法。您只提供圖表所需的節(jié)點和鏈接數(shù)據(jù)(即模型)以及自動復制到圖表中的零件實例(即模板)。可以通過節(jié)點和鏈接數(shù)據(jù)的屬性來參數(shù)化這些模板。
使用代碼構(gòu)建圖表
讓我們嘗試構(gòu)建兩個節(jié)點并用鏈接連接它們。這是一種方法:
var node1 = $(go.Node, "Auto", $(go.Shape, { figure: "RoundedRectangle", fill: "lightblue" }), $(go.TextBlock, { text: "Alpha", margin: 5 }) ) diagram.add(node1); var node2 = $(go.Node, "Auto", $(go.Shape, { figure: "RoundedRectangle", fill: "pink" }), $(go.TextBlock, { text: "Beta", margin: 5 }) ); diagram.add(node2); diagram.add( $(go.Link, { fromNode: node1, toNode: node2 }, $(go.Shape) ));
這會產(chǎn)生一個漂亮,簡單的圖表。如果拖動其中一個節(jié)點,您將看到該鏈接仍然與其連接。
雖然這種構(gòu)建圖表的方式可行,但在創(chuàng)建大圖時,它不會很好地擴展。通常,您需要不同數(shù)量的節(jié)點,每個節(jié)點與其他節(jié)點非常相似。最好分享節(jié)點的結(jié)構(gòu),但參數(shù)化一些值應該變化的東西。
一種可能性是將代碼構(gòu)建到一個函數(shù)中,該函數(shù)返回一個完全構(gòu)造的Node,包括其可視樹中的所有Panel和其他GraphObject。您可能希望參數(shù)化該函數(shù),以便提供所需的字符串和顏色以及圖形和圖像URL。然而,這種方法非常特別:系統(tǒng)很難知道如何自動調(diào)用這些功能以便按需創(chuàng)建新節(jié)點或新鏈接。此外,當您的應用程序數(shù)據(jù)動態(tài)更改時,您將如何使用此類函數(shù)更新現(xiàn)有節(jié)點和鏈接中現(xiàn)有對象的屬性,而不會無效地重新創(chuàng)建所有內(nèi)容?如果您希望在應用程序數(shù)據(jù)發(fā)生變化時自動更新任何內(nèi)容/所有內(nèi)容,系統(tǒng)將如何知道該怎么做?
這個圖表構(gòu)建代碼也比管理節(jié)點引用需要更麻煩,以便您可以將它們鏈接起來。這類似于在代碼中構(gòu)建節(jié)點的可視樹時必須使用臨時命名變量并在需要時引用它們時的早期問題。
我們要尋找的是將所有節(jié)點的外觀,定義和構(gòu)造與描述每個特定節(jié)點的獨特方面所需的應用程序數(shù)據(jù)分開。
使用模型和模板
實現(xiàn)節(jié)點外觀與節(jié)點數(shù)據(jù)分離的一種方法是使用數(shù)據(jù)模型和節(jié)點模板。模型基本上只是一個數(shù)據(jù)集合,它包含每個節(jié)點和每個鏈接的基本信息。模板基本上只是一個可以復制的部分 ; 您將擁有Node和Link的不同模板。
事實上,一個Diagram已經(jīng)有非常簡單的節(jié)點和鏈接默認模板。如果要自定義圖中節(jié)點的外觀,可以通過設置Diagram.nodeTemplate替換默認節(jié)點模板。
要自動使用模板,請?zhí)峁┮粋€模型,其中包含每個節(jié)點的數(shù)據(jù)和每個鏈接的數(shù)據(jù)。GraphLinksModel保持節(jié)點的數(shù)據(jù)和鏈接數(shù)據(jù)作為值的集合(實際上陣列) GraphLinksModel.nodeDataArray和GraphLinksModel.linkDataArray。然后設置Diagram.model屬性,以便該圖可以為所有節(jié)點數(shù)據(jù)創(chuàng)建Node,為所有鏈接數(shù)據(jù)創(chuàng)建Link。
模型解釋和維護數(shù)據(jù)之間的引用。期望每個節(jié)點數(shù)據(jù)具有唯一的鍵值,以便可以可靠地解析對節(jié)點數(shù)據(jù)的引用。模型還管理動態(tài)添加和刪除數(shù)據(jù)。
模型中的節(jié)點數(shù)據(jù)和鏈接數(shù)據(jù)可以是任何JavaScript對象。您可以決定這些對象具有哪些屬性 - 添加您的應用程序所需的數(shù)量。由于這是JavaScript,您甚至可以動態(tài)添加屬性。GoJS模型假設存在數(shù)個屬性,例如“密鑰”(在節(jié)點數(shù)據(jù)上)和“類別”和“從”和“到”(后兩個在鏈接數(shù)據(jù)上)。但是,您可以通過設置名稱以“... Property”結(jié)尾的模型屬性來告訴模型使用不同的屬性名稱。
節(jié)點數(shù)據(jù)對象通常在“key”屬性中具有其節(jié)點的唯一鍵值。目前,節(jié)點數(shù)據(jù)鍵必須是字符串或數(shù)字。您可以通過Node.key屬性或通過獲取Node的密鑰someNode.data.key。
讓我們創(chuàng)建一個圖表,提供最少量的必要信息。特定節(jié)點數(shù)據(jù)已放入JavaScript對象數(shù)組中。我們在鏈接數(shù)據(jù)對象的單獨數(shù)組中聲明鏈接關(guān)系。每個鏈接數(shù)據(jù)通過使用其鍵來保存對節(jié)點數(shù)據(jù)的引用。通常,引用是“from”和“to”屬性的值。
var nodeDataArray = [ { key:“Alpha” }, { key:“Beta” } ]。 var linkDataArray = [ { from:“Alpha”,to:“Beta” } ]。diagram.model = new go.GraphLinksModel(nodeDataArray,linkDataArray);
這導致兩個節(jié)點和一個鏈接,但節(jié)點不按我們想要的方式顯示。因此,我們將節(jié)點模板定義為我們在上面執(zhí)行的特定節(jié)點構(gòu)造的概括。
diagram.nodeTemplate = // provide custom Node appearance $(go.Node, "Auto", $(go.Shape, { figure: "RoundedRectangle", fill: "white" }), $(go.TextBlock, { text: "hello!", margin: 5 }) ); var nodeDataArray = [ { key: "Alpha" }, { key: "Beta" } ]; var linkDataArray = [ { from: "Alpha", to: "Beta" } ]; diagram.model = new go.GraphLinksModel(nodeDataArray, linkDataArray);
現(xiàn)在圖表看起來更好,但節(jié)點尚未參數(shù)化 - 它們都是相同的!我們可以通過使用數(shù)據(jù)綁定來實現(xiàn)該參數(shù)化。
使用數(shù)據(jù)綁定參數(shù)化節(jié)點
數(shù)據(jù)綁定是一種聲明性聲明,應該使用一個對象的屬性值來設置另一個對象的屬性值。
在這種情況下,我們希望確保TextBlock.text屬性獲取相應節(jié)點數(shù)據(jù)的“鍵”值。我們希望確保將Shape.fill屬性設置為相應節(jié)點數(shù)據(jù)的“color”屬性值給出的顏色/畫筆。
我們可以通過創(chuàng)建Binding對象并將它們與目標GraphObject相關(guān)聯(lián)來聲明這樣的數(shù)據(jù)綁定。通過調(diào)用GraphObject.bind以編程方式執(zhí)行此操作。但是當使用go.GraphObject.make時,這會在傳入Binding時自動發(fā)生。
diagram.nodeTemplate = $(go.Node, "Auto", $(go.Shape, { figure: "RoundedRectangle", fill: "white" }, // default Shape.fill value new go.Binding("fill", "color")), // binding to get fill from nodedata.color $(go.TextBlock, { margin: 5 }, new go.Binding("text", "key")) // binding to get TextBlock.text from nodedata.key ); var nodeDataArray = [ { key: "Alpha", color: "lightblue" }, // note extra property for each node data: color { key: "Beta", color: "pink" } ]; var linkDataArray = [ { from: "Alpha", to: "Beta" } ]; diagram.model = new go.GraphLinksModel(nodeDataArray, linkDataArray);
現(xiàn)在我們有與以前相同的圖表結(jié)果,但它以更一般的方式實現(xiàn)。您可以輕松添加更多節(jié)點和鏈接數(shù)據(jù)以構(gòu)建更大的圖表。您可以輕松更改所有節(jié)點的外觀而無需修改數(shù)據(jù)。
實際上,您可能會注意到鏈接不同:它有一個箭頭。當我們第一次使用代碼構(gòu)建此圖時,沒有包含箭頭。但是默認的Diagram.linkTemplate包含一個箭頭,在本例中我們沒有用自定義鏈接模板替換鏈接模板。
請注意,上面模板中Shape.fill的值獲取兩次值。首先它被設置為“白色”。然后綁定將它設置為節(jié)點數(shù)據(jù)的“顏色”屬性具有的任何值。能夠指定在節(jié)點數(shù)據(jù)沒有“顏色”屬性或者獲得該值時出錯的情況下保留的初始值可能是有用的。
在這一點上,我們也可以更準確地了解模板是什么。模板是一個部分,可能有一些數(shù)據(jù)綁定以及本身不是圖中,但可能被復制到創(chuàng)建要添加到圖的部分。
模板定義
所有預定義模板的實現(xiàn)都在Extensions目錄的Templates.js中提供。您可能希望在創(chuàng)建自己的模板時復制和修改這些定義。
這些定義可能不是GoJS中實際標準模板實現(xiàn)的最新描述。
各種模型
模型是一種將數(shù)據(jù)對象集合解釋為抽象圖形的方式,其中各種關(guān)系由數(shù)據(jù)屬性和模型所做的假設確定。最簡單的模型Model只能保存“部件”而它們之間沒有任何關(guān)系 - 沒有鏈接或組。但該模型類充當其他類型模型的基類。
GraphLinksModel
您在上面看到的模型GraphLinksModel實際上是最常見的一種。它為每個鏈接使用單獨的鏈接數(shù)據(jù)對象支持鏈接關(guān)系。鏈接可以連接的節(jié)點沒有固有的限制,因此允許自反和重復鏈接。鏈接也可能導致圖中的循環(huán)。但是,您可以通過設置各種屬性(例如Diagram.validCycle)來阻止用戶繪制此類鏈接。如果您希望鏈接看起來與鏈接而不是節(jié)點連接,則可以通過具有屬于鏈接的特殊節(jié)點(稱為“標簽節(jié)點”)來實現(xiàn),這些節(jié)點沿著鏈接的路徑排列。與文本標簽在鏈接上排列的方式相同。
此外,GraphLinksModel還支持在節(jié)點內(nèi)識別邏輯上和物理上不同的連接對象(稱為“端口”)。因此,單個鏈路可以與特定端口連接而不是與整個節(jié)點連接。“ 鏈接點和端口”頁面更深入地討論了此主題。
一個GraphLinksModel還支持組成員關(guān)系。任何部分最多只能屬于一個集團 ; 任何群體都不能直接或間接地包含在內(nèi)。
TreeModel
一種更簡單的模型TreeModel僅支持形成樹形結(jié)構(gòu)圖的鏈接關(guān)系。沒有單獨的鏈接數(shù)據(jù),因此沒有“l(fā)inkDataArray”。樹中固有的父子關(guān)系由子節(jié)點數(shù)據(jù)上的額外屬性確定,該屬性通過其鍵引用父節(jié)點。如果該屬性(其名稱默認為“parent”)未定義,則該數(shù)據(jù)的相應節(jié)點是樹根。每個鏈接仍然是數(shù)據(jù)綁定,但鏈接的數(shù)據(jù)是子節(jié)點數(shù)據(jù)。
diagram.nodeTemplate = $(go.Node, "Auto", $(go.Shape, { figure: "Ellipse" }, new go.Binding("fill", "color")), $(go.TextBlock, { margin: 5 }, new go.Binding("text", "key")) ); var nodeDataArray = [ { key: "Alpha", color: "lightblue" }, { key: "Beta", parent: "Alpha", color: "yellow" }, // note the "parent" property { key: "Gamma", parent: "Alpha", color: "orange" }, { key: "Delta", parent: "Alpha", color: "lightgreen" } ]; diagram.model = new go.TreeModel(nodeDataArray);
許多面向樹的樣本使用TreeModel而不是GraphLinksModel。但僅僅因為您的圖形是樹形結(jié)構(gòu)并不意味著您必須使用TreeModel。您可能會發(fā)現(xiàn)您的數(shù)據(jù)是使用單獨的“表”來組織的,該表定義了鏈接關(guān)系,因此使用GraphLinksModel是最自然的。或者您可能想要使用TreeModel不支持的其他功能。
修改模型
如果要以編程方式添加或刪除節(jié)點,則可能需要調(diào)用 Model.addNodeData和Model.removeNodeData方法。如果您只有唯一的鍵值,請使用Model.findNodeDataForKey方法查找特定的節(jié)點數(shù)據(jù)對象。您還可以調(diào)用Model.copyNodeData來創(chuàng)建節(jié)點數(shù)據(jù)對象的副本,然后可以將其修改并傳遞給Model.addNodeData。
它不能簡單地修改Model.nodeDataArray,因為GoJS軟件不會被通知有關(guān)任何JavaScript數(shù)組的任何更改,因此無法根據(jù)需要添加或刪除Node或其他部分。
同樣,它不能簡單地修改節(jié)點數(shù)據(jù)對象的屬性。任何依賴于屬性的Binding都不會被通知任何更改,因此它將無法更新其目標GraphObject屬性。例如,設置color屬性不會導致Shape更改顏色。
var data = myDiagram.model.findNodeDataForKey("Delta"); // This will NOT change the color of the "Delta" Node if (data !== null) data.color = "red";
相反,您需要調(diào)用Model.setDataProperty來修改模型中的對象。
var data = myDiagram.model.findNodeDataForKey("Delta"); // This will update the color of the "Delta" Node if (data !== null) myDiagram.model.setDataProperty(data, "color", "red");
當JavaScript數(shù)組或?qū)ο笠呀?jīng)是模型的一部分時,需要 調(diào)用模型方法,如Model.addNodeData或Model.setDataProperty。首次為Model.nodeDataArray構(gòu)建對象數(shù)組 或?qū)avaScript對象初始化為新節(jié)點數(shù)據(jù)對象時,不需要此類調(diào)用。但是,一旦數(shù)據(jù)成為模型的一部分,就必須調(diào)用模型的方法來實現(xiàn)更改。
保存和加載模型
GoJS不要求您以任何特定介質(zhì)或格式保存模型。但由于這是JavaScript和JSON是最流行的數(shù)據(jù)交換格式,我們確實可以輕松地以JSON格式編寫和讀取模型。
只需調(diào)用Model.toJson即可生成表示模型的字符串。調(diào)用靜態(tài)方法Model.fromJson來構(gòu)造并初始化給定Model.toJson生成的字符串的模型。許多示例都證明了這一點 - 搜索名為“save”和“l(fā)oad”的JavaScript函數(shù)。這些函數(shù)中的大多數(shù)都在頁面本身上編寫和讀取TextArea,以便您可以查看和修改JSON文本,然后加載它以獲取新圖表。但是在編輯時請小心,因為JSON語法非常嚴格,任何語法錯誤都會導致這些“加載”函數(shù)失敗。
JSON格式的文本對您可以表示的數(shù)據(jù)類型有嚴格的限制,無需額外的假設。要保存和加載您在節(jié)點數(shù)據(jù)(或鏈接數(shù)據(jù))上設置的任何數(shù)據(jù)屬性,它們需要滿足以下要求:
該屬性是可枚舉的,其名稱不以下劃線開頭(您可以使用以下劃線開頭的屬性名稱,但不會保存它們)
屬性值未定義且不是函數(shù)(JSON不能忠實地保存函數(shù))
模型知道如何將屬性值轉(zhuǎn)換為JSON格式(數(shù)字,字符串,JavaScript數(shù)組或純JavaScript對象)
作為對象或數(shù)組的屬性值形成樹結(jié)構(gòu) - 沒有共享或循環(huán)引用
Model.toJson和Model.fromJson還將處理Point,Size,Rect,Spot,Margin,Geometry和非模式Brush es的實例 。但是,我們建議您使用這些類parse和stringify靜態(tài)函數(shù)將這些對象存儲在其字符串表示中。
因為您使用的是JavaScript,所以向您的節(jié)點數(shù)據(jù)添加數(shù)據(jù)屬性是微不足道的。這允許您將所需的任何信息與每個節(jié)點相關(guān)聯(lián)。但是,如果您需要將某些信息與模型相關(guān)聯(lián),即使根本沒有節(jié)點數(shù)據(jù)也會存在,您可以向Model.modelData對象添加屬性。該對象的屬性將被寫入Model.toJson和閱讀Model.fromJson,就像節(jié)點數(shù)據(jù)對象被寫入和讀取。
=====================================================
想要購買GoJS正版授權(quán)的朋友可以。
更多精彩內(nèi)容,歡迎關(guān)注下方的微信公眾號,及時獲取產(chǎn)品最新資訊▼▼▼
本站文章除注明轉(zhuǎn)載外,均為本站原創(chuàng)或翻譯。歡迎任何形式的轉(zhuǎn)載,但請務必注明出處、不得修改原文相關(guān)鏈接,如果存在內(nèi)容上的異議請郵件反饋至chenjj@fc6vip.cn
文章轉(zhuǎn)載自: