D3.js packed circle layout - how to adjust child radius

前端 未结 2 1404
梦谈多话
梦谈多话 2021-01-15 15:32

I am currently useing d3\'s packed cicle layout(this) and have noticed that when a parent only has one child, the radius of the child is the same as the parents.

Is

相关标签:
2条回答
  • 2021-01-15 15:37

    I haven't looked at v3 of D3, but v4 has pack.padding() method that you can specify the amount of padding to include.

    See the example image, the circle on the right is a solo child.

    0 讨论(0)
  • 2021-01-15 15:45

    I took a stab at it and managed to solve the issue. Might not be optimal but hey, it works. =)

    this.calculateLayout = function( dim, tree ) {
    
        var packlayout = d3.layout.pack()
            .size( [dim, dim] )
            .padding( 80 )
            .sort( d3.descending )
            .value( function( d ) { return 150 } );
    
        addPlaceholders(tree);
    
        var nodes = packlayout( tree );
    
        removePlaceholders(nodes);
    
        centerNodes( nodes );
    
        makePositionsRelativeToZero( nodes );
    
        return nodes;
    };
    
    function addPlaceholders( node ) {
    
        if(node.children) {
    
            for( var i = 0; i < node.children.length; i++ ) {
    
                var child = node.children[i];
                addPlaceholders( child );
            }
    
            if(node.children.length === 1) {
    
                node.children.push({ name:'placeholder', children: [ { name:'placeholder', children:[] }] });
            }
        }
    };
    
    function removePlaceholders( nodes ) {
    
        for( var i = nodes.length - 1; i >= 0; i-- ) {
    
            var node = nodes[i];
    
            if( node.name === 'placeholder' ) {
    
                nodes.splice(i,1);
            } else {
    
                if( node.children ) {
    
                    removePlaceholders( node.children );
                }
            }
        }
    };
    
    function centerNodes( nodes ) {
    
        for( var i = 0; i < nodes.length; i ++ ) {
    
            var node = nodes[i];
    
            if( node.children ) {
    
                if( node.children.length === 1) {
    
                    var offset = node.x - node.children[0].x;
                    node.children[0].x += offset;
                    reposition(node.children[0],offset);
                }
            }
        }
    
        function reposition( node, offset ) {
    
            if(node.children) {
                for( var i = 0; i < node.children.length; i++ ) {
    
                    node.children[i].x += offset;
                    reposition( node.children[i], offset );
                }
            }
        };
    };
    
    function makePositionsRelativeToZero( nodes ) {
    
        //use this to have vis centered at 0,0,0 (easier for positioning)
        var offsetX = nodes[0].x;
        var offsetY = nodes[0].y;
    
        for( var i = 0; i < nodes.length; i ++ ) {
    
            var node = nodes[i];
    
            node.x -= offsetX;
            node.y -= offsetY;
        }
    };
    
    0 讨论(0)
提交回复
热议问题