d3.event.x没有得到x光标的位置

glo*_*th1 1 d3.js


当我使用d3.behavior.drag()时,我不明白为什么d3.event.x == NaN而不是x光标的位置.我使用的是d3.event.sourceEvent.offsetX,但它仅适用于Chrome(例如不适用于Firefox).副作用可以在这里看到:http: //gloumouth1.free.fr/test/Nature 用户只能使用Chrome移动"频率游标".
任何的想法 ?
G.

Rub*_*mov 10

从我的角度来看,d3.js是一个可怕的文档库.对不起迈克博斯托克,但就我个人来说,有时候绝对不可能找到"为什么",没有调试源和示例.

现在,答案是:

首先

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>
Run Code Online (Sandbox Code Playgroud)

第二

<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
        });        
    }
Run Code Online (Sandbox Code Playgroud)

演示:http://jsfiddle.net/c8e2Lj9d/4/