1

这是来自https://observablehq.com/@d3/non-contiguous-cartogram的片段,它控制状态形状的转换。

function transform(d, year) {
  const [x, y] = path.centroid(d);
  return `
    translate(${x},${y})
    scale(${Math.sqrt(data.get(d.id)[year])})
    translate(${-x},${-y})
  `;
}

既然xy是常数,不应该translate(${x},${y})translate(${-x},${-y})抵消吗?

此外,为什么这种机制将质心固定在其旧位置?

4

1 回答 1

2

重要的是要理解 SVG 转换是连续应用的,即顺序很重要。您不能只是将数字相加来合并各种转换定义的列表。用规范的话来说:

'transform' 属性的值是一个<transform-list>,它被定义为一个变换定义的列表,这些定义按照提供的顺序应用。

该列表的每个变换定义都操作坐标系,该坐标系是所有后续变换的基础。尽管在您的示例中,平移名义上在相反方向上的量相同,但它们不会抵消,因为在两者之间发生的缩放会沿途改变坐标系。因此,第二个平移不会覆盖与第一个平移相同的距离。

要理解为什么这些转换将质心保持在适当的位置,更正式地写下它们会有所帮助。给定质心的坐标 (x c , y c )和比例因子k,我们可以将它们写为:

xx c + k ( x - x c )
yy c + k ( y - y c )

每个原始点(x, y)都映射到质心(第一项),然后向外移动到其原始位置,但它只移动了原始距离的缩小部分(第二项)。

将质心本身插入这些规则会显示第二项抵消,它将质心保持在其原始位置,从而将整个变换集中在质心上:

x cx c + k ( x c - x c ) = x c
y cy c + k ( y c - y c ) = y c

于 2020-02-14T23:00:14.230 回答