【问题标题】:D3.js: real-time sunburst Partition data: recreate Hierarchy?D3.js:实时旭日形分区数据:重新创建层次结构?
【发布时间】:2021-05-18 16:40:21
【问题描述】:

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

我一直在研究一个多变量、可缩放、旭日形+冰柱图。作为参考,我受到以下启发:

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

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

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

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

我希望我已经清楚地解释了自己?只求高手指导。谢谢!

【问题讨论】:

  • 我认为您的演示存在一个非常根本的问题:一次渲染太多元素。您需要从渲染高级聚合数据开始,然后通过放大显示特定扇区的详细信息。圆形包装 (observablehq.com/@d3/zoomable-circle-packing) 可能是该类型分层数据的一个很好的例子。可折叠树也可以工作......
  • @MichaelRovinsky 感谢您的评论。是的,100% 同意你的观点,我想通了。我最终构建了一些“智能”,以便如果一个扇区太小(视觉上)无法向下递归,它会“向上滚动”到一个聚合弧。如果你点击它,当你放大时,它会在下面“输入”更详细的节点。

标签: javascript d3.js sunburst-diagram


【解决方案1】:

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

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

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

【讨论】:

  • 抱歉耽搁了!这正是我最终做的,使用data() 中的第二个参数。我所有的元素都有唯一/不变的名称,因此很容易找到更新的元素以及哪些是新的/进入的。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-16
  • 2012-04-22
  • 2020-11-27
  • 2015-01-18
  • 2021-07-22
  • 1970-01-01
相关资源
最近更新 更多