Vis.js 当节点具有坐标时,节点布局未按预期运行

Vis.js node layout not behaving as expected when nodes have coordinates

当节点指定了坐标时,我在理解 vis.js 网络中节点的行为时遇到了一些困难。在下面的代码中,我做了 3 个示例,其中示例 1 和示例 3 的行为符合预期,但示例 2 的行为却出乎意料。

在示例2中,我为节点指定了坐标,但布局不固定。网络最初打开物理,然后在应该关闭稳定物理时关闭。

我预计节点会像示例 1 中那样放置,但节点应该是可拖动的,并且在拖动时节点的行为应该与示例 3 中的一样。但看起来物理仍处于打开状态并且节点没有像示例 1 那样放置。

我看不出我做错了什么。有人可以帮忙吗?

var options = {
  physics: { enabled: true, solver: 'repulsion' },
  edges: { smooth: false },
  nodes: { shape: 'box' },
  layout: { hierarchical: { enabled: false } }
};
var arrowAttr = {  to: { enabled: true, type: "triangle" }};
var edges = new vis.DataSet([
  {arrows: arrowAttr, from: "1", to: "2", hidden: false},
  {arrows: arrowAttr, from: "3", to: "4", hidden: false},
  {arrows: arrowAttr, from: "1", to: "4", hidden: false},
  {arrows: arrowAttr, from: "2", to: "3", hidden: false},
]);

// Example 1
var nodes1 = new vis.DataSet([
  {id: "1", label: "Ex 1, Node 1", x: -50, y: -50, fixed: { x: true, y: true}},
  {id: "2", label: "Ex 1, Node 2", x: -50, y: 50, fixed: { x: true, y: true}},
  {id: "3", label: "Ex 1, Node 3", x: 50, y: -50, fixed: { x: true, y: true}},
  {id: "4", label: "Ex 1, Node 4", x: 50, y: 50, fixed: { x: true, y: true}}
]);
var data1 = {
  nodes: nodes1,
  edges: edges
};  
var container1 = document.getElementById('network1');
var network = new vis.Network(container1, data1, options);
network.on("stabilizationIterationsDone", function () {
  network.setOptions( { physics: false } );
});

// Example 2
var nodes2 = new vis.DataSet([
  {id: "1", label: "Ex 2, Node 1", x: -50, y: -50, fixed: { x: false, y: false}},
  {id: "2", label: "Ex 2, Node 2", x: -50, y: 50, fixed: { x: false, y: false}},
  {id: "3", label: "Ex 2, Node 3", x: 50, y: -50, fixed: { x: false, y: false}},
  {id: "4", label: "Ex 2, Node 4", x: 50, y: 50, fixed: { x: false, y: false}}
]);
var data2 = {
  nodes: nodes2,
  edges: edges
};
options.layout.randomSeed = Math.random();
var container2 = document.getElementById('network2');
var network = new vis.Network(container2, data2, options);
network.on("stabilizationIterationsDone", function () {
  network.setOptions( { physics: false } );
});

// Example 3
var nodes3 = new vis.DataSet([
  {id: "1", label: "Ex 3, Node 1"},
  {id: "2", label: "Ex 3, Node 2"},
  {id: "3", label: "Ex 3, Node 3"},
  {id: "4", label: "Ex 3, Node 4"}
]);
var data3 = {
  nodes: nodes3,
  edges: edges
};
options.layout.randomSeed = Math.random();
var container3 = document.getElementById('network3');
var network = new vis.Network(container3, data3, options);
network.on("stabilizationIterationsDone", function () {
  network.setOptions( { physics: false } );
});
<script type="text/javascript" src="https://unpkg.com/vis-network@9.0.4/dist/vis-network.min.js"></script>
Example 1: Behaves as expected. Nodes are fixed to the coordinates specified.
<div id="network1" style="width: 250px; height: 250px; border: 1px solid #000"></div>
Example 2: Does not behave as expected. Why is the random layout ignored? And physics is not turned off as expected when dragging nodes. Physics is correctly turned off in the next example 3 with the same code.
<div id="network2" style="width: 250px; height: 250px; border: 1px solid #000"></div>
Example 3: Behaves as expected. Nodes are assigned new coordinates randomly on every reload and physics is turned off correctly as specified in the code.
<div id="network3" style="width: 250px; height: 250px; border: 1px solid #000"></div>

如果目标是按照示例 1 初始化网络,并且能够按照示例 3 移动节点 - 那么一个建议是简单地使用您的示例 1 代码示例,但在 stabilizationIterationsDone 事件中, update nodes1 中的每个节点使 fixed: false。如下所示:

var options = {
  physics: { enabled: true, solver: 'repulsion' },
  edges: { smooth: false },
  nodes: { shape: 'box' },
  layout: { hierarchical: { enabled: false } }
};
var arrowAttr = {  to: { enabled: true, type: "triangle" }};
var edges = new vis.DataSet([
  {arrows: arrowAttr, from: "1", to: "2", hidden: false},
  {arrows: arrowAttr, from: "3", to: "4", hidden: false},
  {arrows: arrowAttr, from: "1", to: "4", hidden: false},
  {arrows: arrowAttr, from: "2", to: "3", hidden: false},
]);

