показать подграф на основе корневого узла и заданной глубины уровня - PullRequest
0 голосов
/ 21 апреля 2019

Я новичок в 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);

Не уверен, в обратных вызовах, чтобы понять, как извлечь "узел ссылки" из "данных обратного вызова" (я понимаю, что аргументы обратного вызова являются "данными", ноне «объекты», такие как узлы или ссылки).

Алгоритм прост: показывать только узлы, если он подключен к уже видимому узлу, а затем показывать ссылку только в том случае, если видны как исходный, так и целевой узлы.

Я борюсь с этим, потому что чувствую, что недостаточно разбираюсь в структуре данных ... В основном потому, что не понимаю, как перейти от «данных» к «объектам» (кажется, это разные вещи?)

Если кто-то может помочь, было бы здорово ...

...