2014-01-14 2 views
1

Я строю что-то очень похожее на this. Мне бы хотелось сделать каждый узел либо его размером, как определено в json-файле, либо, если у него нет атрибута размера, а атрибут children в json - сумма всех его размеров. Как можно это сделать? Я пробовал различные методы, но не добавлял и не записывал их в JSON, что немного слабое, я не нашел ничего, что действительно сработало бы (любые предложения, hive mind?d3.js: размер родителей = сумма детей

ответ

6

Если ваши данные древовидную структуру, вы можете использовать Partition Layout для инициализации позиций и размеров узлов. d.value, возвращаемый разделом для родительских узлов, по умолчанию представляет собой сумму значений для всех дочерних узлов, если вы правильно настроили value accessor function для возврата переменной данных которые вы хотите использовать для размера для листовых узлов.

Хотя стандартный дисплей в partition examples должен иметь прямоугольники или дуги пространства вместо узлов и ссылок, он по-прежнему имеет все основные функции других макетов иерархии. Поэтому, как только вы запустите макет вашего корня, чтобы создать свой массив узлов, вы можете запустить links function для расчета ссылок.

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

В сумме:

var root = /*root object read from JSON data*/; 

var w,h; /*set appropriately */ 

var partition = d3.layout.partition() 
      .size([w,h]) 
      .value(function(d){return d.size;}) 
      .children(function(d){return d.children;}) 
        //optional: this is the default, change as needed 
      .sort(null); 
       //optional: turns off sorting, 
       //the default is to sort children by descending size 

var nodes = partition(root); 

var links = partition.links(nodes); 

initialize(); 

var force = d3.layout.force() 
      .nodes(nodes) 
      .links(links) 
      .size([w,h]) 
      /*and any other customization*/ 
      .start(); 

svg.on("tick", update); 

Одно замечание. Значение x, созданное разметкой разделов, предназначено для угла прямоугольника вместо центра круга. Поэтому, если вы разместите свои узлы на основе исходного значения x, вы в конечном итоге родите родителей в крайнем левом углу их детей. Если после этого вы будете запускать все через силовой макет, он будет сортироваться в конце концов, но вы можете сосредоточить их с самого начала, установив d.x = d.x + d.dx/2 и d.y = d.y + d.dy/2 на все ваши узлы во время инициализации (например, используя вызов .each() в вашем enter() цепь). И, конечно, используйте d.value для инициализации размера вашего узла (с соответствующим масштабом).

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