Я сделал разборную древовидную диаграмму в d3 (v5), упрощенную версию которой можно найти здесь: https://jsfiddle.net/philipnye/cwj9nkhr/.
Каждый узел имеет метку, но метки отображаются только там, где естьдостаточно места, чтобы они не перекрывали друг друга или не подходили слишком близко к краю SVG.В связанном примере при первой загрузке метки появляются только для первых двух глубин древовидной диаграммы.
requiredSpacing
используется для приблизительного определения необходимого пространства, а minSpacing
проверяет минимальный существующий интервалмежду узлами на каждой глубине.
Следующие строки располагают узлы и метки с эффектом перехода:
var nodeUpdate=nodeEnter.merge(node)
.transition()
.duration(function() {
if (loaded==0) {
return 0;
}
else {
return duration;
}
})
.attr("transform", function(d) {
return "translate(" + d.x + "," + d.y + ")";
});
nodeUpdate.select("circle")
.attr("r", function(d) {
return radiuses[d.depth];
})
.attr("class", function(d) {
if (d._children) {
return "filled";
} else {
return "unfilled";
}
});
nodeUpdate.select("text")
.style("fill-opacity", function(d) {
if (minSpacing[d.depth]<requiredSpacing[d.depth]*2 || (d.data.position=='left' && Math.ceil(d.x/5)*5-radiuses[d.depth]-requiredSpacing[d.depth]<margin.left) || (d.data.position=='right' && Math.ceil(d.x/5)*5+radiuses[d.depth]+requiredSpacing[d.depth]>width)) {
return 1e-6;
}
else {
return 1;
}
})
.attr("class", function(d) {
if (minSpacing[d.depth]<requiredSpacing[d.depth]*2 || (d.data.position=='left' && Math.ceil(d.x/5)*5-radiuses[d.depth]-requiredSpacing[d.depth]<margin.left) || (d.data.position=='right' && Math.ceil(d.x/5)*5+radiuses[d.depth]+requiredSpacing[d.depth]>width)) {
return "nodeLabel nonselectable";
}
else {
return "nodeLabel";
}
})
Я устанавливаю непрозрачность меток, для которых нет места для показа1e-6 (для включения перехода) и присвойте им класс nonselectable
, что означает, что метки не могут быть выбраны.Но я на самом деле не удаляю их - и у меня возникает проблема, заключающаяся в том, что в некоторых случаях они перекрывают узлы и означают, что нельзя щелкать узлы, чтобы развернуть / свернуть дерево ниже этой точки.Посмотрите на узлы на два или три уровня глубже, чем те, которые обозначены как мужской и женский - только на расстоянии от трети до половины узлов можно щелкнуть.(Обратите внимание, что узлы в слое bottom нельзя развернуть / свернуть, так как у них нет дочерних узлов.)
Как мне лучше удалить эти метки или, по крайней мере, остановить их, чтобы предотвратить васот щелчка по узлам?
Вещи, которые я рассмотрел:
- Изменение порядка прорисовки может предположительно поставить метки «позади» узлов - но я думаю, что это потребует существенной переделкикода, и я не знаю, как
- Предположительно, было бы возможно впоследствии пройти и удалить узлы с классом
nonselectable
, но это не самый эффективный подход, и яУ меня были некоторые проблемы при попытке реализовать это - Я думаю, что смещение меток куда-то за пределы размеров SVG может работать - хотя я не уверен, как бы я справился с этим с переходом, так чтопользователи не видят
- Установка
font-size
близко к нулю.Я попытался прикрепить что-то вроде приведенного ниже кода к своему nodeUpdate
коду, но, похоже, это вызвало проблемы с переходом
.attr("font-size", function(d) {
if (minSpacing[d.depth]<requiredSpacing[d.depth]*2 || (d.data.position=='left' && Math.ceil(d.x/5)*5-radiuses[d.depth]-requiredSpacing[d.depth]<margin.left) || (d.data.position=='right' && Math.ceil(d.x/5)*5+radiuses[d.depth]+requiredSpacing[d.depth]>width)) {
return '0.1em';
}
})
Или может быть другой, лучший способ решения этой проблемы.
Как мне это сделать?