如何在D3中单击添加或拖动? [英] How can I click to add or drag in D3?

查看:674
本文介绍了如何在D3中单击添加或拖动?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



我目前的尝试如下

  points = [] 
b $ b drag = d3.behavior.drag()
.origin((d) - > d)
.on(dragstart,dragstarted)
.on ,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) - > nx)
.attr(cy,(n) - > ny)
.attr(r,5)
.attr(class,dot)
。调用(拖动)

svg = d3.select(body)append(svg)
.attr(width,700)
.attr height,400)
.on(mousedown,mousedown)


解决方案

首先,你肯定有一个正确的想法,如何添加点在 mousedown 。我会改变的两件事是:


  1. 使用点击 c $ c> mousedown ,因此如果您点击现有点,则不会在现有点上添加新点。

  2. 在时间,而不是重新添加每个上的所有点。

这是一个工作的点击函数:

  $ b //忽略点击事件(如果它被抑制)
if(d3.event.defaultPrevented)return;

//提取点击位置\
var point = d3.mouse(this)
,p = {x:point [0],y:point [1] };

//追加一个新点
svg.append(circle)
.attr(transform,translate(+ px +,+ py + ))
.attr(r,5)
.attr(class,dot)
.style(cursor,pointer)
.call(drag);
}

然后,拖动时最简单的方法是移动使用 translate (这也是为什么I
使用 translate 创建点)。唯一真正的步骤是提取拖动的 x y 位置。这是一个 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 +));
}

我把所有这些放在这 http://stackoverflow.com/questions/15943292/how-to-drag-svg-group-using-d3js-drag-behavior\">如何使用d3js拖动行为拖动svg组


I get the impression this question is so simple nobody has bothered to make a demo of it, but I don't know enough D3 (yet) to see what I'm doing wrong. The behavior I'm looking for is if the user clicks where there's not a circle it will create one there, and if they drag an existing circle a new one will not be created, but the one they drag will move.

My current attempt is as follows

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)

解决方案

First off, you definitely have the right idea for how to add points on mousedown. The two things I'd change are:

  1. Use click instead of mousedown, so if you click existing points you don't add a new point on top of the existing one.
  2. Add one point at a time, instead of re-adding all the points on each click.

Here's a working click function:

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

Then, when dragging, it is simplest to move a circle using translate (which is also why I use translate when creating points above). The only real step is to extract the drag's x and y locations. Here's a working example of drag behavior.

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 + ")");
}

I put all this together in this jsfiddle.

Finally, here's a relevant SO question I read when constructing the drag example: how to drag svg group using d3js drag behavior.

这篇关于如何在D3中单击添加或拖动?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