我在用着Vega JS https://vega.github.io/vega用于构建树形图。总的来说,我的问题如下:
Vega 文档有很棒的树形布局示例 https://vega.github.io/vega/examples/tree-layout/。如何通过折叠和展开其节点的能力来扩展它?
更具体地说,让我们考虑一个我正在构建的树形图的示例在 Vega 编辑器中 https://vega.github.io/editor/?#/url/vega/N4IgJAzgxgFgpgWwIYgFwhgF0wBwqgegIDc4BzJAOjIEtMYBXAI0poHsDp5kTykSArJQBMARkoArCGwB2IADQgcSACYqaMsmgGKkDTGwg0AXnDShMATxxn0ylQpAAnOEdNpMThnAC%20io2QySAA2EGgA2qBBCLYYbE4mspghjsQh3mgAZiEQcIpMGg6ooBo4%20mggsHBQANZMbAAeID5%20UUgxFfE0cDLJmOxyigw4KkiYsTBdxkkhAAQA-LMA5JMJ070hS7Ooy6RO-VCbzfJtHegybCpwAOo0KvSp6bbCAAwvrSDRsRdXABJwNDIWEewQyqFEoneJ0%207W%20lzgACE2AwZCowkMRmMJlMZsEFrNwj84P9AVhZgBqWYAFhe8lmRNu9xgFNmAA4XgBdbYEhl3egs150okkoGYFnsjnHU6xTxwOAAFScSBkEEy8QQAAUnGw8I5hqNxhVwqtEhs8YslpYtjslg0lnSTetkublnbuZb7csrjh6J6lrAaMEVC4ZEtJR8vhUDGQyME4CoAHLwkFgmQMYLBRSyCKgOCkXphdAIZG5YZ6zGG87p4LNDk%20DmKA0oVCRGFnECysyKNKg1w5tuxJP7eBICCYRzKEPj1BpjONmgxFUDCoAJXIy8bY2brcj6HlK4aswAamxQR1u080KIAMxvO8R2EVBMH4%20nhjnkA9sEAdlZ7Le9YPu2ACydyzAAgpgwTKgcE5IFOT7xPQcCjuO86LkY2boAAIjQY4JFAaEgE2-a7iA%206HieZ5dp%20l6oP%2097QmRz6UW%20H5frYNJ3u8dZMY%206AJnAADuswAKKaNBqJwQhAlISOY6OOoGHLjheGeDQhGKVupH8eRL5Ue%20NEcdo3FQtKT76WxRl0def73rx5noAiIT9MWLizMB2HST004gKBKgQVBMEaYpC49Jhch7nATgJAYTiWFpyQ6e2FGvtRKacaZQGDpZ6UXr2aCvNxgF8e2CIMJk2TBGwswJgAmt5vQVP5gWSbB6HhSp5HRbF8QJZuSUto5emsXltEFagXGMcNLFpYZGWFVlDkDhUSJjrIHngY1vmCSJ4mxsqDgdUuWHdTFdB9Yl27DalBnsXRkLFaVOWjfN%20VgqIdkActZG-PBmBqk4AUAMLyttT7CWJEmHaFymnfKPUXfFV3JbEt1WQtk1Zc9FmvfdE1FfZ9aKJ4yqquq-ZWDYFT4WMNCZP1IA1HACXnI%20iiTj5ADSLMVJzTUfFTMouDRMT0JcUZ3Izbi2KAARBDW6DhEJfIwA6AKiuGihEgAyiYssgPLKTnPCSIomixyG3Ak501hVW5LohZy4CCtRiLipk4DmrarqLQ-bpcANMoqLxkmVzouN3iFjuulDshqG1lmkWtupMbRVGbAxnGibJiTmexjK%20fZ2HZglcNxB4TQTBxiXEfSAwThQMLcqOKTKpe5T1ixJkgbjE4jiBzg-foAAhAa76UPzYoAD7T7MhRbgAFEsg%20HaH8IQH6XyeuPCCT-BPkAJS1tlFQV0Y1dwAAMhoNR18ijfNzRbfk04CCd9T6CdsEt9hILXcVB7sEPuA8g7DxAAvZIy9V4hxzuHLesId5jAnvXR%20lAvjH0Ag2EAyAnB3w-rEZQDxFCZG1O-YoxFtLoHPlXOMN8ZD4L8BA3o0UkCERoKQLIOQ8gdiVO3CmQ0OwAPQD-BhRCYCOC6D5cwhsXbGxAFIjY-RsxMIgDAJAn9iI0CQGQWQKR-APybgADRkYPcBu9KAWNQU3Sgh5KSL0dLifEvImQEGENyF4mCDENybg1ChZiKgWKsYYuAlBLAsgcTiM0%20IXjcmFBrLAbivEdngmQOAmATH%20LAYE5Be8LHJCcGkzAtjZgAFpZiRLWE4xYLj6BuI8ckgpRS-G5myegIJuTKBNPSWEspFTHHRMWLEnY8TSSYCSc0YmIAehQGTBQ-UWIZH4TYMzGRxl0AAGIoDbMtuImRPc4BBj5mMCRLQWjQiFhUMg2oyza10p2EujhSFsHIaAbITdpzDTFgRCOJFqGV0vrXJ53QjntO0uc2RgQciowzlndeVwJwMDUZ0fQ6ck79jzD5QslQf61HLAaWIFiAxBhDLMAAfLMWJixgBfB2BYr4Pg4nVhPtg6AIQ%20yCLIt8jSEAdaHDjK3YRIAmAw0bC8pAGgZF-Jwekn5wLDlFEjqXRQfC0lLPGDgNA14ABsTD7DqE0GgF4lBRAquRFJVAnhvBTJmXM3MLDh6gBVkyJZcjFafHhIyB4TD4BjNdVC91ozRSWwaFAfZILFVNCYZYMNFCDmgpAAlJhsynAyGiiuVQNAkVrJssmhu0hHVKr5mwDQICIULMrG8wMitQDrJAEJGAdBlWG08Csg2datk7IhZMPY6rtSrIoR2gQAAxYG2rgbDsmUw3B%20DBGXK-oHIiZElKdWzIoUtrD2GcNQPbHhtqEX%20IdTI8YDRPkgHjUUUAU9AlhROnICFQCa1Fs2ayKkf5WRbSYSEF2OaJogDjJkccTCRW5FEe2uiwq2DYBeZbNUvRrgJLPXWi4b8UhMLg5gPW7hB0PSpOWisBsmg4YmlCRNv6wSlOEGc-%20miT1LvuXQAV66HVsP6Nu3dih90Gx8unChdHw0KpkdetmHQH3VvI7EDZ15hAIhk15L9P9AgSYqE3I9wHRyHI0OBv9BhNXoaSAhv1xGwQetQzWfTvQsPaY%20rqphFbCMCdBaAa5yJNXoGdd6xQCB0zTmNQIaNynwR4bORcoVLnbnnrIVKqhMr1JQD-sxvurGOG2A49MmQsyD32pARQojtaHpMI8xIuNEaZHhbc-W1Wls2CVVyNOUpogAsULZQKossqeV8vZfKhNxksy1fSVqvDihfXBua-y2I3L4udaY8KmG4J0PieM5J0S2rh2smHZ%20iFM7o4WCFfxxLm62Ope4ZxjLdr0s5YsIu-1rs7AH16Og2ELIlg2hZFPSgxkFsZkCyADZVJwL-f%205bb9SmlsVAA0B-IGmwM-YQHcFQAqLOYEM6N-Lf6UPIHMyQpIVnAuiGCxiAlMi8vPteE1qtgmKHlYqCN4E06fNGsoAIfzZzlrzsNpYBA9Qax3PbMS4MPRyrQcGOlzL3Gj3NfUZ-NHJmoA0Eboj-w%20sbvyPe-z0lABeLXlKYnci4rBxbMvJMjrHROy2UB83xB%20zgEtam7MEeJ45y9IBqfuaq-T4BKv3UDOdPiUQHimeTMUKzCnTmXc3Iq7TyHOCGfNbdTTqJvuhlM%205KIKd5zdu0eu7z2I6uejA3NURDdSot3HdCHus7WWLu8au6ep3Qn7u%20Tz-er7T660NqbcDxTkUjcqZ4-3dToGtOw-h4r89BnEM-Yx2h7Hlnldg-BFRrMyg5dWC98cqclBm%20zC1xrnXQzU9B5APZx3JXKfOYjxUIrltvOe7jwGhPVTBmzH9zsPzR%20Q-ntK1Ty-6Ao839j2dgfz-0TzmGTwEEP2oywR8CAA.
如果单击节点,它们将切换(展开或折叠),使您可以看到树的特定分支。除非您尝试折叠顶级节点(区域),同时保持二级节点(区域)展开,否则此功能可以正常工作。在这种情况下,树将如下所示:
发生这种情况是因为我处理这种交互的方式:
- 当你点击一个节点时,
toggledNode
信号被触发,进而触发toggle
行动于expandedNodes
数据数组。 IE。通过单击一个节点,我可以将该节点添加到或删除到expandedNodes
数组(更准确地说,我们只用添加/删除一个简化的对象name
财产)
- Thus
expandedNodes
数据包含有关哪些节点的信息显式扩展。但它不知道这些展开的节点是否位于折叠的父节点内部。
- 然后,为了找出哪些节点实际上可见,我使用
visibleNodes
数据。我在那里申请filter
使用以下表达式进行变换:!datum.parent || indata('expandedNodes', 'name', datum.parent)
。 IE。我只检查上一级:节点的父节点是否存在于expandedNodes
array ,我认为该节点是可见的。
问题如下:我找不到任何方法可以跨多个级别扩展此功能。
也许我可以编写一些钩子来检查 2 或 3 个级别的相同条件,例如:
!datum.parent ||
indata('expandedNodes', 'name', datum.parent) &&
indata('expandedNodes', 'name', datum.myCustomFieldWithParentNode.parent) &&
indata('expandedNodes', 'name', datum.myCustomFieldWithParentNode.myCustomFieldWithParentNode.parent)
但对于这样一个简单的问题来说似乎太复杂了,而且这也不是最终的解决方案。理论上,一棵树可能包含几十个嵌套层:那该怎么办呢?
我在 Vega 中发现了一个有用的表达式:树祖先 https://vega.github.io/vega/docs/expressions/#treeAncestors。我可以轻松地用 JavaScript 编写一个解决方案,其中有循环和数组方法,例如.some()
and .every()
。但显然 Vega 不支持任何表达式来迭代数组。所以即使我可以获得树节点祖先的数组treeAncestors
函数,我无法用它做任何事情来验证所有祖先是否都已扩展。
要么我的方法是错误的,并且有人可以找到更好的算法来执行相同的操作,这不需要迭代数组(除了data
and indata
表达式) - 或者这是 Vega 当前的限制。