How do I get the transform y value of an object?

10,421 views
Skip to first unread message

John

unread,
Oct 24, 2011, 9:12:03 PM10/24/11
to d3-js
This seems like a simple question, but I can't find any references in
the group archive.

I've created a rectangle, and am allowing the user to move it up and
down with the mouse, (by applying a transform to the rectangle
group's y axis.

Now I want to retrieve the y value of the rectangle group, but d3
always returns null as the 'y' value

I've tried :
console.log(d3.select("#theBarGroup").attr("y")); //always null

However, I know I have the correct object, because when I log:
console.log(d3.select("#theBarGroup").attr("transform"));

I get some variant of the string
"translate(0, -53) scale(1)"

I just can't seem to grab the -53...
Any ideas?
Thanks!

Mike Bostock

unread,
Oct 24, 2011, 9:14:25 PM10/24/11
to d3...@googlegroups.com
You could try getBBox:

http://www.w3.org/TR/SVG/types.html#__svg__SVGLocatable__getBBox

Which would be:

d3.select("#theBarGroup").node().getBBox()

Alternatively, the data-driven way would be to bind some data to your
rectangle, modify that, and then recompute the transform from the
data. That way, you don't have to pull data back out of the DOM.

Mike

John

unread,
Oct 25, 2011, 3:06:03 PM10/25/11
to d3-js
Thanks for the quick reply Mike,

I tried implementing your solution, but BBox also appears to be
returning zero values.

I threw together a simplified version of the problem up on jsfiddle
here:
http://jsfiddle.net/johnwun/Ap3YP/

It shows that transform is returning values, but BBox doesn't register
them.

I'd settle for anything that works at this point, but I'm also
interested in your second solution, I just don't understand how I'd
implement it in this case.

thanks again,
-J

Ian Johnson

unread,
Oct 25, 2011, 4:26:46 PM10/25/11
to d3...@googlegroups.com
I've dealt with something like this before, you want to get the offset in the svg's coordinate space, so you need to use SVG transforms:
http://jsfiddle.net/KvpMJ/

When dealing with mouse interaction I'm not sure of a clean way to do it in a data-driven manner. You want to have the mouse interact in the svg coordinate space, and you want things to behave appropriately in that space too (lets say by moving the same number of pixels as you moved your mouse)

Is what you are suggesting Mike, something like keeping track of an offset? You draw your rectangle at some starting point plus an offset in the x and y directions. As you drag, the offset is changed accordingly and the translation is updated. This way you can also move/change other things based on the offset you have.

I still needed this transformToElement stuff in the case of using a viewBox which doesn't necessarily match up with the svg height/width.
--
Ian Johnson

John

unread,
Oct 25, 2011, 7:56:44 PM10/25/11
to d3-js
Awesome Ian,
This solves my problem!

Thank you!
-J

Chris Viau

unread,
Oct 26, 2011, 9:43:21 AM10/26/11
to d3...@googlegroups.com
The matrix way is the way to go. But for a simple case, as in your example, where you only want to extract the x and y values from the ".translate(10, 20)" string you receive, you can just split the string to isolate the x and y component.

function getXYFromTranslate(element){
    var split = element.getAttribute("transform").split(" ");
    var x = ~~split[0].split("(")[1];
    var y = ~~split[1].split(")")[0];
    return [x, y];

Chris Viau

unread,
Oct 26, 2011, 10:21:31 AM10/26/11
to d3...@googlegroups.com
And here is the jsfiddle: jsfiddle .

Chris Viau

unread,
Jan 20, 2012, 1:59:00 PM1/20/12
to d3...@googlegroups.com
Another way to do retrieve the transform components (translate, rotate, skew, scale) is with  d3.transform: 
var components = d3.transform(element.attr("transform"));

Reply all
Reply to author
Forward
0 new messages