简体   繁体   English

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

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

I am trying to programmatically open d3.js nodes in a collapsible tree:我正在尝试以编程方式在可折叠树中打开 d3.js 节点:

d3_collapsible_tree_viz

I load the data with the following d3.js snippet (which collapses the nodes after the second level),我使用以下 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);
});

I then use the following d3.js code然后我使用下面的 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);

and this function还有这个 function

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

to programmatically open the "Nature" node.以编程方式打开“自然”节点。

However, when I substitute "Nature" (visible node) with "Earth" (nested child of "Nature", not visible) this expression但是,当我用“地球”(“自然”的嵌套子节点,不可见)替换“自然”(可见节点)时,这个表达式

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

will expand the "Earth" node only if it is visible.只有当它可见时才会展开“地球”节点。

That statement will not expand "Nature" to show "Earth" (and subsequently expand "Earth") if "Earth" is not visible.如果“地球”不可见,该语句将不会扩展“自然”以显示“地球”(并随后扩展“地球”)。

Suggestions?建议?


Edit 1. This is closely related to my earlier StackOverflow question,编辑 1.这与我之前的 StackOverflow 问题密切相关,

Programmatically opening d3.js v4 collapsible tree nodes? 以编程方式打开 d3.js v4 可折叠树节点?

If needed, please refer to the JSFiddle referenced there,如果需要,请参考那里引用的 JSFiddle,

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

The labels are different but otherwise the data and code are similar.标签不同,但数据和代码相似。


Edit 2. Follow-on question编辑 2.后续问题

Accessing promised data in d3.js v6 [programmatically opening nested collapsed nodes] 访问 d3.js v6 中的承诺数据 [以编程方式打开嵌套的折叠节点]

relating to:关系到:

  • d3.js v6; d3.js v6;
  • loading external JSON data via d3.js callback/promise;通过 d3.js 回调/承诺加载外部 JSON 数据;
  • this question, in that updated context.这个问题,在那个更新的上下文中。

ontology.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" }
      ]
    }
  ]
}

You need to discover the node ancestors recursively and then expand them on by one:您需要递归地发现节点祖先,然后将它们扩展一:

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
  }
}

See it's working in a fiddle .看到它在小提琴中工作。

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

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