将标题附加到 D3 树布局会导致错误 (D3)
Appending title to D3 Tree layout causes error (D3)
我正在尝试向 D3 树布局中的某些 SVG 标签添加工具提示。
这是使用转换呈现标签的函数:
buildLabels() {
const labelSelection = d3.select('svg g.labels')
.selectAll('text.label')
.data(this.nodes);
labelSelection.exit()
.remove();
labelSelection.enter()
.append('text')
.style('fill', 'none')
.style('stroke', 'none')
.style('stroke-width', '0')
.attr('transform', (d: any) => // ...)
.style('fill-opacity', 0)
.transition()
.duration(450)
.ease(d3.easeCircleIn)
.attr('transform', (d: any) => {
// ...
})
.attr('class', 'label')
.style('stroke', '#393D3E')
.style('fill', '#393D3E')
.style('fill-opacity', 1)
.style('stroke-width', '.4')
.style('text-anchor', (d: any) => d.parent ? 'start' : 'end')
.text(d => d.name);
}
我试过添加
.append('title')
.text(d => d.name)
在 .text
之后,但我得到了
的长控制台错误
core.js:4061 ERROR TypeError: labelSelection.enter(...).append(...).style(...).style(...).style(...).attr(...).style(...).transition(...).duration(...).ease(...).attr(...).attr(...).style(...).style(...).style(...).style(...).style(...).text(...).append is not a function
如果我将函数更改为:
labelSelection.enter()
.append('text')
.text(d => d.name)
.append('title')
.text(d => d.name);
我得到了我期待的 DOM,即
<text>
Node name
<title>Node name</title>
</text>
然而,none 的节点看起来是正确的,但没有它们应有的位置。当然,转换也全部删除。
我的问题是,是否有另一种方法可以添加不笨重的标题,或者如何解决上述错误。谢谢!
您正在尝试附加到转换:
labelSelection.enter()
.append('text') // returns a selection of newly entered text elements
.style(...) // returns that same selection
.attr(... ) // returns that same selection
// ...
.transition() // returns a transition
.duration(450) // returns that same transition
.ease(...) // returns that same transition
// ...
.text(d => d.name) // returns that same transition
.append(...) // error
Transitions 和 selections 共享很多方法(例如 .style()
、.attr()
,甚至 .text()
),所以它们看起来很相似,但它们并不共享所有方法。
您可以 selection.append()
,但不能 transition.append()
。这就是您收到错误消息的原因,append
不是一种转换方法,它解释了您的错误消息:
labelSelection.enter(...).append(...).style(...).style(...).style(...).attr(...).style(...).transition(...).duration(...).ease(...).attr(...).attr(...).style(...).style(...).style(...).style(...).style(...).text(...).append is not a function
.text returns 在这种情况下是一个转换(因为它被链接到一个转换,如上面第一个代码块中所示),所以我们可以将其减少到 "transition.append is not a function".
相反,您可以通过保留对相关选择的引用来分解方法链:
var labelEnter = labelSelection.enter()
.append('text')
.style(...)
.attr(... )
// ...
labelEnter.transition()
.duration(450)
.ease(...)
// ...
labelEnter.append("title")
.text(...)
另一种方法是使用 transition.selection()
,我认为这会使您的方法链过长,returns 转换对应的选择:
labelSelection.enter()
.append('text')
.style(...)
.attr(... )
// ...
.transition()
.duration(450)
.ease(...)
// ...
.text(d => d.name);
.selection() // return a selection instead of a transition
.append("title")
.text(...)
我正在尝试向 D3 树布局中的某些 SVG 标签添加工具提示。 这是使用转换呈现标签的函数:
buildLabels() {
const labelSelection = d3.select('svg g.labels')
.selectAll('text.label')
.data(this.nodes);
labelSelection.exit()
.remove();
labelSelection.enter()
.append('text')
.style('fill', 'none')
.style('stroke', 'none')
.style('stroke-width', '0')
.attr('transform', (d: any) => // ...)
.style('fill-opacity', 0)
.transition()
.duration(450)
.ease(d3.easeCircleIn)
.attr('transform', (d: any) => {
// ...
})
.attr('class', 'label')
.style('stroke', '#393D3E')
.style('fill', '#393D3E')
.style('fill-opacity', 1)
.style('stroke-width', '.4')
.style('text-anchor', (d: any) => d.parent ? 'start' : 'end')
.text(d => d.name);
}
我试过添加
.append('title')
.text(d => d.name)
在 .text
之后,但我得到了
core.js:4061 ERROR TypeError: labelSelection.enter(...).append(...).style(...).style(...).style(...).attr(...).style(...).transition(...).duration(...).ease(...).attr(...).attr(...).style(...).style(...).style(...).style(...).style(...).text(...).append is not a function
如果我将函数更改为:
labelSelection.enter()
.append('text')
.text(d => d.name)
.append('title')
.text(d => d.name);
我得到了我期待的 DOM,即
<text>
Node name
<title>Node name</title>
</text>
然而,none 的节点看起来是正确的,但没有它们应有的位置。当然,转换也全部删除。
我的问题是,是否有另一种方法可以添加不笨重的标题,或者如何解决上述错误。谢谢!
您正在尝试附加到转换:
labelSelection.enter()
.append('text') // returns a selection of newly entered text elements
.style(...) // returns that same selection
.attr(... ) // returns that same selection
// ...
.transition() // returns a transition
.duration(450) // returns that same transition
.ease(...) // returns that same transition
// ...
.text(d => d.name) // returns that same transition
.append(...) // error
Transitions 和 selections 共享很多方法(例如 .style()
、.attr()
,甚至 .text()
),所以它们看起来很相似,但它们并不共享所有方法。
您可以 selection.append()
,但不能 transition.append()
。这就是您收到错误消息的原因,append
不是一种转换方法,它解释了您的错误消息:
labelSelection.enter(...).append(...).style(...).style(...).style(...).attr(...).style(...).transition(...).duration(...).ease(...).attr(...).attr(...).style(...).style(...).style(...).style(...).style(...).text(...).append is not a function
.text returns 在这种情况下是一个转换(因为它被链接到一个转换,如上面第一个代码块中所示),所以我们可以将其减少到 "transition.append is not a function".
相反,您可以通过保留对相关选择的引用来分解方法链:
var labelEnter = labelSelection.enter()
.append('text')
.style(...)
.attr(... )
// ...
labelEnter.transition()
.duration(450)
.ease(...)
// ...
labelEnter.append("title")
.text(...)
另一种方法是使用 transition.selection()
,我认为这会使您的方法链过长,returns 转换对应的选择:
labelSelection.enter()
.append('text')
.style(...)
.attr(... )
// ...
.transition()
.duration(450)
.ease(...)
// ...
.text(d => d.name);
.selection() // return a selection instead of a transition
.append("title")
.text(...)