如何将拖动应用于rect / image?

时间:2014-12-15 16:52:22

标签: javascript d3.js

这是一个愚蠢的问题,可能有一个简单的答案,但我无法在画布上拖动我的图像。这是我的图像代码:

    function simpleButton(origImage, overlay, iconWidth, iconHeight, xpos, ypos, whenClicked, title)
{
    svg.append("svg:image")
    .datum({
      x: xpos, //-starting 'x' position
      y: ypos  //-starting 'y' position
    })
    .attr("x", function (d) { return d.x; }) 
    .attr("y", function (d) { return d.y; })

        .attr("xlink:href", origImage) //-original image
        // .attr("x",xpos) //-starting 'x' position
        // .attr("y",ypos) //-starting 'y' position
        .attr("width",iconWidth) //-icon width
        .attr("height",iconHeight) //-icon height
        .on("click",whenClicked) //-call when button is clicked
        .on("mouseover",function(){d3.select(this).attr("xlink:href", overlay);}) //-change image when mouseover
        .on("mouseout",function(){d3.select(this).attr("xlink:href", origImage);}) //-reset image
        .call(button_drag)
        .append("svg:title")
            .text(title); //-give the button a title        
}

我的拖拽功能:

var button_drag = d3.behavior.drag()

    .on("dragstart", function(){
        clog("dragstart");
    })
    .on("drag", function(d,i) {
             d.x += d3.event.dx
             d.y += d3.event.dy
            d3.select(this).attr("transform", function(d,i){
                return "translate(" + [ d.x,d.y ] + ")"
            })
        })
    .on("dragend", function(){
        clog("dragend");
    });

尝试拖动其中一张图片时出现错误:

 Uncaught TypeError: Cannot read property 'x' of undefined

我试图研究它,显然我没有将数据应用到我的矩形。我该如何解决这个问题?

1 个答案:

答案 0 :(得分:2)

拖动假设d - 绑定到被拖动元素的基准 - 传递到处理函数.on("drag", function(d,i) { ... }

在您的情况下d未定义,这就是为什么设置d.x会抱怨它无法读取未定义的属性'x'd未定义的原因是因为没有数据绑定到图像。数据绑定到元素的方式是:

  1. 使用d3选择的.data()方法绑定,然后将enter()附加到元素 - 而不是像svg.append那样追加它们。或者,
  2. 如果您不想做#1,那么您需要使用.datum()方法将数据显式绑定到您创建的元素。
  3. 做其中一个提出了d应该是什么的问题。嗯......它应该是一个具有属性xy的对象,因为拖动处理程序想要修改这些道具。

    xy可能应初始化为xposypos,即初始位置。一旦xy成为基准的一部分,您应该切换到基于它们设置图像的x和y位置,而不是硬编码到xpos, ypos

    总而言之,如果您选择了#2选项,那么它看起来像这样:

    svg.append("svg:image") 
        .datum({
          x: xpos, //-starting 'x' position
          y: ypos  //-starting 'y' position
        })
        .attr("xlink:href", origImage) //-original image
        .attr("x", function (d) { return d.x; }) 
        .attr("y", function (d) { return d.y; })
        .attr("width",iconWidth) //-icon width
        .attr("height",iconHeight) //-icon height       
        .call(button_drag)