拖动行为在D3中返回NaN

时间:2012-12-01 08:14:51

标签: javascript svg d3.js

我有这段代码:

  var stage = d3.select("body").append("svg");
  var points = [0, 50, 100, 150];
  var letters = "drag".split(",");
  var log = d3.select("#log");

  //drag behaviour, will bind later
    var drag = d3.behavior.drag()
      .origin(Object)
      .on("drag", dragmove);


  //append texts
    var texts = stage
        .selectAll("text")
        .data(letters)
        .enter()
            .append("text")
            .attr("font-family", "Arial")
            .attr("class", "word")
            .attr("x", function(d,i){return points[i]})
            .attr("y", 100)
            .text(function(d){return d})
            .call(drag);

    function dragmove() {
        log.text(
            "x: " + d3.event.x + ", " +
            "y: " + d3.event.y + ", " +
            "dx: " + d3.event.dx + ", " +
            "dy: " + d3.event.dy
            );
        d3.select(this).attr("x", d3.event.x);
    }​

但是,d3.event.xd3.event.y正在返回NaN。有趣的是,d3.event.dxd3.event.dy正在返回正确的值。我的代码出了什么问题?

你可以在这里看到一个jsfiddle:http://jsfiddle.net/UMwmr/

1 个答案:

答案 0 :(得分:7)

这是因为d3.event转发数据,如果您签入代码:

.attr("x", function(d,i){console.log(d);return points[i]})

你会发现d是文本,不能有x,y属性。

解决方案是将每个字母作为对象(你也将它们分成“,”但我猜它应该是“”)所以这里代码:

var stage = d3.select("body").append("svg");
var points = [0, 50, 100, 150];
var letters = "drag".split("").map(function(d, i) {
    return {
        text: d,
        x: points[i],
        y: 100
    }
});
var log = d3.select("#log");

//drag behaviour, will bind later
var drag = d3.behavior
    .drag()
    .origin(Object)
    .on("drag", dragmove);


//append texts
var texts = stage
    .selectAll("text")
    .data(letters)
    .enter()
       .append("text")
       .attr("font-family", "Arial")
       .attr("class", "word")
       .attr("x", function(d, i) {
            return d.x;
       })
       .attr("y", 100)
       .text(function(d) {
            return d.text;
           })
       .call(drag);

function dragmove(d) {
    log.text(
        "x: " + d3.event.x + ", " + 
        "y: " + d3.event.y + ", " + 
        "dx: " + d3.event.dx + ", " + 
        "dy: " + d3.event.dy);
    //set new position to the object
    d.x=d3.event.x;
    d3.select(this).attr("x", d3.event.x);
}​

fiddle