显示基于根节点和给定级别深度的子图

时间:2019-04-21 09:28:51

标签: javascript d3.js force-layout

我对js和D3都是陌生的。用谷歌搜索了很多,没有答案。

一个简单的问题:我有一个图,我想隐藏除子图以外的所有东西,该子图的根是(初始图的)给定节点,而深度是给定数字。根节点名称和深度都由输入框(未通过GUI选择)给出。

首先,我构建一个拓扑(以了解是否已连接节点):

  // build node topology

  var node_topo = {};
  for (const [key, value] of Object.entries(graph.links)) {
    node_topo[value.source.name + "," + value.target.name] = true;
  }

  function is_connected(a, b) {
    return node_topo[a.name + "," + b.name] || node_topo[b.name + "," + a.name] || a.name == b.name;
  }

然后,我尝试显示一个子图:

  function show_node_subgraph() {
    var node = d3.select("#subgraph_input").node();
    var node_name = node.value;
    var nb_lvl = d3.select("#subgraph_lvl_input").node().value;

    // back to full graph

    if (!node_name) {
      nodes.style("visibility", "visible");
      links.style("visibility", "visible");
      return;
    }

    // hide all but root node

    nodes.style("visibility", function(d) {
                                if (d.name == node_name) return "visible";
                                return "hidden";
                              });
    links.style("visibility", "hidden");

    // then, add levels

    visible_nodes = new Set();
    visible_nodes.add(node);

    for (let lvl = 0; lvl < nb_lvl; lvl++) {
      links.each(function(d) {
                   // show each node of the link if already connected to a visible node
                   // Does not work !...

                   nodes.filter(function(o, i) {return i == d.source.index;}) // keep only link source
                        .filter(function(o) { // keep only if connected to visible node
                                  for (let vn in visible_nodes) {
                                    if (is_connected(vn, o)) return true;
                                  };
                                  return false;
                                })
                        .style("visibility", "visible");

                   nodes.filter(function(o, i) {return i == d.target.index;}) // keep only link source
                        .filter(function(o) { // keep only if connected to visible node
                                  for (let vn in visible_nodes) {
                                    if (is_connected(vn, o)) return true;
                                  };
                                  return false;
                                })
                        .style("visibility", "visible");

                   // show link only if both nodes are visible

                   // How to do this ??
                 });
    };
  };
  d3.select("#subgraph_input").on("keypress", show_node_subgraph);
  d3.select("#subgraph_lvl_input").on("keypress", show_node_subgraph);

不确定在回调中要了解如何从“回调数据”中检索“链接的节点”(我的理解是回调参数是“数据”,而不是“对象”,如节点或链接)。

算法很简单:如果连接到已经可见的节点,则仅显示节点,然后仅当源节点和目标节点均可见时,才显示链接。

我为此感到挣扎,因为我觉得我对数据结构不够了解...主要是因为我不了解如何从“数据”传递到“对象”(似乎这些是不同的东西?)

如果有人可以帮助,那就太好了……

0 个答案:

没有答案