2016-03-17 6 views
0

Я анализирую расстояние связи для каждой ссылки в строке json.Поддерживает динамическое расстояние между узлами, находящимися в силе. D3.js

{ 
    "nodes" : [ { 
    "name" : "cricket", 
    "category" : "main", 
    "id" : 0 
    }, { 
    "name" : "record1", 
    "category" : "twitter", 
    "id" : 1 
    }, { 
    "name" : "record2", 
    "category" : "web", 
    "id" : 2 
    }], 
    "links" : [ { 
    "source" : 0, 
    "target" : 1, 
    "linkDistance" : 13.17538 
    }, { 
    "source" : 0, 
    "target" : 2, 
    "linkDistance" : 13.17538 
    } ] 
} 

В javascript ссылка дана как функция.

var force = d3.layout.force() 
    .gravity(0.3) 
    .charge(0) 
    .size([width,height]) 
    .nodes(jsonstring.nodes) 
    .links(jsonstring.links) 
    .linkDistance(function (d) { 
      return d.linkDistance; 
    }) 
    .start(); 

Но узлы не рисуют на данном расстоянии ссылки. Зарядное значение равно 0. Есть ли у кого-нибудь представление о том, как поддерживать динамические расстояния между линиями, когда он анализируется через json?

+0

Настройте скрипку, чтобы мы могли посмотреть – thatOneGuy

+0

Расстояние ссылки в макете силы D3 лучше всего рассматривать как желание, а не ограничение. Он учитывается при расчете сил, но он не гарантированно имеет эту точную длину и, скорее всего, будет в некоторой степени отличаться. Для объяснения см. Мой [ответ] (/ a/34376334/4235784) на другой вопрос. – altocumulus

ответ

0

Каждый раз, когда ваш d.linkDistance редактируется, вам нужно позвонить еще раз

force.linkDistance(function (d) { 
     return d.linkDistance; 
}) 

для изменения вступили в силу.

Также помните, что расстояние связи очень слабо соблюдается в d3, так что по моему опыту редактирование расстояния ссылки не оказывает большого влияния на график. Вы всегда можете попробовать force.linkStrength(10) или более высокие значения, чтобы увеличить важность вашего расстояния, но этого может быть недостаточно, чтобы точно правильные значения.


Что попробовать:

  • найти spanning tree вашего графа (это дает список ребер, являющихся «скелет» st)

  • Выполните следующие действия для обеспечения соблюдения края длина верна:

    force.on('tick', function() { 
        //consider all edges of a spanning tree, from root to leaves 
        //using links directly instead of st would yield strange results, but depending on your data it might work well enough 
        st.forEach(function(d) { 
         //compute link coordinates 
         var dx = d.target.x - d.source.x; 
         var dy = d.target.y - d.source.y; 
         //ratio desired length/actual length 
         var r = d.linkDistance/Math.sqrt(dx*dx+dy*dy) 
         //add r=Math.sqrt(r) for something smoother (but less constrained) 
         //move target to desired length 
         d.target.x = d.source.x + dx * r; 
         d.target.y = d.source.y + dy * r; 
    
        }) 
    }) 
    

Это плохо ухудшит естественный поток макета силы (возможно, немного меньше с r=Math.sqrt(r), но все же), и это испортит перетаскивание узла, если вы его используете, но при необходимости оно должно обеспечить некоторую длину дуги.

+0

Поблагодарите laurent за ваш ответ. Я отредактировал строку json, чтобы это ясно объяснить. Моя проблема в том, что, поскольку вы можете видеть, что 3 узла с двумя ссылками (0 ---> 1) и (0 ---> 2) имеют ** такое же расстояние связи ** (13.17538). Но он не рисует на одном расстоянии. –

+0

См. Мое редактирование, вы можете увеличить силу связи, чтобы попытаться получить аналогичные расстояния (или уменьшить другие параметры: заряд и гравитация), но в любом случае d3 не гарантирует, что расстояние связи должно быть правильным. – tarulen

+0

Спасибо, laurent. Можете ли вы предложить любую другую библиотеку, которая соответствует моим требованиям? –

Смежные вопросы