替换 D3 v4 中的 d3.transform [英] Replacing d3.transform in D3 v4

查看:27
本文介绍了替换 D3 v4 中的 d3.transform的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在 D3.js v4 中,d3.transform 方法已被删除,没有任何关于如何替换它的提示.有谁知道如何替换下面的 D3.js v3 指令?

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: 有关更通用的方法,请参阅下面的附录.

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

根据变更日志,它已经消失了.transform 中有一个函数/decompose.js,但是,它进行内部使用的计算.遗憾的是,它没有对外公开.

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.

也就是说,即使不使用任何 D3 也很容易做到这一点:

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

这会使用标准 DOM 方法创建一个用于计算目的的虚拟 g 元素,并将其 transform 属性设置为包含您的转换的字符串.然后它调用<的.consolidate()code>SVGTransformList 接口将可能很长的转换列表合并为一个 SVGTransform 类型为 SVG_TRANSFORM_MATRIX,它在其 matrix 属性中包含所有转换的简化版本.这个 SVGMatrix 每个定义包含其属性 ef 中的翻译值.

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.

使用这个函数 getTranslation() 你可以重写你的 D3 v3 语句

Using this function getTranslation() you could rewrite your D3 v3 statement

d3.transform(transformString).translate;

作为

getTranslation(transformString);

<小时>

附录

因为这个答案随着时间的推移引起了一些兴趣,我决定组合一个更通用的方法,不仅能够返回转换,而且能够返回转换字符串的所有转换定义的值.基本方法与我在上面的原始帖子中列出的相同,加上从 transform/decompose.js.此函数将返回一个对象,该对象具有所有转换定义的属性,就像以前的 d3.transform() 做到了.

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

这篇关于替换 D3 v4 中的 d3.transform的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