避免在 d3 轴标签中使用 dx/dy 属性

Avoid dx/dy attributes in d3 axis labels

我在导出 SVG 文件并在 Corel Draw(某些旧版本)中打开它时遇到文本元素位置问题。我通过将每个 dx/dy 属性设置为零并将其值添加到相应的 x/y 属性来修复它。

我写了一个辅助函数,在我使用的每个文本元素上用 .each 调用。

transformDXYtoXY: function(d, i) {
    var that = d3.select(this);

    var y = that.attr("y") == null ? 0 : parseFloat(that.attr("y"));
    var dy = that.attr("dy") == null ? 0 : parseFloat(that.attr("dy"));
    that.attr("y", y + dy);
    that.attr("dy", 0);

    // doing the same with dx/x
    ...
},

在我决定在输入更改时转换轴而不是重新绘制它们之前,这一直很好用:

axis = d3.svg.axis().scale(someScale);
d3.select('.axis')
    .transition()
    .call(axis)
    .selectAll("text")
    .each(transformDXYtoXY);

不调用 transformDXYtoXY() 刻度标签位置关闭 y/dy 属性未设置,即使我在 transformDXYtoXY() 中检查它似乎没问题。

有没有办法告诉 d3 避免使用 dx/dy?问题似乎发生在 transition().

期间

dxdy 属性的使用在 D3 的源代码中进行了硬编码——更改它需要付出很大的努力。但是,有一个简单的解决方法。 D3 转换允许您设置 listener for the end of the transition。您可以利用它 运行 您的代码来修复属性值(对现有代码进行最少的更改):

d3.select('.axis')
  .transition()
  .call(axis)
  .selectAll("text")
  .each("end", transformDXYtoXY);

澄清一下,您目前的代码 运行 的功能是在设置转换后立即修复属性,然后 运行 并覆盖属性值。上面的代码 运行 是转换完成后的函数,即不会发生进一步的属性更改。