【问题标题】:vis.js - Place node manuallyvis.js - 手动放置节点
【发布时间】:2018-03-05 07:20:35
【问题描述】:

如何在 vis.js 中设置节点的位置?

我想手动定位至少一个节点。

我知道一个节点有 xy 选项。我设置了两者,还尝试了 layout 选项的变体(randomSeedimprovedLayouthierarchical),节点为从来没有放在我设置的地方。

这是我定义的简单网络:

  nodes = new vis.DataSet([
    {id: 1,  shape: 'circularImage', image: DIR + '1_circle', label:"1", x: 200, y: 100},
    {id: 2,  shape: 'circularImage', image: DIR + '2_circle', label:"2"},
    {id: 3,  shape: 'circularImage', image: DIR + '3_circle', label:"3"},
  ]);

  edges = [
    {id: "01-03", from: 1, to: 3, length: 300, label: '1 - 3'},
    {id: "02-03", from: 2, to: 3},
  ];

  var container = document.getElementById('graphcontainer');
  var data = {
    nodes: nodes,
    edges: edges
  };
  var options = {
    nodes: {
      borderWidth: 4,
      size: 30,
      color: {
        border: '#222222',
        background: '#666666'
      },
      font:{
        color:'#000000'
      }
    },
    edges: {
      color: 'lightgray'
    },
    //layout: {randomSeed:0}
    //layout: {hierarchical: true}
    layout: {
      randomSeed: undefined,
      improvedLayout:true,
      hierarchical: {
        enabled:false,
        levelSeparation: 150,
        direction: 'UD',   // UD, DU, LR, RL
        sortMethod: 'hubsize' // hubsize, directed
      }
    }
  };
  network = new vis.Network(container, data, options);

节点被放置,但不是在我设置的点(200,100),而是在另一个位置。

我还没有找到在 vis.js 页面上显式设置节点位置的示例。有人可以提供一个吗?谢谢!

【问题讨论】:

  • 请添加一些说明您的具体问题在哪里以及您的预期行为是什么!谢谢。
  • 我希望节点 1 位于 200,100(见示例),但它没有放置在那里。
  • 如果您对如何序列化/保存节点位置然后加载它们感兴趣,请查看this answer

标签: javascript vis.js vis.js-network


【解决方案1】:

您确实可以通过设置节点的xy 属性来设置节点的固定位置,是的,此功能有效且没有损坏。

节点的xy 位置并不表示屏幕上的像素位置,而是网络坐标系中的固定位置。当您在网络中移动和缩放时,固定项目也会移动和缩放,但它们之间的相对位置将始终保持相同。就像您的家乡在地球上有一个固定的位置(经纬度),但您仍然可以在 Google 地图中缩放和移动您的城镇。

编辑:要实现您想要的,您可以修复缩放和移动,并调整视口以使其与 HTML 画布的像素相匹配,这是一个演示:

// create an array with nodes
var nodes = new vis.DataSet([
    {id: 1, label: 'x=200, y=200', x: 200, y: 200},
    {id: 2, label: 'node 2', x: 0, y: 0},
    {id: 3, label: 'node 3', x: 0, y: 400},
    {id: 4, label: 'node 4', x: 400, y: 400},
    {id: 5, label: 'node 5', x: 400, y: 0}
]);

// create an array with edges
var edges = new vis.DataSet([
    {from: 1, to: 2, label: 'to x=0, y=0'},
    {from: 1, to: 3, label: 'to x=0, y=400'},
    {from: 1, to: 4, label: 'to x=400, y=400'},
    {from: 1, to: 5, label: 'to x=400, y=0'}
]);

// create a network
var container = document.getElementById('mynetwork');
var data = {
    nodes: nodes,
    edges: edges
};
var width = 400;
var height = 400;
var options = {
    width: width + 'px',
    height: height + 'px',
    nodes: {
        shape: 'dot'
    },
    edges: {
        smooth: false
    },
    physics: false,
    interaction: {
        dragNodes: false,// do not allow dragging nodes
        zoomView: false, // do not allow zooming
        dragView: false  // do not allow dragging
    }
};
var network = new vis.Network(container, data, options);
  
