【问题标题】:How to insert pie charts in circle packing layout in d3.js?如何在 d3.js 的圆形包装布局中插入饼图?
【发布时间】:2015-03-19 23:11:39
【问题描述】:

我正在尝试使用 d3.js 中的圆形停车布局创建图表,如 http://jsfiddle.net/mypandos/h3pfx6ns/

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

    circle {
        fill: rgb(31, 119, 180);
        fill-opacity: .25;
        stroke: rgb(31, 119, 180);
        stroke-width: 1px;
    }

    .leaf circle {
        fill: #ff7f0e;
        fill-opacity: 1;
    }

    text {
        font: 10px sans-serif;
    }

</style>
<body>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script>

    var diameter = 960,
            format = d3.format(",d"),
            dataSource = 2;
    var pack = d3.layout.pack()
            .size([diameter - 3, diameter - 3])
            .padding(2)
            .sort(function(a, b) {
                return -(a.value - b.value);
            })
            .value(function(d) { return d.size; });
    pie = d3.layout.pie();
    var svg = d3.select("body").append("svg")
            .attr("width", diameter + 300)
            .attr("height", diameter);

    var data = getData();

    var vis = svg.datum(data).selectAll(".node")
            .data(pack.nodes)
            .enter()
            .append("g");

    var titles = vis.append("title")
            .text(function(d) {
                if (!d.children) {
                    return d.parent.name.toUpperCase() + " - " +
                            d.name + ": " + d.size;
                } else {
                    return d.name;
                }
            });

    var circles = vis.append("circle")
            .attr("stroke", "#bbbbbb")
            .style("opacity", function(d) {
                return !d.children ? 0.8 : 0.2;
            })
            .style("fill", function(d) {
                return "#f5467";
            })
            .attr("cx", function(d) { return d.x; })
            .attr("cy", function(d) { return d.y; })
            .attr("r", function(d) { return d.r; });


    var arcs = vis.append("path")
            .attr("fill","none")
            .attr("id", function(d,i){return "s"+i;})


    var arcPaths = vis.append("g")
            .style("fill","navy");
    var labels = arcPaths.append("text")
            .style("opacity", function(d) {
                if (d.depth == 0) {
                    return 0.0;
                }
                if (!d.children) {
                    return 0.0;
                }
                var sumOfChildrenSizes = 0;
                d.children.forEach(function(child){sumOfChildrenSizes += child.size;});
                //alert(sumOfChildrenSizes);
                if (sumOfChildrenSizes <= 5) {
                    return 0.0;
                }
                return 0.8;
            })
            .attr("font-size",10)
            .style("text-anchor","middle")
            .append("textPath")
            .attr("xlink:href",function(d,i){return "#s"+i;})
            .attr("startOffset",function(d,i){return "50%";})
            .text(function(d){return d.name.toUpperCase();})


    function updateVis() {

        if (dataSource == 0)
            pack.value(function(d) { return d.size; });
        if (dataSource == 1)
            pack.value(function(d) { return 100; });
        if (dataSource == 2)
            pack.value(function(d) { return 1 +
                    Math.floor(Math.random()*301); });

        var data1 = pack.nodes(data);

        titles = vis.append("title")
                .text(function(d) {
                    if (!d.children) {
                        return d.parent.name.toUpperCase() + " - " +
                                d.name + " " + d.size;
                    } else {
                        return d.name;
                    }
                });

        circles.transition()
                .duration(5000)
                .attr("cx", function(d) { return d.x; })
                .attr("cy", function(d) { return d.y; })
                .attr("r", function(d) { return d.r; });

    };


    function getData() {
        return {
            "name": "Surveys",
            "children": [
                {
                    "name": "NGS",
                    "children": [
                        {
                            "name": "Background",
                            "children": [
                                {"name": "Biology", "size":30},
                                {"name": "Computational biology", "size":17},
                                {"name": "Statistics","size":13}

                            ]
                        },
                        {
                            "name": "Training needed",
                            "children": [
                                {
                                    "name": "Quality control of reads", "size": 20,
                                    "children":[
                                        {"name": "Biology", "size":3},
                                        {"name": "Computational biology", "size":7},
                                        {"name": "Statistics","size":10}
                                    ]
                                },
                                {"name": "Other", "size": 30,
                                    "children":[
                                        {"name": "Biology", "size":10},
                                        {"name": "Computational biology", "size":10},
                                        {"name": "Statistics","size":10}
                                    ]}
                            ]
                        }
                    ]
                }
            ]
        };
    };


</script>

但我希望 json 数据的最后一个子项是饼图而不是圆形。

有什么想法吗?

【问题讨论】:

标签: javascript svg d3.js pie-chart circle-pack


【解决方案1】:

我稍微修改了您的代码。我希望这可能是您想要的。
这是一个粗略的示例代码。 我只关注如何在包布局中创建饼图,并没有修改标签或其他内容。

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

    circle {
        fill: rgb(31, 119, 180);
        fill-opacity: .25;
        stroke: rgb(31, 119, 180);
        stroke-width: 1px;
    }

    .leaf circle {
        fill: #ff7f0e;
        fill-opacity: 1;
    }

    text {
        font: 10px sans-serif;
    }

