Сделайте два экземпляра d3.forceCollide() хорошими игроками
Я хочу два случая d3.forceCollide()
, В одном каждый узел отталкивается друг от друга, чтобы предотвратить перекрытие. Во втором только подмножество узлов отталкиваются друг от друга с гораздо большим радиусом.
Чтобы выполнить второе действие, я настраиваю метод initialize для фильтрации входящих узлов, например так:
function selective(force,filter){
var init = force.initialize;
force.initialize = function(_){return init(_.filter(filter));};
return force;
}
var dpi = 90; // approximate pixels per inch in SVG
var size = dpi * (1/4); // quarter-inch unit size
var universally_applied =
d3.forceCollide()
.radius(size)
.strength(1);
var selectively_applied =
selective(
d3.forceCollide(),
function(d){return d.id === color;}
)
.radius(size*5)
.strength(1);
}
Теперь это ПОЧТИ работает. Я создал скрипку, чтобы увидеть ее в действии: https://jsfiddle.net/jarrowwx/0dax43ue/38/ - каждый цветной круг должен отталкивать любой другой круг того же цвета на расстоянии. Любой другой цвет, он просто сталкивается и отталкивает его с пути.
Если я не изменю порядок, в котором определяются вещи, то избирательно приложенная сила применяется ТОЛЬКО к первому цвету (красному). Если я тасую data
Массив, прежде чем применять силы, трудно точно определить, что происходит, но сила применяется к некоторым кругам, а не к большинству других, даже среди одного цвета.
Есть идеи, что здесь происходит, или как это исправить?
1 ответ
Команда D3 решила, что это поведение было ошибкой ( Изоляция сил для подмножества узлов? # 72), и исправила ее. Исправление было включено в версию 1.0.4 d3-force, которая доступна как часть полной сборки D3 начиная с версии 4.4.0.
Проблема решается с помощью решения, предложенного "Частичные силы на узлах в D3.js", и код работает так, как задумано сейчас.