d3.js双层分区v4 - 更改子项和值函数

时间:2017-06-29 14:19:26

标签: javascript d3.js svg

我目前正在更新此处链接(https://bl.ocks.org/mbostock/5944371)的双层分区示例,以使用d3.js版本4而不是版本3.现在我不担心放大和缩小,仅关注仅显示深度为2且具有正确值的弧。我有一个工作的JSFiddle,其中显示了所有弧(https://jsfiddle.net/andrewsolis/dgu8Lgpf/)以及下面相同的代码:

<!--

    Attempt at converting bilevelpartition to v4

 -->

<!DOCTYPE html>
<meta charset="utf-8">
<style>

circle,
path {
  cursor: pointer;
}

circle {
  fill: none;
  pointer-events: all;
}

</style>
<body>
</body>
<!-- d3.js library -->
<script src="https://d3js.org/d3.v4.min.js"></script>
<!-- jQuery library -->
<script
  src="https://code.jquery.com/jquery-3.2.1.min.js"
  integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4="
  crossorigin="anonymous"></script>

<script>

var data = {
    "name": "root1", 
    "children": [
        {
            "name": "parent1", 
            "children": [
                {
                    "name": "child1", 
                    "children": [
                        {
                            "name": "leaf1", 
                            "size": 100
                        }, 
                        {
                            "name": "leaf2", 
                            "size": 200
                        }
                    ]
                }, 
                {
                    "name": "child2",
                    "children": [
                        {
                            "name": "leaf1",
                            "size": 300
                        },
                        {
                            "name": "leaf2",
                            "size": 400
                        }
                    ]
                }
            ]
        },
        {    "name": "parent2", 
            "children": [
                {
                    "name": "child1", 
                    "children": [
                        {
                            "name": "leaf1", 
                            "size": 100
                        }, 
                        {
                            "name": "leaf2", 
                            "size": 200
                        }
                    ]
                }, 
                {
                    "name": "child2",
                    "children": [
                        {
                            "name": "leaf1",
                            "size": 300
                        },
                        {
                            "name": "leaf2",
                            "size": 400
                        }
                    ]
                }
            ]
        },
        {
            "name": "parent3", 
            "children": [
                {
                    "name": "child1", 
                    "children": [
                        {
                            "name": "leaf1", 
                            "size": 100
                        }, 
                        {
                            "name": "leaf2", 
                            "size": 200
                        }
                    ]
                }, 
                {
                    "name": "child2",
                    "children": [
                        {
                            "name": "leaf1",
                            "size": 300
                        },
                        {
                            "name": "leaf2",
                            "size": 400
                        }
                    ]
                }
            ]
        }
    ]
};

var width  = 900,
    height = 800,
    radius = ( Math.min( width, height ) / 2 ) - 10;

var formatNumber = d3.format(",d");

var x = d3.scaleLinear()
    .range([0, 2 * Math.PI]);

var y = d3.scaleSqrt()
    .range([0, radius]);

var color = d3.scaleOrdinal( d3.schemeCategory20 );

var svg = d3.select("body")
            .append("svg")
            .attr("width",  width  )
            .attr("height", height )
            .append( "g" )
            .attr( "transform", "translate(" + ( width / 2 ) + "," + (height / 2) + ")" );

var partition = d3.partition();

var arc = d3.arc()
    .startAngle(  function( d ) 
    { 
        return Math.max( 0, Math.min( 2 * Math.PI, x( d.x0 ) ) ); 

    })
    .endAngle(    function( d ) 
    { 
        return Math.max( 0, Math.min( 2 * Math.PI, x( d.x1 ) ) ); 

    })
    .innerRadius( function( d ) 
    { 
        return Math.max( 0, y( d.y0 ) ); 

    })
    .outerRadius( function( d ) 
    { 
        return Math.max( 0, y( d.y1 ) ); 

    });


var root = d3.hierarchy( data );

root.sum( function( d ) 
    { 

        return d.size; 

    })
    .each( function( d )
    {
        d._children = d.children;
        d.overallSum = d.value;
    });

svg.selectAll( "path" )
   .data( partition( root ).descendants( ) )
   .enter()
   .append( "path" )

       .attr( "d", arc )

       .style( "fill", function( d ) 
       { 

           return color( d.data.name ); 

       })
       .append( "title" )

           .text(function( d ) 
           { 

               return d.data.name + "\n" + formatNumber( d.value ); 

           });

</script>

在使用版本3的示例中,一旦读取数据,就会计算初始布局,并且子节点存储在每个数据._children的新变量中,并且值存储在每个数据中#& 39; s .sum属性。然后重新分配childrenvalue函数,以便.children现在返回._children,但仅当数据的深度小于2时,值函数现在返回{每个数据{1}}。

.sum

对于我的JSFiddle,我试图做一个等价的我想要定义// Compute the initial layout on the entire tree to sum sizes. // Also compute the full name and fill color for each node, // and stash the children so they can be restored as we descend. partition .value(function(d) { return d.size; }) .nodes(root) .forEach(function(d) { d._children = d.children; d.sum = d.value; d.key = key(d); d.fill = fill(d); }); // Now redefine the value function to use the previously-computed sum. partition .children(function(d, depth) { return depth < 2 ? d._children : null; }) .value(function(d) { return d.sum; }); 访问器以返回.children如果一个数据的深度小于2,并且值函数返回{ {1}}。但是,D3版本4并不支持覆盖“&#39;值”&#39;分区的功能或仅返回某些子代。我正在寻找一个可能的解决方案,所以我可以改为返回._children变量,并覆盖&#39;值&#39;函数返回.overallSum。任何帮助将不胜感激,如果我需要解释其他任何事情请告诉我。

感谢。

1 个答案:

答案 0 :(得分:0)

var root = d3.hierarchy( data );

/*    
    specifies what each datum should use when a specified datum calls it's 'value'
    function. The node.value property of each node is set to the numeric value 
    returned by the specified function plus the combined value of all descendants.

    https://github.com/d3/d3-hierarchy#hierarchy
    https://github.com/d3/d3-hierarchy#node_eachAfter
*/    
root.sum( function( d ) 
{ 

    return d.size; 

});

/*
Go through each node and assign the children to the new attribute
._children for each dataum. For all nodes that are one level
below the root set children to null. This allows us to only show
those nodes that are necessary.

https://github.com/d3/d3-hierarchy#hierarchy
*/
root.each( function ( d )
{
    d._children = d.children;

    if( d.depth >= 1 )
    {
        d.children = null;
    }
});

我能够弄明白该怎么做。

我在这里(https://bl.ocks.org/d3noob/43a860bc0024792f8803bba8ca0d5ecd)查看了一些指导,一旦我完成并计算每个节点的值,我就会分配d._children = d.children并将.children设置为null如果我不知道我希望展示它。