2015-12-18 4 views
2

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

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

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

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

+0

Я не совсем уверен, верно ли ваше утверждение о расстоянии, но я склонен сказать «да». Я уверен, однако, что, когда linkStrength становится меньше, края выполняются больше за счет заряда узлов и «силы тяжести» силовой диаграммы. Узлы привлекают или отталкивают друг друга, исходя из их заряда. –

ответ

8

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

Есть три силы, рассчитанные на каждой tick:

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

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

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

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

3. Charge. И наконец, рассчитываются взаимные силы узлов charges.

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

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

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

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

2

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

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

+0

Можете ли вы обновить этот синтаксис для v4? У меня есть связанный с этим вопрос: http://stackoverflow.com/questions/39244186/how-do-you-set-a-fixed-link-distance-with-d3-v4?noredirect1_comment65826858_39244186 – dcsan