Reputation: 823
Such a stupid question and probably have a simple answer but I am unable to drag my images around my canvas. Here is my code for my images :
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
}
And my drag function:
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");
});
I get the error when trying to drag one of the images :
Uncaught TypeError: Cannot read property 'x' of undefined
I have tried to research it and apparently I don't have data applied to my rectangle. How do I fix this ?
Upvotes: 1
Views: 156
Reputation: 25157
Drag is supposed to pass d
— the datum bound to the element being dragged – into your handler function .on("drag", function(d,i) { ... }
.
In your case d
is undefined, which is why setting d.x
complains that it can't read property 'x'
of undefined. The reason d
is undefined is because no datum is bound to the image. The way data gets bound to elements is either:
.data()
method to bind and then append the enter()
'ing to elements — rather than just svg.append
ing them as you do. Or,.datum()
method.Doing one of those 2 raises the question of what d
is supposed to be. Well... it should be an object with properties x
and y
, since the drag handler wants to modify those props.
x
and y
should probably be initialized to xpos
and ypos
, i.e. the initial position. Once x
and y
are part of a datum, you should switch to setting the image's x and y positions based on them, rather than hardcoded to xpos, ypos
.
Putting it all together, if you picked option #2, then it looks like this:
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)
Upvotes: 2