In D3.js v4 the d3.transform method has been removed, without any hint about how replacing it. Does anyone know how to replace the following D3.js v3 instruction?

```
d3.transform(String).translate;
```

**Edit 2016-10-07:** For a more general approach see addendum below.

According to the changelog it is gone. There is a function in `transform/decompose.js`

, though, which does the calculations for internal use. Sadly, it is not exposed for external use.

That said, this is easily done even without putting any D3 to use:

```
function getTranslation(transform) {
// Create a dummy g for calculation purposes only. This will never
// be appended to the DOM and will be discarded once this function
// returns.
var g = document.createElementNS("http://www.w3.org/2000/svg", "g");
// Set the transform attribute to the provided string value.
g.setAttributeNS(null, "transform", transform);
// consolidate the SVGTransformList containing all transformations
// to a single SVGTransform of type SVG_TRANSFORM_MATRIX and get
// its SVGMatrix.
var matrix = g.transform.baseVal.consolidate().matrix;
// As per definition values e and f are the ones for the translation.
return [matrix.e, matrix.f];
}
console.log(getTranslation("translate(20,30)")) // simple case: should return [20,30]
console.log(getTranslation("rotate(45) skewX(20) translate(20,30) translate(-5,40)"))
```

This creates a dummy `g`

element for calculation purposes using standard DOM methods and sets its `transform`

attribute to the string containing your transformations. It then calls `.consolidate()`

of the `SVGTransformList`

interface to consolidate the possibly long list of transformation to a single `SVGTransform`

of type `SVG_TRANSFORM_MATRIX`

which contains the boiled down version of all transformations in its `matrix`

property. This `SVGMatrix`

per definition holds the values for the translation in its properties `e`

and `f`

.

Using this function `getTranslation()`

you could rewrite your D3 v3 statement

```
d3.transform(transformString).translate;
```

as

```
getTranslation(transformString);
```

Because this answer has gained some interest over time, I decided to put together a more general method capable of returning not only the translation but the values of all transformation definitions of a transform string. The basic approach is the same as laid out in my original post above plus the calculations taken from `transform/decompose.js`

. This function will return an object having properties for all transformation definitions much like the former `d3.transform()`

did.

```
function getTransformation(transform) {
// Create a dummy g for calculation purposes only. This will never
// be appended to the DOM and will be discarded once this function
// returns.
var g = document.createElementNS("http://www.w3.org/2000/svg", "g");
// Set the transform attribute to the provided string value.
g.setAttributeNS(null, "transform", transform);
// consolidate the SVGTransformList containing all transformations
// to a single SVGTransform of type SVG_TRANSFORM_MATRIX and get
// its SVGMatrix.
var matrix = g.transform.baseVal.consolidate().matrix;
// Below calculations are taken and adapted from the private function
// transform/decompose.js of D3's module d3-interpolate.
var {a, b, c, d, e, f} = matrix; // ES6, if this doesn't work, use below assignment
// var a=matrix.a, b=matrix.b, c=matrix.c, d=matrix.d, e=matrix.e, f=matrix.f; // ES5
var scaleX, scaleY, skewX;
if (scaleX = Math.sqrt(a * a + b * b)) a /= scaleX, b /= scaleX;
if (skewX = a * c + b * d) c -= a * skewX, d -= b * skewX;
if (scaleY = Math.sqrt(c * c + d * d)) c /= scaleY, d /= scaleY, skewX /= scaleY;
if (a * d < b * c) a = -a, b = -b, skewX = -skewX, scaleX = -scaleX;
return {
translateX: e,
translateY: f,
rotate: Math.atan2(b, a) * 180 / Math.PI,
skewX: Math.atan(skewX) * 180 / Math.PI,
scaleX: scaleX,
scaleY: scaleY
};
}
console.log(getTransformation("translate(20,30)"));
console.log(getTransformation("rotate(45) skewX(20) translate(20,30) translate(-5,40)"));
```

If you pull in d3 v4 through npm, you can import the `src/transform/parse`

