Javascript 如何将拖动应用于矩形/图像?

Javascript 如何将拖动应用于矩形/图像?,javascript,d3.js,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 //-sta

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

    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
我试过研究它,显然我没有数据应用到我的矩形上。如何解决此问题?

拖动应该将绑定到被拖动元素的数据传递到处理程序函数
。在(“拖动”时,函数(d,I){…}

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

  • 使用d3 selection的
    .data()
    方法绑定元素,然后将
    enter()
    'ing附加到元素,而不仅仅是
    svg。像您这样附加它们。或者
  • 如果不想执行#1,则需要使用
    .datum()
    方法将基准显式绑定到所创建的元素
  • 执行这两个操作中的一个会引发一个问题,即
    d
    应该是什么。嗯……它应该是一个具有属性
    x
    y
    的对象,因为拖动处理程序想要修改这些道具

    x
    y
    可能应该初始化为
    xpos
    ypos
    ,即初始位置。一旦
    x
    y
    是基准的一部分,您应该切换到基于它们设置图像的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)
    

    很好。为答案干杯。有点成功了。我更新了上面的代码。我拥有的是一个创建按钮的功能,以便可以重用。但是按钮的移动是关闭的。即当我拖动节点时,它向右平移大约1500像素,这是大多数节点上的,但其中一个仅向下平移大约400像素。有没有想法?@meetamit积累
    d.x
    的方式可能不正确。与其使用
    d.x+=d3.event.dx
    ,不如使用
    d.x=mouse[0]
    和(
    d.y=mouse[1]
    )。使用
    var mouse=d3.mouse(this.parentNode);
    @reko