D3.js:实时旭日分区数据:重新创建层次结构?

D3.js: real-time sunburst Partition data: recreate Hierarchy?

首先:我喜欢 D3。太奇妙了。让我希望我能更好地了解 JS。希望有人能帮助我!

我一直在研究多变量、可缩放、森伯斯特+冰柱图。作为参考,我受到以下启发:

我最近一直在考虑添加实时组件:我已经将实时数据馈送(通过 MQTT)集成到我的 JS 代码中,它是来自源的 receive/reading 数据并添加到分层数据。从本质上讲,我不断地添加构建我的旭日图的数据,每 2 秒重新绘制一次旭日图,我想知道最好的方法。

预实时,我开始读取静态 JSON 文件,使用 d3.json 加载 JSON 文件,然后调用 d3.hierarchy ,最终我将其传递给 d3.partition。注意:因为我有多个values/variables,所以我需要运行partition多次得到不同大小的圆弧,然后在它们之间补间。 This seemed to work fine. Example here.

但是现在我一遍又一遍地构建层次结构+分区,每 2 秒一次,随着数据从后面加载,我想知道:是吗最好每次都根据我的数据创建一个新的层次结构(d3 节点树),还是自己构建层次结构?

我特别关心 select.join() 是如何工作的(用于在先前值和新值的弧之间补间),以及 d3 如何知道哪些节点是新节点,哪些不是?如果我每次 运行 d3.hierarchy(),那么每个节点都是新的(对吗?),那么 enter-vs-update 是如何工作的?即使源数据相同(尽管由于实时更新而具有不同的值)。我不认为有创建“new Node()”或如何 maintain/add 到节点树的公开记录方式,但似乎这比 运行ning d3.hierarchy每隔几秒。

希望我已经解释清楚了?只是寻找一些专家指导。谢谢!

当您调用.data()时,您可以提供第二个参数,告诉 D3 如何识别每个项目。例如 .data(mydata, d => d.data.id) 表示使用 id 字段来标识每个节点。

然后,当 .join() 发挥作用时,它将查看此值并将其与附加到每个节点的值进行比较。在任何节点上未看到的任何新值都将转到 enter,而在现有节点上找到的那些值将转到 update.

这样做的唯一技巧是确保您指定的值绝对是唯一的,并且不会在调用之间更改。例如,如果您执行 .data(mydata, d => d.data.surname) 之类的操作并获得两个具有相同姓氏的项目,则 enter/update 将产生不可预测的结果。同样,如果您执行 .data(mydata, d => d.data.randomValue),那么项目将永远不会更新,因为每次调用之间的值始终不同 - 节点将通过 exit 删除,然后通过 enter 重新创建,而不是留在放置但由 update 修改,因为不同的值使 D3 将它们视为新节点而不是将它们识别为现有节点。