Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/svg/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 带svg节点的D3图形-如何将节点移动到任意位置_Javascript_Svg_D3.js_Force Layout - Fatal编程技术网

Javascript 带svg节点的D3图形-如何将节点移动到任意位置

Javascript 带svg节点的D3图形-如何将节点移动到任意位置,javascript,svg,d3.js,force-layout,Javascript,Svg,D3.js,Force Layout,我想做一个D3图,应该是这样的: 加载html页面时,固定位置将有一个节点。让我们说左上角。我们称之为模板节点,这个节点是不可移动的 当用户在模板节点上单击鼠标时,将在与模板节点相同的位置创建一个新节点,并且用户应该能够将新节点拖动到他想要的位置。新节点应保持在用户移动到的位置 在任何时候,用户都应该能够移动节点。同样,节点应该保留在用户离开它的地方 用户应该能够在任意两个节点之间绘制链接。让我们假设,如果他在不按住ctrl键的情况下从一个节点拖动到另一个节点,则会绘制链接,如果他在按住cont

我想做一个D3图,应该是这样的:

  • 加载html页面时,固定位置将有一个节点。让我们说左上角。我们称之为模板节点,这个节点是不可移动的

  • 当用户在模板节点上单击鼠标时,将在与模板节点相同的位置创建一个新节点,并且用户应该能够将新节点拖动到他想要的位置。新节点应保持在用户移动到的位置

  • 在任何时候,用户都应该能够移动节点。同样,节点应该保留在用户离开它的地方

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

  • 在两个节点之间绘制链接时,节点不应更改位置

  • 链接两个节点并通过拖动移动其中一个节点时,链接的大小和方向应根据需要进行更改


  • 我使用的是强制布局

    我可以创建一个模板节点,但它总是指向容器的中心-我认为这是因为容器的中心是重心。但不知道如何通过代码将其位置固定到左上方

    我可以创建链接和新节点。但是节点会移动,链接也会调整大小。可能是因为“力布局”试图使链接长度等于“力布局”中的链接距离。但我不知道如何使用链接距离函数?我甚至不确定这是否真的有用


    那么我应该用什么方法呢?有什么想法吗?

    对于force layout,您可以将节点的“fixed”属性设置为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上将“固定”属性设置为true,如下所示 在粘滞力布局示例中

    另请参见此处:

    如果要使用链接距离函数,请在创建力布局时包含该函数:

    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 */;
          }
        });
    }
    

    对于“强制布局”,可以将节点的“固定”属性设置为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上将“固定”属性设置为true,如下所示 在粘滞力布局示例中

    另请参见此处:

    如果要使用链接距离函数,请在创建力布局时包含该函数:

    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 */;
          }
        });
    }
    

    听起来你不想使用force布局。谢谢你的回复。这是我的第二个问题。我发布这篇文章是因为我觉得这与我之前的问题有很大不同。我应该使用哪种布局?听起来你不想使用force布局。谢谢你的回复。这是我的第二个问题。我发布这篇文章是因为我觉得这与我之前的问题有很大不同。我应该使用哪种布局?编辑了答案以包含linkDistance的延迟计算,改为在update()中调用它。谢谢,但我仍然需要解决这个问题。请查看当前当用户按住ctrl键并拖动节点时,节点会移动。但它也会自行行动。拥有为了实现以下目标,需要对代码进行哪些更改?节点不应自行移动。仅当用户ctrl拖动它时,它才应移动。创建节点时,它应保持在创建位置。当用户移动一个节点时,该节点应保持在用户离开的位置。当用户移动一个节点时,其他节点不应改变其位置。