javascript - 为什么我对 selection.join() 的调用没有返回输入选择?
问题描述
我已经设法<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>
解决方案
用文档的话来说:
根据需要追加、删除和重新排序元素以匹配先前由selection .data绑定的数据,返回合并的输入和更新选择。
这意味着selection.join()
应该已经返回您所追求的选择,即更新节点的合并选择以及新输入的选择。正如您在代码中亲眼目睹的那样,由于文档未涵盖的小细节,情况并非如此。
如果您将函数传递.join()
给以对进入、更新和退出时发生的情况进行细粒度控制,则前两个函数(进入和更新)必须返回它们所作用的相应选择(即分别返回进入或更新选择)!
在您的代码段中,输入选择的处理函数是一个箭头函数,它执行一个不返回任何选择的代码块。因此,进入的节点不包括在返回的选择中.join()
。根据这些处理函数的复杂性,基本上有两种方法:
对于简单的情况,只需省略大括号,这将使箭头函数返回表达式的值:
.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()
选择包括由 enter 和更新处理程序合并为一个返回的选择。尽管我无法为这种相当越野的用途提出应用程序,但可能值得将这些知识留在我们的脑海中。
推荐阅读
- mongodb - 关于如何在猫鼬中编写评论模式的任何想法?
- javascript - Gitlab CI - 在赛普拉斯测试可以运行之前服务器被“杀死”
- python - 我想要以分钟为单位计算的标准偏差
- charts - 在谷歌图表中添加列时如何更改文本颜色
- javascript - 查找出现在检查的网络选项卡 Reactjs 上的 fetch 函数的源文件
- javascript - 移除端口并保留主机
- java - Spring data R2DBC - 连接到多个数据库时未选择自定义转换器
- django - 让 Django ORM 自动获取属性
- java - Firebase“sendSignInLinkToEmail”方法发送一封没有安卓链接的邮件
- reactjs - React Router history.push() 改变了 url 但没有渲染组件内容