如何点击添加或拖动D3?

ter*_*ret 3 d3.js

我得到的印象是这个问题很简单,没有人费心去做它的演示,但是我还不知道D3(还)看到我做错了什么.我正在寻找的行为是,如果用户点击没有圆圈的地方,它将在那里创建一个圆圈,如果他们拖动现有圆圈,则不会创建新圆圈,但他们拖动的圆圈将会移动.

我目前的尝试如下

points = []

drag = d3.behavior.drag()
  .origin((d) -> d)
  .on("dragstart", dragstarted)
  .on("dragend", dragended)

dragstarted = (d) ->
  d3.event.sourceEvent.stopPropagation
  d3.select(this).classed("dragging", true)

dragended = (d) ->
  d3.select(this).classed("dragging", false)

mousedown = ->
  return if d3.event.defaultPrevented
  point = d3.mouse(this)
  points[points.length] = {x: point[0], y: point[1]}
  svg.selectAll("circle").data(points).enter().append("circle")
                                                .attr("cx", (n) -> n.x)
                                                .attr("cy", (n) -> n.y)
                                                .attr("r", "5")
                                                .attr("class", "dot")
                                                .call(drag)

svg = d3.select("body").append("svg")
                         .attr("width", 700)
                         .attr("height", 400)
                         .on("mousedown", mousedown)
Run Code Online (Sandbox Code Playgroud)

mdm*_*dml 12

首先,你肯定对如何添加点有正确的想法mousedown.我要改变的两件事是:

  1. 使用click而不是mousedown,因此如果单击现有点,则不会在现有点上添加新点.
  2. 一次添加一个点,而不是重新添加每个点上的所有点click.

这是一个工作click功能:

function click(){
  // Ignore the click event if it was suppressed
  if (d3.event.defaultPrevented) return;

  // Extract the click location\    
  var point = d3.mouse(this)
  , p = {x: point[0], y: point[1] };

  // Append a new point
  svg.append("circle")
      .attr("transform", "translate(" + p.x + "," + p.y + ")")
      .attr("r", "5")
      .attr("class", "dot")
      .style("cursor", "pointer")
      .call(drag);
}
Run Code Online (Sandbox Code Playgroud)

然后,在拖动时,最简单的移动circle使用translate(这也是我translate在创建上面的点时使用的原因).唯一真正的步骤是提取阻力xy位置.这是drag行为的一个有效例子.

var drag = d3.behavior.drag()
    .on("drag", dragmove);

function dragmove(d) {
  var x = d3.event.x;
  var y = d3.event.y;
  d3.select(this).attr("transform", "translate(" + x + "," + y + ")");
}
Run Code Online (Sandbox Code Playgroud)

我把所有这些放在这个jsfiddle中.

最后,这是我在构建拖动示例时读到的相关SO问题:如何使用d3.js拖动行为拖动svg组?.