Ошибка в том, что вы выбираете объекты данных (d.source и d.target), а не элементы DOM, связанные с этими объектами данных.
У вас есть работающая подсветка строк, но я бы, вероятно, объединил ваш код в одну итерацию, например:
link.style("opacity", function(o) {
return o.source === d || o.target === d ? 1 : opacity;
});
Подсветить соседние узлы сложнее, потому что нужно знать соседей для каждого узла. Эту информацию не так просто определить с вашими текущими структурами данных, поскольку все, что у вас есть в виде массива узлов и массива ссылок. Забудьте DOM на секунду и спросите себя, как бы вы определили, являются ли два узла a
и b
соседями?
function neighboring(a, b) {
// ???
}
Дорогой способ сделать это - перебрать все ссылки и посмотреть, есть ли ссылка, соединяющая a и b:
function neighboring(a, b) {
return links.some(function(d) {
return (d.source === a && d.target === b)
|| (d.source === b && d.target === a);
});
}
(Предполагается, что ссылки не являются ненаправленными. Если вы хотите выделить только соседних по прямой связи, то исключите вторую половину ИЛИ.)
Более эффективный способ вычисления этого, если вам приходится делать это часто, - это иметь карту или матрицу, которая позволяет осуществлять поиск в постоянном времени, чтобы проверить, являются ли a и b соседями. Например:
var linkedByIndex = {};
links.forEach(function(d) {
linkedByIndex[d.source.index + "," + d.target.index] = 1;
});
Теперь вы можете сказать:
function neighboring(a, b) {
return linkedByIndex[a.index + "," + b.index];
}
И, таким образом, теперь вы можете перебирать узлы и корректно обновлять их непрозрачность:
node.style("opacity", function(o) {
return neighboring(d, o) ? 1 : opacity;
});
(Вы также можете захотеть создать особый случай самой ссылки с указанием мыши, либо установив собственную ссылку для каждого узла в linkedByIndex
, либо протестировав d
непосредственно при вычислении стиля, либо с помощью! важный стиль CSS :hover
.
Последнее, что я хотел бы изменить в вашем коде, - это использовать непрозрачность заполнения и непрозрачность обводки, а не непрозрачность, поскольку они обеспечивают гораздо лучшую производительность.