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



在导出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转换允许您为转换的结束设置一个监听器。您可以利用这一点来运行代码来修复属性值(对现有代码的更改最小):

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

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

最新更新