視覺化—gojs 超多超實用經驗分享(四)

Echoyya、發表於2024-07-18

目錄
  • 41.監聽連線拖拽結束後的事件
  • 42.監聽畫布的修改事件
  • 43.監聽節點被 del 刪除後回撥事件(用於實現呼叫介面做一些真實的刪除操作)
  • 44.監聽節點滑鼠移入移出事件,hover 後顯示特定元素
  • 45.監聽樹圖實現滑鼠點選節點本身展開或收起子節點的功能,而不是點選另外的按鈕
  • 46.監聽文字塊編輯結束後回撥事件(用於實現呼叫介面做一些真實的編輯修改操作)
  • 47.文字編輯結束後,實現回車後取消編輯狀態
  • 用到的屬性/方法說明:
    • 1. go.LinkingTool.prototype.doActivate
    • 2. reshapable 和 resegmentable 屬性
    • 3. new go.Binding("text", "name").makeTwoWay()中 makeTwoWay 的作用
    • 4. Point 基本用法
    • 5. draggingTool.gridSnapCellSize 作用
    • 6.initialPosition 初始座標
    • 7.修改按鈕預設樣式
    • 8.放大縮小,還原重做
    • 9.根據 key 值查詢節點元素,查詢元素內的零件
    • 10.toolManager.hoverDelay

41.監聽連線拖拽結束後的事件

可以使用LinkingTool工具來監聽連線拖拽結束後的事件。具體步驟如下:

  1. 建立一個LinkingTool例項,並將其設定為圖表的預設工具:
myDiagram.toolManager.linkingTool = new go.LinkingTool();
  1. 監聽LinkingTooldoCancel()doActivate()方法,以便在連線拖拽結束後執行相應的操作:
myDiagram.toolManager.linkingTool.doCancel = function () {
  // 會在使用者取消連線拖拽時被呼叫
  console.log("Linking cancelled");
  go.LinkingTool.prototype.doCancel.call(this);
};

myDiagram.toolManager.linkingTool.doActivate = function () {
  // 會在使用者完成連線拖拽時被呼叫
  console.log("Linking completed");
  go.LinkingTool.prototype.doActivate.call(this);
};

42.監聽畫布的修改事件

在 gojs 每個案例當中都會有這樣一段程式碼,myDiagram.addDiagramListener('Modified', function() {...}) 方法是用來監聽畫布的修改事件,當畫布被修改時,會執行對應的回撥函式。 但是這個方法不適用於持續監聽,也就是說 每次修改後儲存之後,在修改才能觸發

// when the document is modified, add a "*" to the title and enable the "Save" button
myDiagram.addDiagramListener("Modified", function (e) {
  var button = document.getElementById("SaveButton");
  if (button) button.disabled = !myDiagram.isModified;
  var idx = document.title.indexOf("*");
  console.log(111);
  if (myDiagram.isModified) {
    if (idx < 0) document.title += "*";
  } else {
    if (idx >= 0) document.title = document.title.substr(0, idx);
  }
});

想要監聽畫布的每一次變化,並執行對應的 JSON 變化,該事件會在每次模型被修改時觸發,可以在回撥函式中獲取到最新的 JSON 資料。如果修改很頻繁並且後續操作也較為複雜時,建議將修改函式加一層防抖

myDiagram.addChangedListener((e) => {
  // 執行對應的 JSON 變化操作
  var jsonData = myDiagram.model.toJson();
});

43.監聽節點被 del 刪除後回撥事件(用於實現呼叫介面做一些真實的刪除操作)

刪除節點的事件名稱為 SelectionDeleting。可以使用以下程式碼來監聽刪除節點的事件並呼叫介面:

myDiagram.addDiagramListener("SelectionDeleting", (e) => {
  const deletedObj = e.subject.first();
  const deleteKey = deletedObj.part.data.key;
});

44.監聽節點滑鼠移入移出事件,hover 後顯示特定元素

透過 GoJS 的事件處理機制來實現樹節點滑鼠懸浮時顯示新增節點按鈕的功能。具體實現步驟如下:

  1. 在節點模板中新增一個按鈕元素,用於顯示新增節點按鈕。
  2. 在節點模板中新增滑鼠懸浮事件處理函式,當滑鼠懸浮在節點上時,顯示新增節點按鈕。
  3. 在節點模板中新增滑鼠移出事件處理函式,當滑鼠移出節點時,隱藏新增節點按鈕。
  4. 在新增節點按鈕的模板中新增滑鼠單擊事件處理函式,用於新增新節點。
myDiagram.nodeTemplate = $(
  go.Node,
  "Auto",
  {
    mouseEnter: function (e, node) {
      // 滑鼠懸浮在節點上時,顯示新增節點按鈕
      var addButton = node.findObject("addButton");
      if (addButton) addButton.visible = true;
    },
    mouseLeave: function (e, node) {
      // 滑鼠移出節點時,隱藏新增節點按鈕
      var addButton = node.findObject("addButton");
      if (addButton) addButton.visible = false;
    },
  },
  $(go.Shape, "RoundedRectangle", { fill: "white" }),
  $(go.TextBlock, { margin: 8 }, new go.Binding("text", "name")),
  $(
    go.Panel,
    "Horizontal",
    { alignment: go.Spot.BottomRight, margin: 4 },
    $(
      "Button",
      { name: "addButton", visible: false, click: (e, obj) => {} },
      $(go.TextBlock, "+")
    )
  )
);

45.監聽樹圖實現滑鼠點選節點本身展開或收起子節點的功能,而不是點選另外的按鈕

  // 實現滑鼠點選節點本身展開或收起子節點的功能
  myDiagram.addDiagramListener('ObjectSingleClicked', (e, obj) {
    var part = e.subject.part
    if (part instanceof go.Node) {
      if (part.isTreeExpanded) {
        part.collapseTree()
      } else {
        part.expandTree()
      }
    }
  })

46.監聽文字塊編輯結束後回撥事件(用於實現呼叫介面做一些真實的編輯修改操作)

可以使用 DiagramEvent 類的 TextEdited 事件來監聽編輯文字結束的回撥函式。該事件在文字編輯器完成編輯並關閉時觸發.

myDiagram.addDiagramListener("TextEdited", (e) => {
  const editedText = e.subject.text;
  const key = e.subject.part.data.key;
  console.log("編輯後的內容: " + editedText);
  console.log("節點key:", key);
});

47.文字編輯結束後,實現回車後取消編輯狀態

預設情況下,在使用者完成文字塊編輯後。需要滑鼠移出後點選其他區域,才能取消當前正在編輯的文字塊的編輯狀態,並且在預設情況下,按下回車enter鍵,視為換行。

但大部分使用者的習慣性操作為按下回車enter鍵,即已經完成編輯操作,而不是換行,因此需要改一個屬性。是否可以多行-isMultiline,屬性值為 false 時,按下回車完成編輯操作.

$(
  go.TextBlock,
  {
    editable: true, // 是否 可編輯
    isMultiline: false, // 是否 可多行,false
  },
  new go.Binding("text", "name")
);

用到的屬性/方法說明:

1. go.LinkingTool.prototype.doActivate

是 GoJS 庫中的一個方法,用於在使用者開始使用連結工具時啟用該工具。當使用者點選連結工具按鈕或按下連結工具快捷鍵時,該方法將被呼叫。

2. reshapable 和 resegmentable 屬性

  • reshapable屬性:表示節點是否可以被重新調整形狀。設定為true,則節點可以透過拖動邊緣或角落來改變其形狀。設定為false,則節點的形狀將保持不變。

  • resegmentable屬性:表示節點的連線是否可以被重新分段。設定為true,則節點的連線可以透過拖動中間的點來新增或刪除分段。設定為false,則節點的連線將保持不變。

3. new go.Binding("text", "name").makeTwoWay()中 makeTwoWay 的作用

makeTwoWay 方法用於將繫結設定為雙向繫結。在 GoJS 中,繫結是指將資料模型中的屬性與圖形元素的屬性相互關聯,以便在資料模型中更改屬性時,圖形元素的屬性也會相應地更改。