// Set the coordinate system of Network such that it exactly
// matches the actual pixels of the HTML canvas on screen
// this must correspond with the width and height set for
// the networks container element.
network.moveTo({
    position: {x: 0, y: 0},
    offset: {x: -width/2, y: -height/2},
    scale: 1,
})
#mynetwork {
    border: 1px solid black;
    background: white;
    display: inline-block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vis/4.9.0/vis.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/vis/4.9.0/vis.min.css" rel="stylesheet" type="text/css" />

<p>The following network has a fixed scale and position, such that the networks viewport exactly matches the pixels of the HTML canvas.</p>
<div id="mynetwork"></div>

【讨论】:

  • 所以你必须明确设置所有节点的位置,如果你想将一个节点放置在相对于其他节点的不同位置,例如在中间?我想显示一个以节点为中心的图,其中一个节点位于中间,其他节点位于它周围;确切的位置并不重要,所以我希望自动设置其他位置。
  • 并非所有节点都必须有固定的位置。 (你应该再次设置physics:true 有非固定节点)
【解决方案2】:

文档说nodes positioned by the layout algorithm

使用分层布局时,设置 x 或 y 位置 布局引擎取决于视图的类型

您可以将它们放入明确的点,但我不建议这样做 - 这不是使用图表的正确方法 - 更好地审查您的任务 - 也许您不需要图表(或者您不需要放置点准确定位)。

无论如何 - 如果你真的想放在某个位置,那么你需要使用随机布局并将 fixed 选项设置为 truephysic 选项设置为 false

var DIR = 'http://cupofting.com/wp-content/uploads/2013/10/';
nodes = new vis.DataSet([
    {id: 1,  shape: 'circularImage', image: DIR + '1-circle.jpg', label:"1", x:0, y:0},
    {id: 2,  shape: 'circularImage', image: DIR + '2-circle.jpg', label:"2", x:100, y:0},
    {id: 3,  shape: 'circularImage', image: DIR + '3-circle.jpg', label:"3", x:0, y:100},
  ]);

  edges = [
    {id: "01-03", from: 1, to: 3, length: 300, label: '1 - 3'},
    {id: "02-03", from: 2, to: 3},
  ];

  var container = document.getElementById('graphcontainer');
  var data = {
    nodes: nodes,
    edges: edges
  };
  var options = {
       physics:{
           stabilization: true,
       },
    nodes: {
      borderWidth: 4,
      size: 10,
      //fixed:true,
      physics:false,
      color: {
        border: '#222222',
        background: '#666666'
      },
      font:{
        color:'#000000'
      }
    },
    edges: {
      color: 'lightgray'
    },
    layout: {randomSeed:0}
  };
  network = new vis.Network(container, data, options);
<script src="https://cdnjs.cloudflare.com/ajax/libs/vis/4.9.0/vis.min.js"></script>
<div id="graphcontainer" style="border: 1px solid red; width:300px; height:300px; "> </div>

【讨论】:

    【解决方案3】:

    :) 我今天早上第一次这样做。 X = 0 和 Y = 0 表示图形从居中开始,而不是在画布的左上角。节点有一个固定属性,您可以将节点上的 x 和 y 设置为 true,并设置其 x 和 y 值,并让其他节点使用与其相关的物理。

    查看页面上的完整选项标签 http://visjs.org/docs/network/nodes.html#

    你会看到这件作品:

    fixed: {
      x:false,
      y:false
    },
    

    【讨论】:

      猜你喜欢
      • 2023-03-02
      • 2019-09-28
      • 2018-12-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-22
      • 1970-01-01
      • 2022-07-23
      相关资源
      最近更新 更多