21

I'm trying to get the values for an element's translation.

For example, if I select the x axis:

d3.select('.x.axis').attr("transform")

then I get

"translate(0,112)"

How do I get the 0 and the 112 without parsing a regexp?

I'm trying to do it so that I can add to the value. In pseudocode:

d3.selectAll('.x.axis').attr('transform', 'translate('
        .attr('transform').match(/(\d+)(\.\d+)?/g)[0] // <-- clearly won't work
        + additional_value
        + ', 0)');
ari gold
  • 2,074
  • 3
  • 25
  • 51

2 Answers2

38

D3 provides the transform() function for exactly this purpose:

var t = d3.transform(d3.select('.x.axis').attr("transform")),
    x = t.translate[0],
    y = t.translate[1];
Lars Kotthoff
  • 107,425
  • 16
  • 204
  • 204
  • 1
    How would I go about doing it with a selectAll? So that I'm iterating on each element and, say, storing the x & y in an array? – ari gold Dec 03 '13 at 19:23
  • You could use `.each()`, which calls the function argument for each element in the selection. – Lars Kotthoff Dec 03 '13 at 19:37
  • 1
    Yes, that's what I'm trying (in the Chrome console) but am having issues with scope. That is, `.attr` works on the d3 selection but I can't seem to get access to it -- from the [docs](https://github.com/mbostock/d3/wiki/Selections#wiki-each) I only get the datum (d) the index (i) and the current DOM selection (this). – ari gold Dec 03 '13 at 19:46
  • 1
    You can get access to the current element through `d3.select(this)`. – Lars Kotthoff Dec 03 '13 at 19:54
  • Hmm. I'm not getting the values that I expect. Specifically, I'm getting [0,0] although I see that there is a non zero x value in the transform attribute when I inspect the DOM element. – ari gold Dec 03 '13 at 20:11
  • Could you post an example that demonstrates the problem please? – Lars Kotthoff Dec 03 '13 at 20:19
  • My bad, nevermind. I thought that the `.attr("transform")` part of your answer wasn't necessary because that's what the `d3.transform` part did. Turns out it's essential although I'm not sure why.. Alls good! – ari gold Dec 03 '13 at 20:37
  • 1
    `d3.transform` only parses the string, it doesn't retrieve it. – Lars Kotthoff Dec 03 '13 at 20:43
  • Thank you so much! This is the simplest solution I found and it works perfectly! – Dao Lam Jul 08 '14 at 19:43
  • 17
    only available in **v3** , not d3.js v4 - https://github.com/d3/d3-3.x-api-reference/blob/master/API-Reference.md – shershen Jan 12 '17 at 13:02
  • 3
    For d3.js v4, see this answer: http://stackoverflow.com/a/38230545/1703772 and send in the transform attribute directly. – NuclearPeon Mar 21 '17 at 19:16
4

if you would like to use selectAll you could try something like this:

// move ticks to the center of the x-axis   
var transform;
d3.selectAll('.tick').attr('transform', function(){
  transform = d3.transform(d3.select(this).attr("transform"));
  return "translate("+transform.translate[0]+", -3)";
});
  • The code illustrates how you could solve the problem of using translate with d3.selectAll. to operate on multiple elements. in the comments above ari gold asked how to do this. the code is selecting all the elements that have the class '.tick'. getting the transform attribute and running a function to set the transform attribute. that function uses d3.transform to get values so you could update it in place. – Keith Mitchell Jan 08 '15 at 23:41