【问题标题】:Performing double mouseup events with other element in d3使用 d3 中的其他元素执行双 mouseup 事件
【发布时间】:2018-08-15 15:41:19
【问题描述】:

我正在尝试在我的节点上针对鼠标按下时出现的周围弧线触发 mouseup 事件。

我的预期功能是能够按住节点并将其拖入弧中,触发弧以及节点的 mouseup 事件。我当前的代码有问题,在下面的 JSFiddle 中引用,希望您能提供帮助!

对于我的弧线,我有以下代码,我希望在放开特定弧线上方的鼠标时在 mouseup 时执行:

slices.append('path')
    ...
    .on('mouseup', function(arc) {
        console.log(arc.data.title)
    }
);

我还希望在将节点拖动到特定弧的顶部并释放鼠标按钮后运行节点的 mouseup:

svg.append("g")
        .attr("class", "node")
        .selectAll(".bubble")
          .data(data, function(d){ return d.id; })
        .enter().append("circle")
        ...
        .on('mousedown', nodeClickedArcs)
        .on('mouseup', removeArcs)

谢谢!

http://jsfiddle.net/uas6zr7y/3/

【问题讨论】:

    标签: javascript d3.js data-visualization pie-chart


    【解决方案1】:

    这里的关键挑战是鼠标事件基本上被圆圈吸收了。您也许可以以这样一种方式对元素进行排序,即弧的父 g 拥有一个带有圆圈的子 g,以允许事件传播到相关的父级,但是您的圆圈位于您的弧之下。

    我将在下面演示的一个选项是在拖动期间从节点中剥离指针交互。这不会中断拖动(在 Chrome、Firefox、IE 上测试),但将允许鼠标与其他元素交互,例如鼠标悬停/鼠标移出事件。然后我们可以监听鼠标进入(和退出)目标形状,如果拖动结束(鼠标向上)在目标形状上我们可以触发特定动作。

    这要求鼠标向上的所有事件逻辑都位于拖动结束函数中,但需要侦听器用于目标形状的鼠标进入/退出。

    基于以上,在下面的sn-p I:

    1. 在拖动时从被拖动节点(圆圈)中去除指针事件。
    2. 监听鼠标是否在目标形状(矩形)上移动并更新该元素的基准以反映其“活动”状态。相反,如果鼠标从目标形状上移开,我会将节点设置为不活动。
    3. 如果拖动事件在目标形状处于活动状态时结束,那么我知道我拖动的节点位于目标形状上方(并且鼠标已向上)并且可以相应地采取行动。如果拖动事件以没有活动节点结束,那么我将指针事件恢复到节点。

    在下面的 sn-p 中,如果节点(圆形)在目标形状(矩形)上,我会删除它们,并在此过程中更新矩形颜色:

    var svg = d3.select("body")
      .append("svg")
      .attr("width", 500)
      .attr("height", 300);
    
    var drag = d3.drag()
      .on("drag",dragged)
      .on("end", dragEnd);
    
    var squares = svg.selectAll("rect")
      .data([{x:30},{x:130},{x:230},{x:330},{x:430}])
      .enter()
      .append("rect")
      .attr("x", function(d) { return d.x; })
      .attr("y", 120)
      .attr("width", 40)
      .attr("height",40)
      .attr("fill","white")
      .on("mouseenter", function(d) { d.active = true; })
      .on("mouseout", function(d) { d.active = false; });
      
    var circles = svg.selectAll("circle")
      .data(d3.range(20))
      .enter()
      .append("circle")
      .attr("cx", function(d) { return d/21*500 + 25; })
      .attr("cy", function(d) { return d%2 * 40 + 50; })
      .attr("r", 10)
      .attr("fill",  function(d) { return d3.schemeCategory20[d]; })
      .call(drag);
      
    
    function dragged(d) {
      var x = d3.mouse(this)[0];
      var y = d3.mouse(this)[1];
      
      d3.select(this)
        .attr("cx",x)
        .attr("cy",y)
        .style("pointer-events","none");
    }
    
    function dragEnd(d) {
      var rect = squares.filter(function(d) {
        return d.active;
      })
      if(!rect.empty()) {
        var circle = d3.select(this);
        rect.attr("fill",interpolateColor(rect,circle));
        circle.remove();
      }
      else {
        d3.select(this).style("pointer-events","all");
      }
    }
    
    function interpolateColor(r,c) {
     return d3.interpolateLab(r.attr("fill"),c.attr("fill"))(0.5)
    }
    svg {
      stroke: black;
      stroke-width: 2px;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.10.0/d3.min.js"></script>

    这会检查鼠标位置,而不是如果圆圈与矩形重叠,碰撞检测将需要不同的方法

    【讨论】:

      猜你喜欢
      • 2019-04-23
      • 2020-05-28
      • 1970-01-01
      • 2013-11-21
      • 1970-01-01
      • 2014-07-10
      • 2016-05-24
      • 2021-12-30
      • 1970-01-01
      相关资源
      最近更新 更多