1. 程式人生 > 實用技巧 >GoJS學習-模型與模板

GoJS學習-模型與模板

實現節點外觀與節點資料分離的一種方法是使用資料模型和節點模板。

模型基本上只是一個數據集合,其中包含每個節點和每個連結的基本資訊。

模板基本上只是一個可以複製的部分。您將為NodeLink具有不同的模板。

實際上,已經具有非常簡單的節點和連結預設模板。如果要自定義圖中節點的外觀,可以通過設定Diagram.nodeTemplate來替換預設節點模板。

要自動使用模板,請為該圖提供一個模型,其中包含每個節點的資料和每個連結的資料。

GraphLinksModel保持節點的資料和連結資料作為值的集合(實際上陣列)GraphLinksModel.nodeDataArrayGraphLinksModel.linkDataArray

。然後,設定Diagram.model屬性,以便該圖可以為所有節點資料建立Node,併為所有連結資料建立Link

模型解釋並維護資料之間的引用。每個節點資料應具有唯一的鍵值,以便可以可靠地解析對節點資料的引用。模型還管理動態新增和刪除資料。

型中的節點資料和連結資料可以是任何JavaScript物件。您可以決定這些物件具有哪些屬性-根據需要新增任意數量的應用程式。由於這是JavaScript,因此您甚至可以動態新增屬性。GoJS模型假定資料上存在幾個屬性,例如“鍵”(在節點資料上)和“類別”,“從”和“到”(後兩個在連結資料上)。

但是,可以通過設定名稱以“ ... Property”結尾的模型屬性來告訴模型使用不同的屬性名稱。

  var nodeDataArray = [
    { key: "Alpha"},
    { key: "Beta" }
  ];
  var linkDataArray = [
    { from: "Alpha", to: "Beta" }
  ];
  diagram.model = new go.GraphLinksModel(nodeDataArray, linkDataArray);

這顯示兩個節點和一個連結,但是這些節點並沒有按照我們想要的方式出現。

因此,我們將自定義節點模板以展示。

  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);

現在,該圖看起來更好,但是尚未對節點進行引數化-它們都是相同的!我們可以通過使用資料繫結來實現該引數化。

使用資料繫結對節點進行引數化

資料繫結是一個宣告性宣告,其中應使用一個物件的屬性值來設定另一個物件的屬性值。

在這種情況下,我們要確保TextBlock.text屬性獲取相應節點資料的“鍵”值。並且我們要確保Shape.fill屬性設定為相應節點資料的“ color”屬性值所給定的顏色/畫筆。

我們可以通過建立Binding物件並將其與目標GraphObject關聯來宣告此類資料繫結您可以通過程式設計方式呼叫GraphObject.bind來執行此操作但是,當使用go.GraphObject.make時,當您傳遞Binding時會自動發生

diagram.nodeTemplate =
    $(go.Node, "Auto",
      $(go.Shape,
        { figure: "RoundedRectangle",
          fill: "white" },  // 預設Shape.fill值
        new go.Binding("fill", "color")),  // 繫結 nodedata.color的值到fill
      $(go.TextBlock,
        { margin: 5 },
        new go.Binding("text", "key"))  // 繫結nodedata.key的值到TextBlock
    );

  var nodeDataArray = [
    { key: "Alpha", color: "lightblue" },  
    { key: "Beta", color: "pink" }
  ];
  var linkDataArray = [
    { from: "Alpha", to: "Beta" }
  ];
  diagram.model = new go.GraphLinksModel(nodeDataArray, linkDataArray);

您可能會注意到連結是不同的:它有一個箭頭。當我們第一次使用程式碼構建此圖時,沒有箭頭。但是預設的Diagram.linkTemplate包含一個箭頭,在此示例中,我們沒有用自定義模板替換連結模板。

請注意,上面模板中Shape.fill值獲得了兩次值。首先將其預設值設定為“white”。然後,繫結將其設定為節點資料的“color”屬性具有的任何值。如果節點資料不具有“ color”屬性或在獲取該值時出錯,則能夠指定保留的初始值可能會很有用。

我們還可以更加精確地瞭解模板是什麼。模板是一個Part,它可能具有一些資料Binding,並且它本身並不是圖中的一部分,但可以被複制以建立新增到圖中的零件。

樹模型

較簡單的模型TreeModel僅支援形成樹形圖的連結關係。沒有單獨的連結資料,因此沒有“ linkDataArray”。樹中固有的父子關係由子節點資料上的額外屬性確定,該屬性通過其鍵引用父節點。如果未定義名稱預設為“ parent”的該屬性,則該資料的對應節點為樹根。每個連結仍然是資料繫結的,但是連結的資料是子節點資料。

 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。但是,僅僅因為您的圖形是樹形結構並不意味著您必須使用TreeModel。

您可能會發現資料是用定義連結關係的單獨“表”組織的,因此使用GraphLinksModel是最自然的。或者,您可能想使用TreeModel不支援的其他功能。

修改模型的值:

     var node = myDiagram.model.findNodeDataForKey('Beta')
      myDiagram.model.setDataProperty(node,'color','red')

當JavaScript陣列或物件已經是模型的一部分時,需要呼叫諸如Model.addNodeDataModel.setDataProperty之類的模型方法。

首次為Model.nodeDataArray構建物件陣列時,或將JavaScript物件初始化為新的節點資料物件時,此類呼叫都是不必要的。但是,一旦資料成為模型的一部分,就需要呼叫模型的方法來實現更改。

儲存和載入模型

GoJS不需要您以任何特定的介質或格式儲存模型。但是因為這是JavaScript,而JSON是最流行的資料交換格式,所以我們確實使以JSON格式的文字形式編寫和讀取模型變得容易。

只需呼叫Model.toJson即可生成表示您的模型的字串。 再次載入時,需要將JSON.parse格式化json資料

let modelJson=myDiagram.model.toJSON()
            
modelJson=JSON.parse(modelJson)
myDiagram.model=new go.GraphLinksModel(modelJson.nodeDataArray,modelJson.linkDataArray)