d3:如何独立于背景拖动线元素

d3: how to drag line elements independently of background

我开发了一个显示 d3 对角树的小程序。图表可通过拖动背景进行导航。

它基于在以下 link 找到的代码: https://bl.ocks.org/adamfeuer/042bfa0dde0059e2b288

我正在尝试在页面上添加垂直线以进一步注释树/图(基于以下 link:https://bl.ocks.org/dimitardanailov/99950eee511375b97de749b597147d19)。

见下文:

看这里:https://jsfiddle.net/chrisclarkson100/opfq6ve8/28/

我将线条附加到图表中,如下所示:

    var data_line = [
          {
            'x1': 300,
            'y1': 700,
            'x2': 300,
            'y2': 700
          },
          ////....
      ];
      
      // Generating the svg lines attributes
      var lineAttributes = {
          ....
          'x1': function(d) {
              return d.x1;
          },
          'y1': function(d) {
              return screen.availHeight;
          },
          'x2': function(d) {
              return d.x2;
          },
          'y2': function(d) {
              return 0;
          }
      };
      
      var drag_line = d3.behavior.drag()
        .origin(function(d) { return d; })
        .on('drag', dragged_line);
      
      // Pointer to the d3 lines
    var svg = d3.select('body').select('svg');
      var lines = svg
        .selectAll('line')
          .data(data_line)
        .enter().append('g') 
          .attr('class', 'link');

      links_lines=lines.append('line')
              .attr(lineAttributes)
              .call(drag_line);

      lines.append('text')
          .attr('class','link_text')
          .attr("x", d => d.x1)
          .attr("y", d => 350)
          .style('fill', 'darkOrange')
          .style("font-size", "30px")

      function dragged_line() {
          var x = d3.event.dx;
          var y = d3.event.dy;
          var line = d3.select(this);
          // Update the line properties
          var attributes = {
            x1: parseInt(line.attr('x1')) + x,
            y1: parseInt(line.attr('y1')) + y,
            x2: parseInt(line.attr('x2')) + x,
            y2: parseInt(line.attr('y2')) + y,
          };
          line.attr(attributes);
      }

线条显示如我所愿,并且可以拖动。但是,当我拖动它们时,背景/树网络会随之移动...我希望不同的可拖动元素彼此独立。

有人能看出我是如何未能使每个元素的拖动交互性相互独立的吗?

这是一个 JSFiddle,它似乎可以做你想做的事——你可以移动垂直线而不用移动树;并在不移动垂直线的情况下移动树:

https://jsfiddle.net/adamfeuer/gd4ouvez/125/

(JSFiddle 使用的树节点数据集要小得多;您链接到的数据集太大,无法轻松迭代和调试。)

您发布的代码的问题是,树的缩放(平移)功能同时处于活动状态,线的缩放()处于活动状态,因此树和活动线同时拖动时间.

我添加了一个简单的机制来将两者分开——一个名为 lineDragActive 的布尔值。然后代码检查树 zoom() 中的那个,当线拖动开始时将其设置为真,当线拖动结束时将其设置为假:

      // Define the zoom function for the zoomable tree
  
      // flag indicates if line dragging is active...
      // if so, we don't want to drag the tree
      var lineDragActive = false;
      function zoom() {
        if (lineDragActive == false) {
        // not line dragging, so we can zaoom (drag) the tree
        svgGroup.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");
        }
      }

[...]

  function drag_linestarted() {
    // tell others not to zoom while we are zooming (dragging)
    lineDragActive = true;

    d3.select(this).classed(activeClassName, true);
  }

  function drag_lineended() {
    // tell others that zooming (dragging) is allowed
    lineDragActive = false;

    d3.select(this).classed(activeClassName, false);

    label = baseSvg.selectAll('.link_text').attr("transform", "translate(" + String(Number(this.x1.baseVal.value) - 400) + "," + 0 + ")");

  }