【问题标题】:D3js sunburst take up entire size of containing elementD3js sunburst 占据了包含元素的整个大小
【发布时间】:2017-06-28 17:11:08
【问题描述】:

我目前正在使用类似于链接here 的 D3.js 创建旭日形。然而,我喜欢我的旭日形首饰有点不同。我不想显示所有弧线,而是想过滤掉并只显示那些在当前根节点上方一级的弧线。我在这里通过 jsfiddle 有一个工作版本:https://jsfiddle.net/andrewsolis/7tactp4z/4/。我还在下面附上了我的javascript代码。

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

/*
    width and height of svg canvas, aspect ratio, and radius of sunburst
*/

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

/*
    show commas for numbers greater then 999 and use decimal notation

    https://github.com/d3/d3-format/blob/master/README.md#format
*/
var formatNumber = d3.format(",d");

/*
    range of linear scale x: 0 to 2 * Math.PI 

    https://github.com/d3/d3-scale#linear-scales
*/
var x = d3.scaleLinear()
    .range( [ 0, ( 2 * Math.PI ) ] );

/*
    range of square root scale y: radius

    https://github.com/d3/d3-scale/blob/master/README.md#scaleSqrt
*/
var y = d3.scaleSqrt()
    .range( [ 0, radius ] );

/*
    create an ordinal scale of colors
    where each name is correlated to a color

    https://github.com/d3/d3-scale/blob/master/README.md#scaleOrdinal
    https://github.com/d3/d3-scale/blob/master/README.md#schemeCategory20    
*/
var color = d3.scaleOrdinal( d3.schemeCategory20 );

/*
    creates a default adjancency diagram which is a space-filling
    variant of a node-link tree diagram. Rather than drawing a link between
    parent and child in the hierarchy, nodes are drawn as solid areas (either arcs
    or rectangles) with placements relative to other nodes 

    https://github.com/d3/d3-hierarchy/blob/master/README.md#partition
*/
var partition = d3.partition();

/*
    creates an arc generator that is used to define how big of a slice a particular
    element should take up on the sunburst

    https://github.com/d3/d3-shape/blob/master/README.md#arcs
*/
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 ) ); 

    });

/*
    creating svg html element with 'width' and 'height' and translating
    it to be the middle of the 'g' tag containing the svg
*/
var svg = d3.select("#sunburst_chart")
        .attr("width",  width  )
        .attr("height", height )
        .append( "g" )
        .attr( "transform", "translate(" + ( width / 2 ) + "," + ( height / 2 ) + ")" );

/*    
    creates a hierarchy root object for d3 where the object
    represents the root of all the data and contains properties
    that can be used to access the associated 'children' data, 
    depth of a node, height, height of a node, etc.

    https://github.com/d3/d3-hierarchy/blob/master/README.md#hierarchy
*/    
var hierarchy_data = 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
*/    
hierarchy_data.sum( function( d ) 
{ 

    return d.size; 

});

svg.selectAll( "path" )
    /*  
        Specify the data to use for the svg element, .descendants returns an array
        of descendant nodes starting with the root node. 

        https://github.com/d3/d3-hierarchy/blob/master/README.md#node_descendants

    */
    .data( partition( hierarchy_data ).descendants( ) )
    .enter()
    .filter( function ( d )
    {
        return d.depth <= 1;
    })
    .append( "path" )
        /*
            Use the 'arc' generator to generate slices for each datum given a certain value. 

            https://github.com/d3/d3-hierarchy#hierarchy
        */
        .attr( "d", arc )

        /*
            Fill the slice with a color based off the color ordinal scale.

            https://github.com/d3/d3-shape/blob/master/README.md#arcs
        */
        .style( "fill", function( d ) 
        { 

            return color( ( d.children ? d : d.parent ).data.name ); 

        })
        .append( "title" )

            .text(function( d ) 
            { 

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

            });

svg.select("path").attr("id", "centroid");

没有任何交互,这正是我想要的,但是大小有问题。如果您检查 svg 元素的 sunburst,您会注意到 sunburst 外半径不等于宽度或高度,但比它包含在其中的实际 svg 元素小一点。我认为这是因为我的弧正在做我的计算,就好像那里有切片一样,但是这些稍后会被d3.filter 函数过滤掉。相反,考虑到数据被过滤掉的事实,我希望我的 sunburst 占用所有可能的空间。任何帮助将不胜感激,如果我需要提供其他任何帮助,请告诉我。

谢谢!

【问题讨论】:

    标签: javascript jquery d3.js svg


    【解决方案1】:

    您可以将viewBox 属性添加到您的svg 元素。如果您的最大层次深度为 3,则计算最外层圆弧的半径,如下所示:

    var maxHierarchy = 3;
    var depth = 1;
    var maxRadius = y((depth + 1) / (maxHierarchy + 1));
    
    var svg = d3.select("#sunburst_chart")
        .attr("width",  width  )
        .attr("height", height )
        .attr("viewBox", (radius - maxRadius) + "," + (radius - maxRadius) + "," +
              (2*maxRadius + 20) + "," + (2*maxRadius + 20))
        .append( "g" )
        .attr( "transform", "translate(" + ( width / 2 ) + "," + ( height / 2 ) + ")" );
    
     //...
    
    svg.selectAll( "path" )
        //...
        .filter( function ( d )
        {
            return d.depth <= depth;
        })
        //...
    

    (+ 20 是您的填充。)

    【讨论】:

    • 我更改了代码以实现您推荐的内容,但现在我收到一个奇怪的错误,看起来图表没有正确移动。您可以通过此处的链接查看:imgur.com/a/7qi7K。我还在这里更新了 jsFiddle:jsfiddle.net/andrewsolis/7tactp4z/5.
    • 对不起,我的例子似乎模棱两可。仍然需要 translate 属性。另外,别忘了在过滤器中使用depth。
    猜你喜欢
    • 2017-07-28
    • 1970-01-01
    • 2016-10-02
    • 1970-01-01
    • 1970-01-01
    • 2012-05-14
    • 2019-11-21
    • 1970-01-01
    • 2015-04-07
    相关资源
    最近更新 更多