在导出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()
期间。
dx
和dy
属性的使用是在D3的源代码中硬编码的——更改它将是一项巨大的工作。然而,有一个简单的解决方法。D3转换允许您为转换的结束设置一个监听器。您可以利用这一点来运行代码来修复属性值(对现有代码的更改最小):
d3.select('.axis')
.transition()
.call(axis)
.selectAll("text")
.each("end", transformDXYtoXY);
为了澄清,您目前拥有的代码在设置转换后立即运行函数来修复属性,然后运行转换并覆盖属性值。上面的代码在转换完成后运行函数,即不会发生进一步的属性更改。