当我使用d3.behavior.drag()时,我不明白为什么d3.event.x == NaN而不是x光标的位置。
我使用了d3.event.sourceEvent.offsetX,但它仅适用于Chrome(例如不适用于Firefox)。
副作用可以在这里看到:
http://gloumouth1.free.fr/test/Nature
用户只能使用Chrome移动“频率游标”
有什么想法?
-G。
答案 0 :(得分:9)
从我的观点来看,d3.js是一个可怕的文档库。抱歉Mike Bostock,但就我个人来说,有时候绝对不可能找到"为什么",而无需调试源和示例。
现在,答案是:
第一次
d3可以在任何浏览器中正确创建和识别d3.event.x等自己的事件,但是你应该绘制可拖动的界面元素 INSIDE <g></g>
!您不应该在<svg></svg>
中精确放置圆圈,矩形或其他任何内容。这没有记录。
示例:
<svg>
<rect></rect> // you can not use 'd3.event.x' or 'd3.event.y' for this element.
// for this element is possible to use 'd3.event.sourceEvent.x' in Chrome
// and 'd3.event.sourceEvent.offsetX' in Firefox.
// d3.event.x === NaN, d3.event.y === NaN in any browser
<g>
<rect></rect> // 'd3.event.x' and 'd3.event.y' will work for this element
</g>
<svg>
第二次
<g></g>
包装器应存储data([{x:..., y:...}])
,即使您不需要它。如果没有<g></g>
中的数据,.origin()
方法将无法正常工作,并且元素将在窗口上的光标下无法预测地跳转。
<强>最后强>
让我们在一个例子中结合所有关于拖动的知识:
var draggable = d3.behavior.drag()
.origin(Object) // the sequence function(d){return(d);} in not necessary
.on("drag", drg);
var board = d3.select("body").append("svg:svg").attr({width: 500, height: 500});
var wrap = board.append("svg:g")
.data([{x: 100, y: 100}]); // this is the coordinates of draggable element
// they should be stored in <g></g> wrapper as the data
// IMPORTANT! There is no wrap.data().enter() sequence
// You should not call .enter() method for <g></g> data,
// but nested elements will read the data() freely
var handle = wrap.append("svg:circle")
.attr({
cx: function(d){return(d.x);}, // position of circle will be stored in the data property of <g> element
cy: function(d){return(d.x);},
r: 30,
fill: "gray",
stroke: "black"
}).call(draggable);
function drg(d){
// now d3.event returns not a mouse event,
// but Object {type: "drag", x: ..., y: ..., dx: ..., dy: ...}
d3.select(this).attr({
// reposition the circle and
// update of d.x, d.y
cx: d.x = Math.max(0, Math.min(500 - 60, d3.event.x)), // 500 - width of svg, 60 - width of circle
cy: d.y = Math.max(0, Math.min(500 - 60, d3.event.y)) // 500 - height of svg, 60 - height of circle
});
}