繁体   English   中英

在 d3.js v4 中以编程方式打开嵌套、折叠(隐藏)节点

[英]Programmatically open nested, collapsed (hidden) nodes in d3.js v4

我正在尝试以编程方式在可折叠树中打开 d3.js 节点:

d3_collapsible_tree_viz

我使用以下 d3.js 片段(在第二级之后折叠节点)加载数据,

d3.json("js/ontology.json", function(error, treeData) {
  if (error) throw error;
  root = d3.hierarchy(treeData, function(d) { return d.children; });
  root.x0 = height / 2;
  root.y0 = 0;
  // Collapse after the second level:
  root.children.forEach(collapse);
  update(root);
});

然后我使用下面的 d3.js 代码

var nodeEnter = node.enter().append('g')
    .attr('class', 'node')
    .attr('node-name', d => d.data.name.toLowerCase())
    .attr("transform", function(d) {
      return "translate(" + source.y0 + "," + source.x0 + ")";
  })
.on('click', click);

还有这个 function

function expandNode() {
  const node = d3.select('.node[node-name="Nature"]').node();
  console.log('NODE: ', node);
  node.dispatchEvent(new Event('click'));
  }
expandNode();

以编程方式打开“自然”节点。

但是,当我用“地球”(“自然”的嵌套子节点,不可见)替换“自然”(可见节点)时,这个表达式

const node = d3.select('.node[node-name="Earth"]').node();

只有当它可见时才会展开“地球”节点。

如果“地球”不可见,该语句将不会扩展“自然”以显示“地球”(并随后扩展“地球”)。

建议?


编辑 1.这与我之前的 StackOverflow 问题密切相关,

以编程方式打开 d3.js v4 可折叠树节点?

如果需要,请参考那里引用的 JSFiddle,

https://jsfiddle.net/vstuart/acx5zfgn/62/

标签不同,但数据和代码相似。


编辑 2.后续问题

访问 d3.js v6 中的承诺数据 [以编程方式打开嵌套的折叠节点]

关系到:

  • d3.js v6;
  • 通过 d3.js 回调/承诺加载外部 JSON 数据;
  • 这个问题,在那个更新的上下文中。

本体.json

{ "name": "Root",
  "children": [
    { "name": "Culture",
      "children": [
        { "name": "LGBT" }
      ]
    },

    { "name": "Nature",
      "id": "nature",
      "children": [
        { "name": "Earth",
          "id": "earth",
          "children": [
            { "name": "Environment" },
            { "name": "Geography" },
            { "name": "Geology" },
            { "name": "Geopolitical" },
            { "name": "Geopolitical - Countries" },
            { "name": "Geopolitical - Countries - Canada" },
            { "name": "Geopolitical - Countries - United States" },
            { "name": "Nature" },
            { "name": "Regions" }
          ]
        },
        { "name": "Cosmos" },
        { "name": "Outer space" }
      ]
    },

    { "name": "Humanities",
      "children": [
          { "name": "History" },
          { "name": "Philosophy" },
          { "name": "Philosophy - Theology" }
      ]
    },

    { "name": "Miscellaneous",
      "children": [
          { "name": "Wikipedia",
            "url": "https://wikipedia.com" },
          { "name": "Example.com",
            "url": "https://example.com" }
      ]
    },
      
    { "name": "Science",
      "children": [
          { "name": "Biology" },
          { "name": "Health" },
          { "name": "Health - Medicine" },
          { "name": "Sociology" }
      ]
    },

    { "name": "Technology",
      "children": [
            { "name": "Computers" },
            { "name": "Computers - Hardware" },
            { "name": "Computers - Software" },
            { "name": "Computing" },
            { "name": "Computing - Programming" },
            { "name": "Internet" },
            { "name": "Space" },
          { "name": "Transportation" }
      ]
    },

  { "name": "Society",
      "children": [
            { "name": "Business" },
            { "name": "Economics" },
            { "name": "Economics - Business" },
            { "name": "Economics - Capitalism" },
            { "name": "Economics - Commerce" },
            { "name": "Economics - Finance" },
            { "name": "Politics" },
          { "name": "Public services" }
      ]
    }
  ]
}

您需要递归地发现节点祖先,然后将它们扩展一:

const findNodeAncestors = (root, name) => {
  if (root.name === name) {
    return [name];
  }

  if (root.children) {
    for (let i = 0; i < root.children.length; i++) {
      const chain = findNodeAncestors(root.children[i], name);
      if (chain) {
        chain.push(root.name);
        return chain;
      }
    }
  }
  return null;
}; 
   

const chain = findNodeAncestors(treeData.data, 'Earth');
  
for (let i = chain.length - 1; i >= 0; i--) {
  const node = d3.select(`.node[node-name="${chain[i]}"]`);
  const nodeData = node.datum();
  if (!nodeData.children && nodeData.data.children) {  // Node has children and collapsed
    node.node().dispatchEvent(new Event('click'));     // Expand the node
  }
}

看到它在小提琴中工作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM