如何使用D3js为饼图添加图例?如何使饼图居中显示?

5
 <script type="text/javascript">
 var w = 400,                        //width
  h = 400,                            //height
  r = 150,                            //radius

  color = d3.scale.category20c();     //builtin range of colors


  data = [       
        {"label":"Single", "value":<?php echo $PercentageSingle; ?>}, 
        {"label":"In a relationship", "value":<?php echo $PercentageInRe; ?>}, 
        {"label":"Engaged", "value":<?php echo $PercentageEngaged; ?>},
        {"label":"Married", "value":<?php echo $PercentageMarried; ?>}, 
        {"label":"In an open relationship", "value":<?php echo $PercentageInOpenRe; ?>}, 
        {"label":"It's complicated", "value":<?php echo $PercentageCom; ?>}, 
        {"label":"Separated", "value":<?php echo $PercentageSeparated; ?>}, 
        {"label":"Divorced", "value":<?php echo $PercentageDivorced; ?>},
        {"label":"Widowed", "value":<?php echo $PercentageWidowed; ?>},
        {"label":"Unknown", "value":<?php echo $PercentageUnknown; ?>}        
];

var vis = d3.select("body")
    .append("svg:svg")              //create the SVG element inside the <body>
    .data([data])                   //associate our data with the document
        .attr("width", w)           //set the width and height of our visualization (these will be attributes of the <svg> tag
        .attr("height", h)
    .append("svg:g")                //make a group to hold our pie chart
        .attr("transform", "translate(" + r + "," + r + ")")    //move the center of the pie chart from 0, 0 to radius, radius

var arc = d3.svg.arc()              //this will create <path> elements for us using arc data
    .outerRadius(r);

var pie = d3.layout.pie()           //this will create arc data for us given a list of values
    .value(function(d) { return d.value; });    //we must tell it out to access the value of each element in our data array

var arcs = vis.selectAll("g.slice")     //this selects all <g> elements with class slice (there aren't any yet)
    .data(pie)                          //associate the generated pie data (an array of arcs, each having startAngle, endAngle and value properties) 
    .enter()                            //this will create <g> elements for every "extra" data element that should be associated with a selection. The result is creating a <g> for every object in the data array
        .append("svg:g")                //create a group to hold each slice (we will have a <path> and a <text> element associated with each slice)
            .attr("class", "slice");    //allow us to style things in the slices (like text)

    arcs.append("svg:path")
            .attr("fill", function(d, i) { return color(i); } ) //set the color for each slice to be chosen from the color function defined above
            .attr("d", arc);                                    //this creates the actual SVG path using the associated data (pie) with the arc drawing function

    arcs.append("svg:text")                                     //add a label to each slice
            .attr("transform", function(d) {                    //set the label's origin to the center of the arc
            //we have to make sure to set these before calling arc.centroid
            d.innerRadius = 0;
            d.outerRadius = r;
            return "translate(" + arc.centroid(d) + ")";        //this gives us a pair of coordinates like [50, 50]
        })
        .attr("text-anchor", "middle")                          //center the text on it's origin
        .text(function(d, i) { return data[i].label; });        //get the label from our original data array

</script>

我使用了上面的代码生成了一个饼图,但是它总是在网页显示时位于左侧,我该如何使其居中? 此外,当幻灯片非常小的时候,文本会挤在一起,所以我该如何添加图例而不是在每个幻灯片内显示文本?

这就是您要找的吗? 要居中,请将SVG附加到一个居中的“div”或类似的容器。 - Lars Kotthoff
2个回答

11

这里是我使用的示例代码:http://bl.ocks.org/ZJONSSON/3918369,但你需要 d3.legend.js,你应该可以在那个链接中找到它。添加它之后,需要完成三个步骤。

第一步:为图例添加一个CSS类。

.legend rect {
 fill:white;
 stroke:black;
 opacity:0.8; }

第二步,将属性data-legend添加到g.append("path")。

        g.append("path")
            .attr("d", arc)
            .attr("data-legend", function(d){return d.data.name})
            .style("fill", function (d) { return color(d.data.name); });

第三步。在这之后,继续前进并将此元素放入其中。

legend = svg.append("g")
            .attr("class", "legend")
            .attr("transform", "translate(50,30)")
            .style("font-size", "12px")
            .call(d3.legend)

接下来你应该会得到一个漂亮简洁的图例。如果你想居中显示,就在创建图例时调整translate的值(50, 30)。

以下是最终效果。 enter image description here


3
传说只是添加到 svg 上的矩形和文本。可以在 vida.io 上查看人口饼图模板,其中传说已经内置于图表中: https://vida.io/documents/gSvr8dAH23eirKQDp 要将图表居中,需要更改 svg 中的 "translate" 参数。现在它设置为 "r"。可以尝试这样做:(width / 2 - r) 和 (height / 2 - r)。
var svg = d3.select("#canvas").append("svg")
    .attr("width", width)
    .attr("height", height)
  .append("g")
    .attr("transform", "translate(" + (width / 2 - r) + "," + (height / 2 - r) + ")");

11
您提供的链接需要登录才能查看代码示例。将此类链接分享会让互联网变得更糟。为了方便大家,请使用JSFiddle、bl.ocks.org、CodePen或其他开放的网站。 - couchand

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接