繁体   English   中英

带有SVG节点的D3图-如何将节点移动到任意位置

[英]D3 graph with svg nodes - How to move nodes to arbitrary positions

我要制作一个D3图,应如下所示:

  1. 加载html页面时,在固定位置将只有一个节点。 让我们说左上方。 让我们将其称为模板节点,并且该节点是不可移动的。

  2. 当用户在模板节点上向下移动鼠标时,将在与模板节点相同的位置创建一个新节点,并且用户应能够将新节点拖到所需位置。 新节点应准确保留在用户将其移动到的位置。

  3. 用户随时都可以移动节点。 同样,该节点应保留在用户离开的位置。

  4. 用户应该能够在任何两个节点之间绘制链接。 让我们假设,如果他在不按住ctrl键的情况下从一个节点拖动到另一节点,则绘制了一个链接;如果在按住Control键的同时拖动,则该节点移动了。

  5. 当在两个节点之间绘制链接时,则这些节点不应更改位置。

  6. 当两个节点被链接并且其中一个节点通过拖动移动时,该链接应根据需要更改大小和方向。


我正在使用强制布局。

我能够创建一个模板节点,但是它总是到达容器的中心-我认为这是因为容器的中心是重心。 但是不确定如何通过代码将其位置固定在左上方。

我可以创建链接和新节点。 但是节点移动并且链接重新调整大小。 可能是因为力布局试图使链接长度等于力布局中的链接距离。 但是我不知道如何使用函数来实现链接距离? 我什至不确定这是否真的有帮助。

那我应该用什么方法呢? 任何想法?

对于强制布局,可以将节点的“固定”属性设置为true,以防止其受到仿真的影响。 之后,您应该可以手动设置其位置。 您可以选择在函数调用中执行此操作:

function pinNode(node) {
  node.fixed = true;
}

function unpinNode(node) {
  node.fixed = false;
}

我相信可以通过这样的调用将节点移到左上角: pinNode(node, 0, 0) 只要节点的固定属性设置为true,它就不会受到sim的影响。 您可能会从文档中发现此片段很有帮助; 它描述了受force.drag影响固定属性的方式:

将行为绑定到节点以允许使用鼠标或触摸进行交互式拖动。 与节点上的调用运算符结合使用; 例如,在初始化时说出node.call(force.drag)。 拖动事件会在鼠标悬停时设置节点的固定属性,这样,一旦鼠标悬停在节点上,鼠标就会停止移动。 固定在鼠标悬停而不是鼠标悬停上,可以更轻松地捕获移动的节点。 接收到mousedown事件时,以及随后的每次mousemove直到mouseup,节点中心都将设置为当前鼠标位置。 此外,每次移动鼠标都会触发力布局的恢复,从而重新模拟。 如果要在拖动后使被拖动的节点保持固定,请像在粘滞力布局示例中一样,在dragstart上将fixed属性设置为true。

force.drag

另请参见此处: 强制布局节点

如果要使用函数来链接距离,请在创建力布局时将其包括在内:

var force = d3.layout.force()
    .size(width, height)
    .linkStrength(0.5) // how much can link distance be overridedn by the simulation
    .linkDistance(function() {return /* some evaluation */;});

// ...

// You might need to defer the calculation of linkDistance until later,
// such as in update(), since nodes might not have the properties
// that you need to check until that point:

function update() {
  force
    .nodes(nodes)
    .links(links)
    .linkDistance(function(link) {
      // The function gets called for each link in the simulation.
      // Each link will be connected to two nodes, source and target, 
      // which may be useful in determining link distance.
      if (link.source.someProperty || link.target.somePropery) {
        return /* something */;
      } else {
        return /* something else */;
      }
    });
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM