简体   繁体   English

如何在d3饼图中添加一个漂亮的图例

[英]How to add a nice legend to a d3 pie chart

I have my pie chart working ok but I would like to add a nice legend kind of like this (made in mspaint) 我的饼图工作正常,但我想添加一个像这样的好传奇(用mspaint制作)

在此输入图像描述

but can't quite make it work... 但不能使它工作......

Here is my pie chart code (without the 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 the donut pie chart layout var pie = d3.layout.pie() .value(function(d) { return d.count; }) .sort(null); // Append SVG attributes and append g to the 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 and fill in the colours var g = svg.selectAll(".arc") .data(pie(newData)) .enter().append("g") .attr("class", "arc"); // Append the path to 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 to 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 this sort of thing. 我很惊讶没有更多这种东西的“库存”例子。

Here's a quickie legend that looks nice with your data: 这是一个与您的数据相关的快速图例:

// again rebind for legend
var legendG = mySvg.selectAll(".legend") // note appending it to mySvg and not svg to 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 the right and bump each one down 15 pixels
  })
  .attr("class", "legend");   

legendG.append("rect") // make a matching color rect
  .attr("width", 10)
  .attr("height", 10)
  .attr("fill", function(d, i) {
    return colour(i);
  });

legendG.append("text") // add the 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 the donut pie chart layout var pie = d3.layout.pie() .value(function(d) { return d.count; }) .sort(null); // Append SVG attributes and append g to the 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 and fill in the colours var g = svg.selectAll(".arc") .data(pie(newData)) .enter().append("g") .attr("class", "arc"); // Append the path to 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 to 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> 

Why not just create another div next to where you display your chart, and create the legend using ul/li elements. 为什么不在显示图表的位置旁边创建另一个div,并使用ul / li元素创建图例。 You can match the colors easily and use the names. 您可以轻松匹配颜色并使用名称。 Then you can use css for placement and styling pretty easily. 然后,您可以非常轻松地使用css进行放置和样式设置。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM