【问题标题】:Skip all nodes on path between 2 nodes in GoJS diagram跳过GoJS图中2个节点之间路径上的所有节点
【发布时间】:2020-02-17 17:18:38
【问题描述】:

我有一个 GoJS 图表,我想在其中隐藏/取消隐藏任意 2 个选定节点之间路径上的所有节点。

例如在图中 A --> B --> C --> D

我想隐藏 B 和 C 节点,让它变成这样 A --(2)--> D

其中 (2) 表示隐藏了 2 个节点。 当然,图表可能要复杂得多,我想任意隐藏/取消隐藏节点。

我尝试在 2 个节点之间对项目进行分组,这适用于某些场景,但由于可能有一些节点需要隐藏,这些节点已经是组的一部分 - 我被卡住了。

在 GoJS 中是否有一个开箱即用的(或明显的)解决方案?

谢谢

【问题讨论】:

  • 欢迎来到 StackOverflow! Stack Overflow 不是免费的代码编写服务,也不是指南、教程和文档的替代品。请在您的问题中添加您实现此功能的尝试。见:Ask questions, get answers, no distractionsHow do I ask a good question?help center
  • 感谢您的欢迎。感谢您的关注。如果我正在寻找代码编写服务等,我会买一些。然而,就我而言,我只是花了一些时间评估 GoJS 库并陷入困境,所以我问了一个可以对二进制答案感到满意的问题。你知道答案吗?
  • 看起来你需要做一些自定义功能,你做了什么,请分享你的工作代码

标签: gojs


【解决方案1】:

以下代码假定您不想在模型中存储虚拟节点。隐藏节点不可见,并且虚拟节点通过虚拟链接与与现在隐藏节点连接的相同未选择节点连接。

<!DOCTYPE html>
<html>
<head>
<title>Simple Coalescing of Nodes without using Collapsed Groups</title>
<!-- Copyright 1998-2020 by Northwoods Software Corporation. -->
<meta charset="UTF-8">
<script src="https://unpkg.com/gojs"></script>
<script id="code">
  function init() {
    var $ = go.GraphObject.make;

    myDiagram =
      $(go.Diagram, "myDiagramDiv",
          {
            layout: $(go.ForceDirectedLayout,
                      { maxIterations: 500, isRealtime: false }),
            "InitialLayoutCompleted": function(e) {
              e.diagram.nodes.each(function(g) {
                if (g instanceof go.Group) g.layout = null;
              });
            },
            "undoManager.isEnabled": true
          });

    myDiagram.nodeTemplate =
      $(go.Node, "Auto",
        { width: 80, height: 50 },
        $(go.Shape,
          { fill: "white", portId: "", fromLinkable: true, toLinkable: true, cursor: "pointer" },
          new go.Binding("fill", "color")),
        $(go.TextBlock, { textAlign: "center" },
          new go.Binding("text"))
      );

    myDiagram.linkTemplate =
      $(go.Link,
        { relinkableFrom: true, relinkableTo: true },
        $(go.Shape),
        $(go.Shape, { toArrow: "OpenTriangle" })
      );

    myDiagram.groupTemplate =
      $(go.Group, "Auto",
        { layout: $(go.CircularLayout) },
        $(go.Shape, { fill: "#8882" }),
        $(go.Placeholder, { padding: 8 }),
        $(go.TextBlock, { font: "bold 12pt sans-serif" },
          new go.Binding("text", "key"))
      )

    myDiagram.model = new go.GraphLinksModel(
    [
      { key: 1, text: "Concept Maps" },
      { key: 2, text: "Organized Knowledge" },
      { key: 3, text: "Context Dependent" },
      { key: 4, text: "Concepts", group: "G1" },
      { key: 5, text: "Propositions", group: "G1" },
      { key: 6, text: "Associated Feelings or Affect", group: "G1" },
      { key: 7, text: "Perceived Regularities" },
      { key: 8, text: "Labeled" },
      { key: 9, text: "Hierarchically Structured" },
      { key: 10, text: "Effective Teaching", group: "G2" },
      { key: 11, text: "Crosslinks", group: "G2" },
      { key: 12, text: "Effective Learning" },
      { key: 13, text: "Events (Happenings)" },
      { key: 14, text: "Objects (Things)" },
      { key: 15, text: "Symbols", group: "G3" },
      { key: 16, text: "Words", group: "G3" },
      { key: 17, text: "Creativity", group: "G3" },
      { key: 18, text: "Interrelationships" },
      { key: 19, text: "Infants" },
      { key: 20, text: "Different Map Segments" },
      { key: "G1", isGroup: true },
      { key: "G2", isGroup: true },
      { key: "G3", isGroup: true }
    ],
    [
      { from: 1, to: 2, text: "represent" },
      { from: 2, to: 3, text: "is" },
      { from: 2, to: 4, text: "is" },
      { from: 2, to: 5, text: "is" },
      { from: 2, to: 6, text: "includes" },
      { from: 2, to: 10, text: "necessary\nfor" },
      { from: 2, to: 12, text: "necessary\nfor" },
      { from: 4, to: 5, text: "combine\nto form" },
      { from: 4, to: 6, text: "include" },
      { from: 4, to: 7, text: "are" },
      { from: 4, to: 8, text: "are" },
      { from: 4, to: 9, text: "are" },
      { from: 5, to: 9, text: "are" },
      { from: 5, to: 11, text: "may be" },
      { from: 7, to: 13, text: "in" },
      { from: 7, to: 14, text: "in" },
      { from: 7, to: 19, text: "begin\nwith" },
      { from: 8, to: 15, text: "with" },
      { from: 8, to: 16, text: "with" },
      { from: 9, to: 17, text: "aids" },
      { from: 11, to: 18, text: "show" },
      { from: 12, to: 19, text: "begins\nwith" },
      { from: 17, to: 18, text: "needed\nto see" },
      { from: 18, to: 20, text: "between" }
    ]);
  }

  function test() {
    if (myDiagram.selection.count === 0) return;
    if (myDiagram.selection.count === 1 && myDiagram.selection.first().hidden !== null) {
      // only expand a single coalesced node (dummy) at a time
      myDiagram.commit(function(diag) {
        var dummy = diag.selection.first();
        diag.remove(dummy);  // also removes connected links that are dummies
        dummy.hidden.each(function(n) {
          n.visible = true;
        });
        diag.selectCollection(dummy.hidden);
      }, "expanded");
    } else {
      myDiagram.commit(function(diag) {
        var $ = go.GraphObject.make;
        var dummy = $(go.Node, "Auto",
                      { locationSpot: go.Spot.Center },
                      $(go.Shape, "Circle", { fill: "yellow" }),
                      $(go.TextBlock, "hidden\nnodes", { textAlign: "center" })
                    );
        dummy.hidden = new go.Set();  // keep track of the nodes that it represents
        diag.selection.each(function(n) {
          if (n instanceof go.Node) {
            dummy.hidden.add(n);
            n.visible = false;
            new go.List(n.linksConnected).each(function(l) {
              if (!l.fromNode.isSelected || !l.toNode.isSelected) {
                var dum = $(go.Link,
                            $(go.Shape, { stroke: "brown" }),
                            $(go.Shape, { toArrow: "OpenTriangle", stroke: "brown" }));
                if (!l.fromNode.isSelected) dum.fromNode = l.fromNode;
                if (!l.toNode.isSelected) dum.toNode = l.toNode;
                if (!dum.fromNode) dum.fromNode = dummy;
                if (!dum.toNode) dum.toNode = dummy;
                diag.add(dum);
              }
            });
          }
        });
        dummy.location = diag.computePartsBounds(diag.selection).center;
        diag.add(dummy);
        diag.select(dummy);
      }, "coalesced nodes");
    }
  }
</script>
</head>
<body onload="init()">
  <div id="myDiagramDiv" style="border: solid 1px black; width:100%; height:600px"></div>
  <button onclick="test()">Test</button> to hide selected nodes,
  replaced by a temporary yellow node and temporary brown links that are not in the model
</body>
</html>

【讨论】:

  • 非常感谢。当您回复 GoJS 的制造商时,我假设没有开箱即用的解决方案 - 但这已经足够接近了。有几个更复杂的场景需要测试,但对于您的示例来说这很容易。再次感谢。
  • 顺便说一句 - 我们尝试的第一次迭代是没有节点的模板来隐藏哪些类型的工作,因为节点没有被渲染。但是当有很多节点要隐藏并且您进行布局时,它很糟糕,因为线可能不直。
  • 布局适用于所有节点和链接,即使它们没有建模(即从模型数据创建)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-03-21
  • 1970-01-01
  • 2011-03-08
  • 2012-06-21
  • 1970-01-01
  • 2017-08-21
  • 1970-01-01
相关资源
最近更新 更多