我已经设法使用<g>
创建了一些selection.join()
标签。完成连接后,我想重新选择所有用于方法链的现有<g>
标签的完整列表,即之前存在的标签加上已创建的标签减去销毁的标签。如何从joinedNodes
变量中获取此信息?
private createOrRemovePanelGroups(chartPanelsGroup: any, panelsRectangles: Array<Rectangle>): any {
const joinedNodes: any = chartPanelsGroup
.selectAll('g')
.data(panelsRectangles)
.join(
enter => {
enter.append('g');
});
在下面的第二个示例中,该方法采用<g>
中选定的selectedParentNode
和矩形的描述符。它必须在此处绘制一个唯一的矩形。我使用ID进行选择。在第一次运行中,它被创建,但是不包含在.join()
返回的选择中。因此,对于新创建的矩形,不执行最后4行。但是,如果第二次执行并且矩形已经存在,则会执行这些行,然后设置属性。
static drawRectangle(selectedParentNode: any, rectangle: Rectangle, uniqueId: any, classStyle: any) {
selectedParentNode
.selectAll('#' + uniqueId)
.data([{rectangle}])
.join(
(enter: any) => {
enter
.append('rect')
.attr('id', uniqueId);
},
(update: any) => update
)
.attr('x', rectangle.getLeftX())
.attr('y', rectangle.getTopY())
.attr('width', rectangle.getWidth())
.attr('height', rectangle.getHeight())
.attr('class', classStyle);
}
我的具体问题可以归结为以下MCVE。为什么.join()
返回的选择为空?
const joinedSelection = d3.select("body").selectAll(null)
.data([1])
.join(enter => { enter.append("p"); });
console.log(joinedSelection.empty()); // true -- Why is this selection empty?
<script src="https://d3js.org/d3.v5.js"></script>
答案 0 :(得分:1)
用文档的话来说:
根据需要添加,删除和重新排序元素,以匹配先前由selection.data绑定的数据,返回merged输入并更新选择。
这意味着selection.join()
应该已经返回了您要选择的内容,即更新后的节点以及新输入的节点的合并选择。正如您在代码中亲眼目睹的那样,情况并非如此,原因是文档中未包含一些小细节。
如果要将函数传递给.join()
以便对输入,更新和退出时发生的情况进行细粒度控制,则前两个函数(输入和更新)必须返回它们所作用的相应选择(即返回输入或更新选择)!
在您的代码段中,用于enter选择的处理函数是一个箭头函数,执行一个代码块,该代码块不返回任何选择。因此,输入节点不包含在.join()
返回的选择中。根据这些处理程序函数执行的复杂性,基本上有两种解决方法:
在简单情况下,只需省略大括号即可,这将使arrow函数返回表达式的值:
.join(enter => enter.append('g'));
对于更复杂的情况,您可以轻松地从代码块中返回选择:
.join(enter => {
// ...do some serious stuff first.
// append the entering nodes
enter = enter.append("g")
// ...followed by even more action.
// Finally return the selection.
return enter;
}
请注意,在使用上述(1.)解决方案读取的第二个代码段中,如何正确选择更新。
您的MCVE可以轻松地进行相应调整:
const joinedSelection = d3.select("body").selectAll(null)
.data([1])
.join(enter => { return enter.append("p"); });
// .join(enter => enter.append("p")); // works as well
console.log(joinedSelection.empty()); // false, contains enter selection
<script src="https://d3js.org/d3.v5.js"></script>
流氓用法(不是胆小的人)-与您的特定问题无关。
对回车或更新处理程序函数返回的选择类型没有限制;您可能还会返回任何选择,甚至是空选择或完全不相关的选择。 .join()
返回的选择包括回车返回的选择,并且更新处理程序合并为一个。尽管我无法针对这种越野用途提出申请,但值得将这些知识放在脑后。