Monday, May 20, 2024
 Popular · Latest · Hot · Upcoming
178
rated 0 times [  180] [ 2]  / answers: 1 / hits: 24544  / 8 Years ago, wed, july 6, 2016, 12:00:00

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;

More From » svg

 Answers
16

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)));




[#61493] Monday, July 4, 2016, 8 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
maurodannyr

Total Points: 126
Total Questions: 103
Total Answers: 105

Location: Maldives
Member since Sun, Feb 27, 2022
2 Years ago
;