d3.js - D3 在 v6 中拖动并单击分组对象

标签 d3.js click drag

正在处理Mike's example我试图找出如何将概念转移到分组元素。我可以单独创建启动拖动和单击,但在一起时我似乎无法单击来工作。下面是一个片段 - 这只是我使用过的众多方法之一。

  const width = 400;
  const height = 300;
  const radius = 5;
  
  const svg = d3.select("#chart").append('svg')
    .attr('width', '400')
    .attr('height', '400')
    .style('border', 'solid 1px');

  const circles = d3.range(20).map(i => ({
    x: Math.random() * (width - radius * 2) + radius,
    y: Math.random() * (height - radius * 2) + radius,
    index: i
  }));

const group =  svg.selectAll("g").data(circles).enter()
      .append("g")
      .attr("cx", d => d.x)
      .attr("cy", d => d.y)            
      .call(d3.drag()
      .on("start", dragstarted)
      .on("drag", dragged)
      .on("end", dragended))
  
  group.append("circle")
      .attr("cx", d => d.x)
      .attr("cy", d => d.y)            
      .attr("r", radius)
      .attr("fill", d => d3.schemeCategory10[d.index % 10])
      .on("click", clicked);
      
    group.append("text")
      .attr("x", d => d.x)
      .attr("y", d => d.y)            
      .style("fill", 'white')
      .text('a')
    

  function clicked(event, d) {
    if (event.defaultPrevented) return; // dragged

    d3.select(this).transition()
        .attr("fill", "black")
        .attr("r", radius * 2)
      .transition()
        .attr("r", radius)
        .attr("fill", d3.schemeCategory10[d.index % 10]);
  }


  function dragstarted() {
    d3.select(this).attr("stroke", "black");
  }

  function dragged(event, d) {
    d3.select(this).raise().attr("cx", d.x = event.x).attr("cy", d.y = event.y);
  }

  function dragended() {
    d3.select(this).attr("stroke", null);
  }
<script src="https://d3js.org/d3.v6.js"></script>
<div id="chart"></div>

最佳答案

关键问题是您使用 cxcy 属性定位每个 g ,并在拖动时更新这些属性。 g 元素无法通过 cxcy 定位,因此最初设置这些元素并在拖动时更新它们将不会导致任何变化。

您需要使用翻译来定位 g 元素:

  .attr("transform", d=> "translate("+[d.x,d.y]+")" )   

此外,您现在不需要定位圆圈和文本 - 或者每个 x 和 y 坐标将应用两次 - 一次应用于 g,一次应用于子元素。

现在您只需要在每次拖动时更新翻译,例如:

function drag(event,d) {
    d.x = event.x;
    d.y = event.y;
    d3.select(this).raise().attr("transform", d=> "translate("+[d.x,d.y]+")" )
}

这应该给你类似的东西:

const width = 400;
  const height = 300;
  const radius = 5;
  
  const svg = d3.select("#chart").append('svg')
    .attr('width', '400')
    .attr('height', '400')
    .style('border', 'solid 1px');

  const circles = d3.range(20).map(i => ({
    x: Math.random() * (width - radius * 2) + radius,
    y: Math.random() * (height - radius * 2) + radius,
    index: i
  }));

const group =  svg.selectAll("g").data(circles).enter()
      .append("g")
      .attr("transform", d=> "translate("+[d.x,d.y]+")" )            
      .call(d3.drag()
      .on("start", dragstarted)
      .on("drag", dragged)
      .on("end", dragended))
  
  group.append("circle")    
      .attr("r", radius)
      .attr("fill", d => d3.schemeCategory10[d.index % 10])
      .on("click", clicked);
      
    group.append("text")    
      .style("fill", 'white')
      .text('a')
    

  function clicked(event, d) {
    if (event.defaultPrevented) return; // dragged

    d3.select(this).transition()
        .attr("fill", "black")
        .attr("r", radius * 2)
      .transition()
        .attr("r", radius)
        .attr("fill", d3.schemeCategory10[d.index % 10]);
  }


  function dragstarted() {
    d3.select(this).attr("stroke", "black");
  }

  function dragged(event, d) {
    d.x = event.x;
    d.y = event.y;
    d3.select(this).raise().attr("transform", d=> "translate("+[d.x,d.y]+")" )
  }

  function dragended() {
    d3.select(this).attr("stroke", null);
  }
<script src="https://d3js.org/d3.v6.js"></script>
<div id="chart"></div>

关于d3.js - D3 在 v6 中拖动并单击分组对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64397454/

相关文章:

javascript - TypeError : n is undefined in D3. js,试图复制分层边缘捆绑

javascript - 如何在鼠标悬停时获取直方图中数据元素的索引?

javascript - D3 : How to validate data during data binding?

java - 是否有类似于 swing for eclipse 的 JavaFX 拖放插件?

javascript - 如何在 iPhone 上拖动 'div' 元素

javascript - 鼠标悬停事件未在 xhtml 元素上触发 - d3.js

jquery - 单击链接 href 后,pie.htc 样式的 Div 未正确重绘

jQuery 监听器不会 "listen"动态创建 DOM 元素上的事件

delphi - 如何点击</span>标签? (网络浏览器 - 德尔福)

android - 如何在 fragment 内的对象中实现 onDragListener?