javascript - How to add a nice legend to a d3 pie chart -


i have pie chart working ok add nice legend kind of (made in mspaint)

enter image description here

but can't quite make work...

here pie chart code (without legend part) :

<!doctype html>  <html>    <head>    <script data-require="d3@3.5.3" data-semver="3.5.3" src="//cdnjs.cloudflare.com/ajax/libs/d3/3.5.3/d3.js"></script>  </head>    <body>    <script>      var newdata = [{          count: 1,          emote: "onetwothree"        }, {          count: 1,          emote: "fourfivesix"        }, {          count: 1,          emote: "seveneightnine"        }, {          count: 15,          emote: "teneleventwelve"        },        ]        // define size & radius of donut pie chart      var width = 450,        height = 800,        radius = math.min(width, height) / 2;        // define arc colours      var colour = d3.scale.category20();        // define arc ranges      var arctext = d3.scale.ordinal()        .rangeroundbands([0, width], .1, .3);        // determine size of arcs      var arc = d3.svg.arc()        .innerradius(radius - 130)        .outerradius(radius - 10);        // create donut pie chart layout      var pie = d3.layout.pie()        .value(function(d) {          return d.count;        })        .sort(null);        // append svg attributes , append g svg      var mysvg = d3.select('body').append("svg")        .attr("width", width)        .attr("height", height);        var svg = mysvg        .append("g")        .attr("transform", "translate(" + radius + "," + radius + ")");        var svgtext = mysvg        .append("g")        .attr("transform", "translate(" + radius + "," + radius + ")");        // define inner circle      svg.append("circle")        .attr("cx", 0)        .attr("cy", 0)        .attr("r", 100)        .attr("fill", "#fff");        // calculate svg paths , fill in colours      var g = svg.selectall(".arc")        .data(pie(newdata))        .enter().append("g")        .attr("class", "arc");        // append path each g      g.append("path")        .attr("d", arc)        //.attr("data-legend", function(d, i){ return parseint(newdata[i].count) + ' ' + newdata[i].emote; })        .attr("fill", function(d, i) {          return colour(i);        });        var textg = svg.selectall(".labels")        .data(pie(newdata))        .enter().append("g")        .attr("class", "labels");        // append text labels each arc      textg.append("text")        .attr("transform", function(d) {          return "translate(" + arc.centroid(d) + ")";        })        .attr("dy", ".35em")        .style("text-anchor", "middle")        .attr("fill", "#fff")        .text(function(d, i) {          return d.data.count > 0 ? d.data.emote : '';        });    </script>  </body>    </html>

i'm surprised there's not more "stock" examples of sort of thing.

here's quickie legend looks nice data:

// again rebind legend var legendg = mysvg.selectall(".legend") // note appending mysvg , not svg make positioning easier   .data(pie(newdata))   .enter().append("g")   .attr("transform", function(d,i){     return "translate(" + (width - 110) + "," + (i * 15 + 20) + ")"; // place each legend on right , bump each 1 down 15 pixels   })   .attr("class", "legend");     legendg.append("rect") // make matching color rect   .attr("width", 10)   .attr("height", 10)   .attr("fill", function(d, i) {     return colour(i);   });  legendg.append("text") // add text   .text(function(d){     return d.value + "  " + d.data.emote;   })   .style("font-size", 12)   .attr("y", 10)   .attr("x", 11); 

full example:

<!doctype html>  <html>    <head>    <script data-require="d3@3.5.3" data-semver="3.5.3" src="//cdnjs.cloudflare.com/ajax/libs/d3/3.5.3/d3.js"></script>  </head>    <body>    <script>      var newdata = [{          count: 1,          emote: "onetwothree"        }, {          count: 1,          emote: "fourfivesix"        }, {          count: 1,          emote: "seveneightnine"        }, {          count: 15,          emote: "teneleventwelve"        },        ]        // define size & radius of donut pie chart      var width = 450,        height = 800,        radius = math.min(width, height) / 2.5;        // define arc colours      var colour = d3.scale.category20();        // define arc ranges      var arctext = d3.scale.ordinal()        .rangeroundbands([0, width], .1, .3);        // determine size of arcs      var arc = d3.svg.arc()        .innerradius(radius - 130)        .outerradius(radius - 10);        // create donut pie chart layout      var pie = d3.layout.pie()        .value(function(d) {          return d.count;        })        .sort(null);        // append svg attributes , append g svg      var mysvg = d3.select('body').append("svg")        .attr("width", width)        .attr("height", height);        var svg = mysvg        .append("g")        .attr("transform", "translate(" + radius + "," + radius + ")");        var svgtext = mysvg        .append("g")        .attr("transform", "translate(" + radius + "," + radius + ")");        // define inner circle      svg.append("circle")        .attr("cx", 0)        .attr("cy", 0)        .attr("r", 100)        .attr("fill", "#fff");        // calculate svg paths , fill in colours      var g = svg.selectall(".arc")        .data(pie(newdata))        .enter().append("g")        .attr("class", "arc");        // append path each g      g.append("path")        .attr("d", arc)        //.attr("data-legend", function(d, i){ return parseint(newdata[i].count) + ' ' + newdata[i].emote; })        .attr("fill", function(d, i) {          return colour(i);        });        var textg = svg.selectall(".labels")        .data(pie(newdata))        .enter().append("g")        .attr("class", "labels");        // append text labels each arc      textg.append("text")        .attr("transform", function(d) {          return "translate(" + arc.centroid(d) + ")";        })        .attr("dy", ".35em")        .style("text-anchor", "middle")        .attr("fill", "#fff")        .text(function(d, i) {          return d.data.count > 0 ? d.data.emote : '';        });            var legendg = mysvg.selectall(".legend")        .data(pie(newdata))        .enter().append("g")        .attr("transform", function(d,i){          return "translate(" + (width - 110) + "," + (i * 15 + 20) + ")";        })        .attr("class", "legend");               legendg.append("rect")        .attr("width", 10)        .attr("height", 10)        .attr("fill", function(d, i) {          return colour(i);        });            legendg.append("text")        .text(function(d){          return d.value + "  " + d.data.emote;        })        .style("font-size", 12)        .attr("y", 10)        .attr("x", 11);                </script>  </body>    </html>


Comments

Popular posts from this blog

c# - Binding a comma separated list to a List<int> in asp.net web api -

Delphi 7 and decode UTF-8 base64 -

html - Is there any way to exclude a single element from the style? (Bootstrap) -