D3 tree vertical separation

前端 未结 4 504
时光说笑
时光说笑 2020-12-30 08:03

I am using the D3 tree layout, such as this one: http://mbostock.github.com/d3/talk/20111018/tree.html

I have modified it for my needs and am running into an issue.

相关标签:
4条回答
  • 2020-12-30 08:43

    The original fix you proposed will work, you just have to make sure you do it after you add everything to the canvas. d3 recalculates the layout each time you enter, exit, append, etc. Once you've done all that, then you can fiddle with the d.y to fix the depth.

    nodes.forEach(function(d) { d.y = d.depth * fixdepth});
    
    0 讨论(0)
  • 2020-12-30 08:44

    I know I'm not supposed to respond to other answers, but I don't have enough reputation to add a comment.

    Anyway, I just wanted to update this for people using the latest d3.v3.js file. (I assume this is because of a new version, because the line references in the accepted answer were wrong for me.)

    The d3.layout.tree function that you are editing is found between lines 6236 and 6345. d3_layout_treeVisitAfter starts on line 6318. The hierarchy variable is declared on line 6237. The bit about tree.elementsize still stands - I put it on line 6343.

    Lastly (I assume this was an error): when you create the tree, put the dimensions inside square brackets, like you normally do with "size". So:

    var tree = d3.layout.tree()
             .size(null)
             .elementsize([50, 240]);
    
    0 讨论(0)
  • 2020-12-30 08:56

    As of 2016, I was able to achieve this using just

    tree.nodeSize([height, width])
    

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

    The API Reference is a bit poor, but is works pretty straight forward. Be sure to use it after tree.size([height, width]) or else you will be overriding your values again.

    For more reference: D3 Tree Layout Separation Between Nodes using NodeSize

    0 讨论(0)
  • 2020-12-30 09:04

    I was able to figure this out with help from a user on Google Groups. I was not able to find the post. The solution requires you to modify D3.js in one spot, which is not recommended but it was the only to get around this issue that I could find.

    Starting around line 5724 or this method: d3_layout_treeVisitAfter

    change:

    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;
    });
    

    to:

    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;
    });
    

    Below add a new variable called: elementsize and default it to [ 1, 1 ] to line 5731

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

    Below that there is a method called tree.size = function(x). Add the following below that definition:

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

    Finally when you create the tree you can change the elementsize like so

    var tree = d3.layout.tree()
                 .size(null)
                 .elementsize(50, 240);
    
    0 讨论(0)
提交回复
热议问题