这在d3版本4的Datum()中无法访问绑定元素

时间:2017-04-15 13:42:47

标签: javascript d3.js

请参阅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)));

1 个答案:

答案 0 :(得分:1)

您的代码段无法正常工作。但是,在解决这个问题之前,请考虑一下您的问题:

  • 来自Bostock(内联标签)的代码使用D3 v4 ,而不是v3。
  • 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