如何在D3中单击添加或拖动? [英] How can I click to add or drag in 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
。我会改变的两件事是:
- 使用
点击
c $ c> mousedown ,因此如果您点击现有点,则不会在现有点上添加新点。 - 在时间,而不是重新添加每个
上的所有点。
这是一个工作的点击
函数:
$ 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 +));
}
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:
- Use
click
instead ofmousedown
, so if you click existing points you don't add a new point on top of the existing one. - 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屋!