我正在使用Vega JS用于构建树形图。总的来说,我的问题如下:
Vega 文档有一个很棒的 example of tree layout 。我怎样才能扩展它并具有折叠和展开其节点的能力?
更具体地说,让我们考虑一下我正在构建的树形图的示例 here in Vega Editor .
如果您单击节点,它们将切换(展开或折叠),使您可以看到树的特定分支。除非您尝试折叠顶级节点(区域),同时保持二级节点(区域)展开,否则此功能可以正常工作。在这种情况下,树将如下所示:
发生这种情况是因为我处理此交互的方式:
- 当您点击节点时,会触发
toggledNode
信号,进而触发expandedNodes
数据数组中的toggle
操作。 IE。通过单击一个节点,我可以将该节点添加到expandedNodes
数组中或从中删除(更准确地说,我们添加/删除仅具有name
属性的简化对象) - 因此,
expandedNodes
数据包含有关哪些节点显式扩展的信息。但它不知道这些展开的节点是否位于折叠的父节点内部。 - 然后,为了找出哪些节点实际上可见,我使用
visibleNodes
数据。在那里,我使用以下表达式应用filter
转换:!datum.parent || indata('expandedNodes', 'name', datum.parent)
。 IE。我仅检查上一级:如果节点的父节点存在于expandedNodes
数组中,我认为该节点可见。
问题如下:我找不到任何方法可以跨多个级别扩展此功能。
也许我可以编写一些钩子(Hook)来检查 2 或 3 个级别的相同条件,例如:
!datum.parent ||
indata('expandedNodes', 'name', datum.parent) &&
indata('expandedNodes', 'name', datum.myCustomFieldWithParentNode.parent) &&
indata('expandedNodes', 'name', datum.myCustomFieldWithParentNode.myCustomFieldWithParentNode.parent)
但是对于这样一个简单的问题来说似乎太复杂了,而且这也不是最终的解决方案。理论上,一棵树可能包含几十个嵌套级别:那该怎么办?
我在 Vega 中发现了一个有用的表达式:treeAncestors 。我可以轻松地用 JavaScript 编写一个解决方案,其中有循环和数组方法,例如 .some()
和 .every()
。但显然 Vega 不支持任何表达式来迭代数组。因此,即使我可以使用 treeAncestors
函数获取树节点祖先数组,但我无法用它做任何事情来验证所有祖先是否都已展开。
要么我的方法是错误的,有人可以找到更好的算法来执行相同的操作,该算法不需要迭代数组(data
和 indata
表达式除外) - 或者这是 Vega 当前的限制。
最佳答案
您可以使用treeAncestors,然后使用展平变换来获取可以查询的数据集。在你的情况下,它看起来像:
{
"transform": [
{
"as": "treeAncestors",
"type": "formula",
"expr": "treeAncestors('tree', datum.id, 'root')"
}
],
"name": "tree-ancestors",
"source": "tree"
},
{
"transform": [{"fields": ["treeAncestors"], "type": "flatten"}],
"name": "tree-ancestors-flatt",
"source": "tree-ancestors"
},
{
"transform": [
{
"type": "filter",
"expr": "indata('selected', 'value', datum.treeAncestors.id)"
}
],
"name": "filtered",
"source": "tree-ancestors-flatt"
},
{
"transform": [{"type": "aggregate", "groupby": ["id"]}],
"name": "filtered-aggregate",
"source": "filtered"
},
{
"transform": [
{
"type": "filter",
"expr": "indata('filtered-aggregate', 'id', datum.id) "
}
],
"name": "filtered-tree",
"source": "tree"
}
关于javascript - 如何在Vega JS中实现树节点切换?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69302893/