Я новичок в 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);
Не уверен, в обратных вызовах, чтобы понять, как извлечь "узел ссылки" из "данных обратного вызова" (я понимаю, что аргументы обратного вызова являются "данными", ноне «объекты», такие как узлы или ссылки).
Алгоритм прост: показывать только узлы, если он подключен к уже видимому узлу, а затем показывать ссылку только в том случае, если видны как исходный, так и целевой узлы.
Я борюсь с этим, потому что чувствую, что недостаточно разбираюсь в структуре данных ... В основном потому, что не понимаю, как перейти от «данных» к «объектам» (кажется, это разные вещи?)
Если кто-то может помочь, было бы здорово ...