D3从嵌套的JSON中绘制第二个圆环图

时间:2015-04-07 15:37:40

标签: javascript svg d3.js

我今天正在学习D3。下面是一组带有JSON数据集的示例代码。我目前正在尝试在主要圆环图旁边创建第二个图表。此图表将是thin_vols []数组的另一个圆环图,它嵌套在每个对象中。如果你看到下面的注释代码,我试图建立第二个图表没有这样的运气。非常感谢任何建议或帮助。谢谢。

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8"/>
    <title>D3 Donut Chart</title>
</head>
<meta charset="utf-8">
<style>

    body {
        font: 10px sans-serif;
    }

    .arc path {
        stroke: #fff;
    }

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

    var sampleSet = {
        "title":"DummyData",
        "data":[
            {
                "origin":"Disk_Pool_1",
                "volumeName":"Vol1",
                "usage":15,
                "type":"thick",
                "thin_vols":[]
            },
            {
                "origin":"Disk_Pool_1",
                "volumeName":"Vol2",
                "usage":25,
                "type":"thick",
                "thin_vols":[]
            },
            {
                "origin":"Disk_Pool_1",
                "volumeName":"Repo_06",
                "usage":50,
                "type":"thick",
                "thin_vols":[
                    {
                        "origin":"Repo_06",
                        "volumeName":"thinVol1",
                        "usage":10,
                        "max":20,
                        "type":"thin"
                    },
                    {
                        "origin":"Repo_06",
                        "volumeName":"thinVol2",
                        "usage":10,
                        "max":30,
                        "type":"thin"
                    },
                    {
                        "origin":"Repo_06",
                        "volumeName":"freespace",
                        "usage":20,
                        "max":40,
                        "type":"freespace"
                    }]
            }
        ]
    };

    var m = 10,
            r = 100,
            z = d3.scale.category20c();

    var pie = d3.layout.pie()
            .value(function(d) { return +d.usage; })
            .sort(function(a, b) { return b.usage - a.usage; });

    var arc = d3.svg.arc()
            .innerRadius(r / 2)
            .outerRadius(r);

    //here

    var disks = d3.nest()
            .key(function(d) { return d.origin; })
            .entries(sampleSet.data);

    var svg = d3.select("body").selectAll("div")
            .data(disks)
            .enter().append("div")
            .style("display", "inline-block")
            .style("width", (r + m) * 2 + "px")
            .style("height", (r + m) * 2 + "px")
            .append("svg:svg")
            .attr("width", (r + m) * 2)
            .attr("height", (r + m) * 2)
            .append("svg:g")
            .attr("transform", "translate(" + (r + m) + "," + (r + m) + ")");

    svg.append("svg:text")
            .attr("dy", ".35em")
            .attr("text-anchor", "middle")
            .text(function(d) { return d.key; });



    var g = svg.selectAll("g")
            .data(function(d) { return pie(d.values); })
            .enter().append("svg:g");

    g.append("svg:path")
            .attr("d", arc)
            .style("fill", function(d) { return z(d.data.volumeName); })
            .append("svg:title")
            .text(function(d) { return d.data.volumeName + ": " + d.data.usage; });

    g.filter(function(d) { return d.endAngle - d.startAngle > .2; }).append("svg:text")
            .attr("dy", ".35em")
            .attr("text-anchor", "middle")
            .attr("transform", function(d) { return "translate(" + arc.centroid(d) + ")rotate(" + angle(d)        + ")"; })
            .text(function(d) { return d.data.volumeName + ": " + d.data.usage; });


    var disks2 = d3.nest()
            .key(function(d) { return d.origin; })
            .entries(sampleSet.data.thin_vols);

    var svg2 = d3.select("body").selectAll("div")
            .data(disks2)
            .enter().append("div")
            .style("display", "inline-block")
            .style("width", (r + m) * 2 + "px")
            .style("height", (r + m) * 2 + "px")
            .append("svg:svg")
            .attr("width", (r + m) * 2)
            .attr("height", (r + m) * 2)
            .append("svg:g")
            .attr("transform", "translate(" + (r + m) + "," + (r + m) + ")");

    svg2.append("svg:text")
            .attr("dy", ".35em")
            .attr("text-anchor", "middle")
            .text(function(d) { return d.key; });

    var g2 = svg2.selectAll("g")
            .data(function(d) { return pie(d.values); })
            .enter().append("svg:g");

    g2.append("svg:path")
            .attr("d", arc)
            .style("fill", function(d) { return z(d.data.volumeName); })
            .append("svg:title")
            .text(function(d) { return d.data.thinvolumeName + ": " + d.data.usage; });

    g2.filter(function(d) { return d.endAngle - d.startAngle > .2; }).append("svg:text")
            .attr("dy", ".35em")
            .attr("text-anchor", "middle")
            .attr("transform", function(d) { return "translate(" + arc.centroid(d) + ")rotate(" + angle(d)        + ")"; })
            .text(function(d) { return d.data.volumeName + ": " + d.data.usage; });

    function angle(d) {
        var a = (d.startAngle + d.endAngle) * 90 / Math.PI - 90;
        return a > 90 ? a - 180 : a;
    }