file directly and call `parseSvg`

:

```
// using es2015 modules syntax
import { parseSvg } from "d3-interpolate/src/transform/parse";
parseSvg("translate(20, 20)");
```

On elements which have the d3.js `zoom`

listener on them -- usually the `<g>`

element appended to the svg element -- you can use this call to get the transformation attributes outside of the zoom function:

```
var self = this;
var t = d3.zoomTransform(self.svg.node());
// t = {k: 1, x: 0, y: 0} or your current transformation values
```

This returns the same values as when calling `d3.event.transform`

within the zoom event function itself.

Calling `d3.event.transform`

outside the zoom event function will error:
`Uncaught TypeError: Cannot read property 'transform' of null`

I have to use `d3.zoomTransform`

to allow panning and zooming from buttons outside the graph.

I found a little bit simpler solution than that.

```
selection.node().transform.baseVal[0].matrix
```

In this matrix you have cordinates e and f witch are equivalent to x, y. (e === x, f === y). No need to implement your very own funtion for that.

baseVal is a list of transformations of the element. **You can't use that for the object without previus transformation! (the list will be empty)** Or if you done many tranformation to the object the last position will be under the last element of baseVal list.

I am a little late to the party, but I had some code that was beneficial to me, I hope it helps you out too.

The code above by @altocumulus is quite thorough and works like a charm. However it didn't quite meet my needs since I was doing the calculations by hand and needed to alter some transform properties as painlessly as possible.

This might not be the solution for everyone, but it was perfect for me.

```
function _getTokenizedTransformAttributeValue(transformStr) {
var cleanedUpTransformAttrArr = transformStr.split(')', ).slice(0,-1);
return cleanedUpTransformAttrArr.reduce(function(retObj, item) {
var transformPair = item.split('(');
retObj[transformPair[0]] = transformPair[1].split(',');
return retObj;
}, {});
}
```

```
function _getStringFromTokenizedTransformAttributeObj(transformAttributeObj) {
return _.keys(transformAttributeObj).reduce(function(finalStr, key) {
// wrap the transformAttributeObj[key] in array brackets to ensure we have an array
// join will flatten the array first and then do the join so [[x,y]].join(',') -> "x,y"
return finalStr += key + "(" + [transformAttributeObj[key]].join(',') + ")";
}, '');
}
```

The really great thing with the first function is that I can manually alter a specific property (e.g. rotation), and not have to worry about how it affects translate or anything else (when rotating around a point), whereas when I rely on the built-in or even `d3.transform`

methods they consolidate all the properties into one value.

Imagine a some HTML

```
<g class="tick-label tick-label--is-rotated" transform="translate(542.8228777985075,0) rotate(60, 50.324859619140625, 011.402383210764288)" style="visibility: inherit;"></g>
```

In object form

```
jr {rotate: 59.99999999999999, translate: [577.8600589984691, -37.88141544673796], scale: [1, 1], skew: 0, toString: function}
```

In string form

```
"translate(577.8600589984691,-37.88141544673796)rotate(59.99999999999999)skewX(0)scale(1,1)"
```

Which is correct mathematically, but makes it hard for me to simply remove the angle of rotation *and* the translation that had to be introduced to rotate this element around a given point.

`_getTokenizedTransformAttributeValue`

functionIn object form

```
{translate: ["542.8228777985075", "0"], rotate: ["60", " 50.324859619140625", " 011.402383210764288"]}
```

In string form *using the function _getStringFromTokenizedTransformAttributeObj*

```
"translate(542.8228777985075,0)rotate(60, 50.324859619140625, 011.402383210764288)"
```

Which is perfect because now when you remove the rotation, your element can go back to where it was

Granted, the code could be cleaner and the function names more concise, but I really wanted to get this out there so others could benefit from it.

I found a way do achieve something similar by using this:

```
d3.select(this).node().getBBox();
```

this will give you access to the x/y position and width/height You can see an example here: https://bl.ocks.org/mbostock/1160929

©2020 All rights reserved.