d3.js linkStrength влияет на linkDistance в графе сил

Я работаю над графиком, чтобы показать отношения между различными узлами. Чем ближе связаны узлы (согласно бизнес-логике), тем ближе должны быть узлы.

Я заметил, что некоторые ссылки с linkStrength из .1 короче (это то, что я хотел достичь), и некоторые другие с такой же силой длиннее, чем те, с linkStength из 1, Из документации о параметрах силового макета я нашел следующую цитату:

Значение linkStrength по умолчанию равно 1,0, что сохраняет полный эффект linkDistance. Однако, установив значение linkStrength меньше 1, ограничение по расстоянию можно ослабить.

Означает ли это, что если бы я должен был установить linkDistance в 150ссылки с linkStrength(1.0) будет ближе к 150, чем те, с linkStrength(.1)? И если да, нужно ли им быть короче, длиннее или это не имеет значения вообще? Потому что я был немного удивлен макетом.

2 ответа

Решение

Короче говоря: при использовании форс-макета D3 нет встроенного способа обеспечить фиксированную длину ссылок. Макет силы по своей природе является динамическим и устанавливает значения для force.linkDistance() и force.linkStrength() представляет просто еще одну силу для набора вычислений, выполняемых на каждой итерации, то есть для каждого тика во время выполнения макета силы.

На каждый тик рассчитаны три силы:

1. Длина ссылки. Первая сила, которая будет рассчитана, - это корректировка длин звеньев, установленная с помощью вышеупомянутых методов. Это делается в цикле для каждой ссылки, и, глядя на источник, все сводится к одной строке кода:

l = alpha * strengths[i] * ((l = Math.sqrt(l)) - distances[i]) / l;

С l рассчитывается как евклидово расстояние между узлом источника и целевым узлом, желаемое расстояние связи distances[i] и ссылка strengths[i] эта строка определяет, как объединить оба узла или раздвинуть их, чтобы приблизить расстояние между соединениями, установленное через force.linkDistance(), Легко видеть, что сила связи линейно влияет на результирующую силу. В отличие от документации API, которая определяет допустимый диапазон прочности в интервале [0,1], исходный код не накладывает никаких ограничений на значение, установленное force.linkStrength(),

2. Гравитация. Вторая сила, которая будет рассчитана, будет учитывать гравитационные силы на каждом узле.

3. Зарядка. Наконец, рассчитываются взаимные силы зарядов узлов.

Поскольку эффекты всех вычисленных сил накладываются и будут суммироваться с результирующим движением каждого узла для данного тика, становится ясно, что длина связи составляет только одну часть всего вычисления. Две другие силы могут ослабить или даже обратить вспять свой эффект.

Что касается вашего вопроса

Означает ли это, что если бы я должен был установить linkDistance на 150, ссылки с linkStrength(1.0) будут ближе к 150, чем ссылки с linkStrength(.1)?

Результат во многом зависит от настройки параметров силового макета и распределения узлов, и до сих пор не дано никаких гарантий относительно окончательной длины ссылок.

Сила связи задает жесткость связей, а не расстояние между узлами ( силовой макет документа). Расстояние узлов друг от друга контролируется их зарядом. Вы можете сделать заряд узла динамическим, например, так:

var force = d3.layout.force()
        .nodes(nodes)
        .theta(0.1)
        .charge(function (d) {
            return -(d.radius * d.radius * 0.125);
        })
        .gravity(0.1)
        .size([width, height])
        .on("tick", tick)
        .start();

Рабочий пример, который использует эту технику: vizz.ly

Другие вопросы по тегам