</style>
<body>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script>
    
    var pie = d3.layout.pie().value(function(d) {
            return d.size;
        });

        var color = d3.scale.category10();

        var drawCircle = function(selection){
            selection.append("circle")
            .attr("stroke", "#bbbbbb")
            .style("opacity", function(d) {
                return !d.children ? 0.8 : 0.2;
            })
            .style("fill", function(d) {
                return "#f5467";
            })
            .attr("cx", function(d) { return d.x; })
            .attr("cy", function(d) { return d.y; })
            .attr("r", function(d) { return d.r; });
    };

        
        var drawPieChart = function(selection) {
            var d = selection.datum();
            var arc = d3.svg.arc()
                .outerRadius(d.r)
                .innerRadius(0);
            var arcg = selection.attr("transform","translate("+d.x+"," + d.y+")")
                    .selectAll(".arc")
                    .data(pie(d.children))
                    .enter().append("g")
                    .attr("class", "arc");
            arcg.append("path")
                    .attr("d", arc)
                    .style("fill", function(d, i) {
                        return color(i);
                    });
        };

    var diameter = 960,
            format = d3.format(",d"),
            dataSource = 2;
    var pack = d3.layout.pack()
            .size([diameter - 3, diameter - 3])
            .padding(2)
            .sort(function(a, b) {
                return -(a.value - b.value);
            })
            .value(function(d) { return d.size; });

    var svg = d3.select("body").append("svg")
            .attr("width", diameter + 300)
            .attr("height", diameter);

    var data = getData();

    var vis = svg.datum(data).selectAll(".node")
            .data(pack.nodes)
            .enter()
            .append("g")
            .each(function(d) {
                    if (!d.children)
                        return;
                    
                    if (d.children[0].children) {
                        drawCircle(d3.select(this));
                    }else{
                        drawPieChart(d3.select(this));
                    }                   
    });

    var titles = vis.append("title")
            .text(function(d) {
                if (!d.children) {
                    return d.parent.name.toUpperCase() + " - " +
                            d.name + ": " + d.size;
                } else {
                    return d.name;
                }
            });

    
    var arcs = vis.append("path")
            .attr("fill","none")
            .attr("id", function(d,i){return "s"+i;})


    var arcPaths = vis.append("g")
            .style("fill","navy");
    var labels = arcPaths.append("text")
            .style("opacity", function(d) {
                if (d.depth == 0) {
                    return 0.0;
                }
                if (!d.children) {
                    return 0.0;
                }
                var sumOfChildrenSizes = 0;
                d.children.forEach(function(child){sumOfChildrenSizes += child.size;});
                //alert(sumOfChildrenSizes);
                if (sumOfChildrenSizes <= 5) {
                    return 0.0;
                }
                return 0.8;
            })
            .attr("font-size",10)
            .style("text-anchor","middle")
            .append("textPath")
            .attr("xlink:href",function(d,i){return "#s"+i;})
            .attr("startOffset",function(d,i){return "50%";})
            .text(function(d){return d.name.toUpperCase();})


    function updateVis() {

        if (dataSource == 0)
            pack.value(function(d) { return d.size; });
        if (dataSource == 1)
            pack.value(function(d) { return 100; });
        if (dataSource == 2)
            pack.value(function(d) { return 1 +
                    Math.floor(Math.random()*301); });

        var data1 = pack.nodes(data);

        titles = vis.append("title")
                .text(function(d) {
                    if (!d.children) {
                        return d.parent.name.toUpperCase() + " - " +
                                d.name + " " + d.size;
                    } else {
                        return d.name;
                    }
                });

        circles.transition()
                .duration(5000)
                .attr("cx", function(d) { return d.x; })
                .attr("cy", function(d) { return d.y; })
                .attr("r", function(d) { return d.r; });

    };


    function getData() {
        return {
            "name": "Surveys",
            "children": [
                {
                    "name": "NGS",
                    "children": [
                        {
                            "name": "Background",
                            "children": [
                                {"name": "Biology", "size":30},
                                {"name": "Computational biology", "size":17},
                                {"name": "Statistics","size":13}

                            ]
                        },
                        {
                            "name": "Training needed",
                            "children": [
                                {
                                    "name": "Quality control of reads", "size": 20,
                                    "children":[
                                        {"name": "Biology", "size":3},
                                        {"name": "Computational biology", "size":7},
                                        {"name": "Statistics","size":10}
                                    ]
                                },
                                {"name": "Other", "size": 30,
                                    "children":[
                                        {"name": "Biology", "size":10},
                                        {"name": "Computational biology", "size":10},
                                        {"name": "Statistics","size":10}
                                    ]}
                            ]
                        }
                    ]
                }
            ]
        };
    };


</script>

【讨论】:

    猜你喜欢
    • 2015-01-05
    • 1970-01-01
    • 1970-01-01
    • 2013-01-27
    • 2015-03-12
    • 1970-01-01
    • 1970-01-01
    • 2014-02-09
    • 2014-10-20
    相关资源
    最近更新 更多