我得到的印象是这个问题很简单,没有人费心去做它的演示,但是我还不知道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.我要改变的两件事是:
click而不是mousedown,因此如果单击现有点,则不会在现有点上添加新点.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在创建上面的点时使用的原因).唯一真正的步骤是提取阻力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 + ")");
}
Run Code Online (Sandbox Code Playgroud)
我把所有这些放在这个jsfiddle中.
最后,这是我在构建拖动示例时读到的相关SO问题:如何使用d3.js拖动行为拖动svg组?.