请参阅d3 v4.0.0-alpha 9中的Inline Labels,
label.append("rect", "text")
.datum(() => this.nextSibling.getBBox())
.attr('x', d => (d.x - labelPadding))
.attr('y', d => (d.y - labelPadding))
.attr('width', d => (d.width + (2 * labelPadding)))
.attr('height', d => (d.height + (2 * labelPadding)));
它会通过这个访问datum()中的元素,为文本附加一个矩形。
为每个系列中的每个点渲染一个标签。在此标签下方,添加了一个白色矩形,其大小和位置使用element.getBBox和一点填充自动计算。由此产生的标签是清晰的
根据D3 v3 set datum,我们应该创建一个未绑定到数据的新选择,以便以后在版本4中使用(例如,v4.7.4)。我尝试创建新的选择,如下所示,但似乎bbox是单个对象而不是多个对象应该在数据中循环,如上面的代码在d3 v4.0.0-alpha 9中。
const newText = label.selectAll('text');
const bbox = newText.node().getBBox();
label.append('rect', 'text')
.datum(() => bbox)
.attr('x', d => (d.x - labelPadding))
.attr('y', d => (d.y - labelPadding))
.attr('width', d => (d.width + (2 * labelPadding)))
.attr('height', d => (d.height + (2 * labelPadding)));
答案 0 :(得分:1)
您的代码段无法正常工作。但是,在解决这个问题之前,请考虑一下您的问题:
append("rect", "text")
不会将矩形附加到文本中。它将矩形附加到容器,无论是SVG还是组元素(在这种特殊情况下,是一个组),之前文本。最后一个要点非常重要,因为文本将始终与矩形相关nextSiblings
。
话虽如此,我们来到你的片段。当你这样做时:
const newText = label.selectAll('text');
const bbox = newText.node().getBBox();
你实际上是这样做的:
const bbox = label.selectAll('text').node().getBBox();
您的datum
函数将最终成为:
.datum(() => label.selectAll('text').node().getBBox();)
嗯,这与Bostock的代码大不相同,因为这......
label.selectAll('text').node()
...将选择所有text
元素,但只返回DOM中的第一个。这是因为node()
,其中:
返回此选择中的第一个(非null)元素。 (强调我的)
另一方面,在Bostock的代码中,这......
.datum(() => this.nextSibling.getBBox())
...将在每次迭代时指向不同的DOM元素,因为this.nextSibling
每次都是不同的text
元素(正如我们在本答案的开头看到的那样,相应矩形的nextSibling
。