</script>
</body>
</html>

1 个答案:

答案 0 :(得分:1)

我能够通过展平现有的JSON来渲染第二个图表。请参阅以下源代码。

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8"/>
    <title>D3 Donut Chart</title>
</head>
<meta charset="utf-8">
<style>

    body {
        font: 10px sans-serif;
    }

    .arc path {
        stroke: #fff;
    }

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

    var sampleSet = {
        "title": "DummyData",
        "data": [
            {
                "origin": "Disk_Pool_1",
                "volumeName": "Vol1",
                "usage": 15,
                "type": "thick"
            },
            {
                "origin": "Disk_Pool_1",
                "volumeName": "Vol2",
                "usage": 25,
                "type": "thick"
            },
            {
                "origin": "Disk_Pool_1",
                "volumeName": "Repo_06",
                "usage": 50,
                "type": "thick"
            },
            {
                "origin": "Repo_06",
                "volumeName": "thinVol1",
                "usage": 10,
                "max": 20,
                "type": "thin"
            },
            {
                "origin": "Repo_06",
                "volumeName": "thinVol2",
                "usage": 10,
                "max": 30,
                "type": "thin"
            },
            {
                "origin": "Repo_06",
                "volumeName": "freespace",
                "usage": 20,
                "max": 40,
                "type": "freespace"
            }
        ]
    };

    var m = 10, r = 100, z = d3.scale.category20c();

    var pie = d3.layout.pie()
            .value(function (d) {
                return +d.usage;
            })
            .sort(function (a, b) {
                return b.usage - a.usage;
            });

    var arc = d3.svg.arc()
            .innerRadius(r / 2)
            .outerRadius(r);

    var disks = d3.nest()
            .key(function (d) {
                return d.origin;
            })
            .entries(sampleSet.data);

    var svg = d3.select("body").selectAll("div")
            .data(disks)
            .enter().append("div")
            .style("display", "inline-block")
            .style("width", (r + m) * 2 + "px")
            .style("height", (r + m) * 2 + "px")
            .append("svg:svg")
            .attr("width", (r + m) * 2)
            .attr("height", (r + m) * 2)
            .append("svg:g")
            .attr("transform", "translate(" + (r + m) + "," + (r + m) + ")");

    svg.append("svg:text")
            .attr("dy", ".35em")
            .attr("text-anchor", "middle")
            .text(function (d) {
                return d.key;
            });


    var g = svg.selectAll("g")
            .data(function (d) {
                return pie(d.values);
            })
            .enter().append("svg:g");

    g.append("svg:path")
            .attr("d", arc)
            .style("fill", function (d) {
                return z(d.data.volumeName);
            })
            .append("svg:title")
            .text(function (d) {
                return d.data.volumeName + ": " + d.data.usage;
            });

    g.filter(function (d) {
        return d.endAngle - d.startAngle > .2;
    }).append("svg:text")
            .attr("dy", ".35em")
            .attr("text-anchor", "middle")
            .attr("transform", function (d) {
                return "translate(" + arc.centroid(d) + ")rotate(" + angle(d) + ")";
            })
            .text(function (d) {
                return d.data.volumeName + ": " + d.data.usage;
            });

    function angle(d) {
        var a = (d.startAngle + d.endAngle) * 90 / Math.PI - 90;
        return a > 90 ? a - 180 : a;
    }

</script>
</body>
</html>