How can d3.transform be used in d3 v4?
d3.js, javascript, svg
Solution
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);
Addendum
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)"));
Problem
In d3.js v4 the `d3.transform` method has been removed, without any hint about how to replace it. Does anyone know how to replace the following d3.js v3 code? ``` d3.transform(String).translate; ```