當使用 makeTwoWay 方法時,繫結將變為雙向繫結,這意味著當圖形元素的屬性更改時,資料模型中的屬性也會相應地更改。這使得資料模型和圖形元素之間的同步更加方便和高效。

4. Point 基本用法

Point 是 GoJS 中的一個類,用於表示一個二維平面上的點。它的定義在 GoJS 的 API 文件中可以找到。

在 GoJS 中,可以使用 new go.Point(x, y) 的方式建立一個 Point 物件,其中 xy 分別表示點的橫座標和縱座標。例如:

var point = new go.Point(100, 200);

也可以使用 Point.parse(str) 方法將一個字串解析為一個 Point 物件。str 是一個字串,表示一個點的座標。Point.parse(str) 方法將這個字串解析為一個 Point 物件,並將其賦值給 point 變數。例如:

var str = "100 200";
var point = go.Point.parse(str);

5. draggingTool.gridSnapCellSize 作用

draggingTool.gridSnapCellSize 是 gojs 中拖拽工具的屬性之一,它定義了拖拽時網格捕捉的單元格大小。當設定了這個屬性後,拖拽的元素會自動對齊到網格的單元格邊界上,從而使得佈局更加整齊美觀。例如,如果將 draggingTool.gridSnapCellSize 設定為 20,則拖拽的元素會自動對齊到 20 畫素的邊界上。這個屬性的預設值為 null,表示不進行網格捕捉。

myDiagram = $(go.Diagram, "myDiagramDiv", {
  "draggingTool.gridSnapCellSize": new go.Size(1, 5),
});

6.initialPosition 初始座標

gojs 生成繪圖時,預設情況下是將圖形放置在畫布的中心位置。因為 gojs 的預設佈局是居中佈局。但是可以透過設定 Diagram 的 initialPosition 屬性來改變它的位置。如果想讓繪圖從左上角開始,可以:

var myDiagram = $(go.Diagram, "myDiagramDiv", {
  initialPosition: new go.Point(0, 0), // 初始座標位置
});

7.修改按鈕預設樣式

$(
  "Button",
  {
    width: 15,
    height: 15,
    "ButtonBorder.fill": "green", // 改掉預設填充色
    _buttonFillOver: "red", // 滑鼠懸浮填充色
    //   _buttonStrokeOver: "#000", // 滑鼠懸浮邊框色
  },
  $(go.TextBlock, "按鈕文字")
);

8.放大縮小,還原重做

// 放大
myDiagram.scale += 0.1;
// 縮小
myDiagram.scale -= 0.1;
// 還原
myDiagram.commandHandler.undo();
// 重做
myDiagram.commandHandler.redo();

9.根據 key 值查詢節點元素,查詢元素內的零件

// 根據 key 值查詢節點元素
const node = diagram.findNodeForKey("key值");
// 查詢元素內的零件: 查詢元素name:TEXT的零件,字型顏色改為紅色
node.findObject("TEXT").stroke = "red";

10.toolManager.hoverDelay

toolManager.hoverDelay 屬性用於設定滑鼠指標懸停在圖表元素上時將觸發懸停事件的延遲時間

滑鼠懸停在圖形元素上才會觸發 hover 事件。預設值為 300 毫秒。如果將其設定為 200,表示滑鼠懸停在圖形元素上 200 毫秒後才會觸發 hover 事件。

myDiagram = $(go.Diagram, "myDiagramDiv", {
  "toolManager.hoverDelay": 200, // 延時
});

我一般會用在 toolTip 的顯示時間上,滑鼠懸浮顯示 toolTip,預設延時時間有點長,可以透過以上屬性,更改為合適的時間,toolTip的基本用法:

$(
  go.TextBlock,
  {
    width: 100,
    maxLines: 1,
    overflow: go.TextBlock.OverflowEllipsis,
  },
  new go.Binding("text", "name").makeTwoWay(),
  {
    toolTip: $("ToolTip", $(go.TextBlock, new go.Binding("text", "name"))),
  }
);

相關文章