D3 дерево вертикальное разделение

Я использую макет дерева D3, такой как этот:http://mbostock.github.com/d3/talk/20111018/tree.html

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

Я попытался изменить алгоритм разделения, чтобы он работал:

.separation(function (a, b) {
    return (a.parent == b.parent ? 1 : 2) / a.depth;
})

Это нет работа. Я также попытался вычислить, на какой глубине больше всего детей, а затем указать высоту сцены, которая будетchildren * spaceBetweenNodes, Это приблизило меня, но все еще не было точным.

depthCounts = [];
nodes.forEach(function(d, i) { 
    d.y = d.depth * 180;

    if(!depthCounts[d.depth])
        depthCounts[d.depth] = 0;

    if(d.children)
    {
        depthCounts[d.depth] += d.children.length;
    }
});

tree_resize(largest_depth(depthCounts) * spaceBetweenNodes);

Я также пытался изменить узелx значение тоже в методе ниже, где он рассчитываетy расставание, но без сигары. Я бы тоже опубликовал это изменение, но я удалил его из своего кода.

nodes.forEach(function(d, i) { 
    d.y = d.depth * 180;
});

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

Ответы на вопрос(4)

Решение Вопроса

используя только

tree.nodeSize([height, width])

https://github.com/mbostock/d3/wiki/Tree-Layout#nodeSize

Справочник по API немного скуден, но работает довольно просто. Обязательно используйте его послеtree.size([height, width]) иначе вы снова будете переопределять свои ценности.

Для получения дополнительной информации:Разделение структуры дерева D3 между узлами с использованием NodeSize

 Ajay Reddy15 нояб. 2016 г., 15:54
Спасибо, добрый сэр!! :)

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

Во всяком случае, я просто хотел обновить это для людей, использующих последний файл d3.v3.js. (Я предполагаю, что это из-за новой версии, потому что ссылки на строки в принятом ответе были для меня неправильными.)

Редактируемая функция d3.layout.tree находится между строками 6236 и 6345. d3_layout_treeVisitAfter запускается в строке 6318. Переменная иерархии объявляется в строке 6237. Немного о tree.elementsize все еще остается - я поместил его в строку 6343.

И наконец (я предполагаю, что это ошибка): когда вы создаете дерево, поместите размеры в квадратные скобки, как вы это обычно делаете с "размер", Так:

var tree = d3.layout.tree()
         .size(null)
         .elementsize([50, 240]);
 patorjk26 авг. 2014 г., 15:51
Если ты'Вы используете версию 3, вы не должнынужно внести изменения. Там'Уже есть свойство nodeSize, которое можно использовать вместо elementize.

смог найти пост. Решение требует, чтобы вы модифицировали D3.js в одном месте, что не рекомендуется, но это был единственный способ обойти эту проблему, которую я смог найти.

Начиная вокруг линии5724 или этот метод:d3_layout_treeVisitAfter

менять:

d3_layout_treeVisitAfter(root, function(node) {
    node.x = (node.x - x0) / (x1 - x0) * size[0];
    node.y = node.depth / y1 * size[1];
    delete node._tree;
});

чтобы:

d3_layout_treeVisitAfter(root, function(node) {
    // make sure size is null, we will make it null when we create the tree
    if(size === undefined || size == null) 
    { 
        node.x = (node.x - x0) * elementsize[0]; 
        node.y = node.depth * elementsize[1]; 
    } 
    else 
    { 
        node.x = (node.x - x0) / (x1 - x0) * size[0];
        node.y = node.depth / y1 * size[1]; 
    } 
    delete node._tree;
});

Ниже добавьте новую переменную с именем:elementsize и по умолчанию это[ 1, 1 ] на линию 5731

var hierarchy = d3.layout.hierarchy().sort(null).value(null)
    , separation = d3_layout_treeSeparation
    , elementsize = [ 1, 1 ] // Right here
    , size = [ 1, 1 ];

Ниже, что есть метод с именемtree.size = function(x), Добавьте следующее определение ниже:

tree.elementsize = function(x) {
    if (!arguments.length) return elementsize;
    elementsize = x;
    return tree;
};

Наконец, когда вы создаете дерево, вы можете изменитьelementsize вот так

var tree = d3.layout.tree()
             .size(null)
             .elementsize(50, 240);
 Biovisualize28 мая 2013 г., 07:40
Вот ссылка на группы Google для получения дополнительной информацииgroups.google.com/forum/?fromgroups#!topic/d3-js/7Js0dGrnyek
 patorjk26 авг. 2014 г., 15:49
В d3 версии 3 естьТеперь свойство nodeSize будет выполнять то же самое, что и вышеуказанная модификация. Ref:github.com/mbostock/d3/wiki/Tree-Layout#nodeSize

которое вы предложили, будет работать, вам просто нужно убедиться, что вы делаете это после добавления всего на холст. d3 пересчитывает раскладку каждый раз при входе, выходе, добавлении и т. д.Сделав все это, вы можете поиграть с d.y, чтобы зафиксировать глубину.

nodes.forEach(function(d) { d.y = d.depth * fixdepth});

Ваш ответ на вопрос