// Example 1
var nodes1 = new vis.DataSet([
  {id: "1", label: "Ex 1, Node 1", x: -50, y: -50, fixed: { x: true, y: true}},
  {id: "2", label: "Ex 1, Node 2", x: -50, y: 50, fixed: { x: true, y: true}},
  {id: "3", label: "Ex 1, Node 3", x: 50, y: -50, fixed: { x: true, y: true}},
  {id: "4", label: "Ex 1, Node 4", x: 50, y: 50, fixed: { x: true, y: true}}
]);
var data1 = {
  nodes: nodes1,
  edges: edges
};  
var container1 = document.getElementById('network1');
var network1 = new vis.Network(container1, data1, options);
network1.on("stabilizationIterationsDone", function () {
  network1.setOptions( { physics: false } );
  // now update data set so that each node is no longer fixed
  nodes1.forEach(function(node) {
    nodes1.update({id: node.id, fixed: false});
  });
});
<script type="text/javascript" src="https://unpkg.com/vis-network@9.0.4/dist/vis-network.min.js"></script>
<div id="network1" style="width: 250px; height: 250px; border: 1px solid #000"></div>

关于示例 2 中物理的意外性质 - 每个示例都使用 var network = ...。如果将其替换为 var network1 = ...var network2 = ... 等,则此问题就会消失:

var options = {
  physics: { enabled: true, solver: 'repulsion' },
  edges: { smooth: false },
  nodes: { shape: 'box' },
  layout: { hierarchical: { enabled: false } }
};
var arrowAttr = {  to: { enabled: true, type: "triangle" }};
var edges = new vis.DataSet([
  {arrows: arrowAttr, from: "1", to: "2", hidden: false},
  {arrows: arrowAttr, from: "3", to: "4", hidden: false},
  {arrows: arrowAttr, from: "1", to: "4", hidden: false},
  {arrows: arrowAttr, from: "2", to: "3", hidden: false},
]);

// Example 1
var nodes1 = new vis.DataSet([
  {id: "1", label: "Ex 1, Node 1", x: -50, y: -50, fixed: { x: true, y: true}},
  {id: "2", label: "Ex 1, Node 2", x: -50, y: 50, fixed: { x: true, y: true}},
  {id: "3", label: "Ex 1, Node 3", x: 50, y: -50, fixed: { x: true, y: true}},
  {id: "4", label: "Ex 1, Node 4", x: 50, y: 50, fixed: { x: true, y: true}}
]);
var data1 = {
  nodes: nodes1,
  edges: edges
};  
var container1 = document.getElementById('network1');
var network1 = new vis.Network(container1, data1, options);
network1.on("stabilizationIterationsDone", function () {
  network1.setOptions( { physics: false } );
});

// Example 2
var nodes2 = new vis.DataSet([
  {id: "1", label: "Ex 2, Node 1", x: -50, y: -50, fixed: { x: false, y: false}},
  {id: "2", label: "Ex 2, Node 2", x: -50, y: 50, fixed: { x: false, y: false}},
  {id: "3", label: "Ex 2, Node 3", x: 50, y: -50, fixed: { x: false, y: false}},
  {id: "4", label: "Ex 2, Node 4", x: 50, y: 50, fixed: { x: false, y: false}}
]);
var data2 = {
  nodes: nodes2,
  edges: edges
};
options.layout.randomSeed = Math.random();
var container2 = document.getElementById('network2');
var network2 = new vis.Network(container2, data2, options);
network2.on("stabilizationIterationsDone", function () {
  network2.setOptions( { physics: false } );
});

// Example 3
var nodes3 = new vis.DataSet([
  {id: "1", label: "Ex 3, Node 1"},
  {id: "2", label: "Ex 3, Node 2"},
  {id: "3", label: "Ex 3, Node 3"},
  {id: "4", label: "Ex 3, Node 4"}
]);
var data3 = {
  nodes: nodes3,
  edges: edges
};
options.layout.randomSeed = Math.random();
var container3 = document.getElementById('network3');
var network3 = new vis.Network(container3, data3, options);
network3.on("stabilizationIterationsDone", function () {
  network3.setOptions( { physics: false } );
});
<script type="text/javascript" src="https://unpkg.com/vis-network@9.0.4/dist/vis-network.min.js"></script>
Example 1: Behaves as expected. Nodes are fixed to the coordinates specified.
<div id="network1" style="width: 250px; height: 250px; border: 1px solid #000"></div>
Example 2: Does not behave as expected. Why is the random layout ignored? And physics is not turned off as expected when dragging nodes. Physics is correctly turned off in the next example 3 with the same code.
<div id="network2" style="width: 250px; height: 250px; border: 1px solid #000"></div>
Example 3: Behaves as expected. Nodes are assigned new coordinates randomly on every reload and physics is turned off correctly as specified in the code.
<div id="network3" style="width: 250px; height: 250px; border: 1px solid #000"></div>

细长的布局仍然存在,所以我会参考最初的建议来解决这个问题。