简体   繁体   English

D3-饼图

[英]D3 - pie charts

I have tried many ways but I couldn't draw pie charts in d3 where I have a data like: 我已经尝试了许多方法,但是无法在d3中绘制饼图,其中的数据如下:

"something": [{
    "a":"some value",
    "b":"another value",
    .  
    .
    .
},{
    "c":"a value",
    "d":"value",
    .
    .
    .
}]

This data is almost 55,000 lines and each group has 19 different value. 该数据接近55,000行,每个组具有19个不同的值。 Each group starts with "{" and ends with "}". 每个组以“ {”开头,以“}”结尾。 The code I want should draw pie charts dynamically of reading the data. 我想要的代码应该动态绘制读取数据的饼图。

var width = 550;
var height = 350;
var radius = 300/ 2;
var color = d3.scale.category20b();  //builtin range of colors
var svg = d3.select('#pie_chart').append('svg')
                                 .attr('width', width)
                                 .attr('height', height)
                                 .append('g')
                                 .attr('transform', 'translate(' + (width / 2) +',' + (height / 2) + ')');
var total = 0;

for(var a=0;a<Data.length;a++){
total=total+parseInt(Data[a].count); // simple logic to calculate total of data count value
console.log(total);
}
var pie_data=[];
for( var a=0;a<Data.length;a++){ // simple logic to calculate percentage data for the pie
pie_data[a]=(Data[a].count/total)*100;
}
var arc = d3.svg.arc().outerRadius(radius);
// creating arc element.
var pie = d3.layout.pie()
.value(function(d,i) { return pie_data[i]; })
.sort(null);
//Given a list of values, it will create an arc data for us
//we must explicitly specify it to access the value of each element in our data array
var path = svg.selectAll('path')
.data(pie(Data))
.enter()
.append('path')
.attr('d', arc)
.attr('fill', function(d, i) {
return Data[i].color;
});
//set the color for each slice to be chosen, from the color defined in sample_data.json
//this creates the actual SVG path using the associated data (pie) with the arc drawing function
*/

2nd try 第二次尝试

//pie chart

var width = 300;
var height = 300;

  //each arc in the pie chart
  var outerRadius = width/2;
  var innerRadius = width/3;
  var arc = d3.svg.arc()
                  .innerRadius(innerRadius)
                  .outerRadius(outerRadius);

  //pie chart
  var pie = d3.layout.pie();
  //colors
  var color = d3.scale.category20();

  //Create SVG element
  var svg = d3.select("body")
              .append("svg")
              .attr("width", width)
              .attr("height", height);

//Set up groups
var arcs = svg.selectAll("g.arc")
              .data(pie(data))
              .enter()
              .append("g")
              .attr("class", "arc")
              .attr("transform", "translate(" + outerRadius + "," + outerRadius + ")");

//Draw arc paths
arcs.append("path")
    .attr("fill", function(d, i) {
      return color(i);
    })
    .attr("d", arc);

//Labels
arcs.append("text")
    .attr("transform", function(d) {
      return "translate(" + arc.centroid(d) + ")";
    })
    .attr("text-anchor", "middle")
    .text(function(d) {
      return d.value;
    });

Any idea? 任何想法?

Here's a quick example. 这是一个简单的例子。 It touches on some relatively advanced d3 concepts, so I'll try to explain. 它涉及一些相对高级的d3概念,因此我将尝试进行解释。

First, let's think about your data. 首先,让我们考虑一下您的数据。 d3 likes to deal with arrays of object s . d3喜欢处理对象s的数组。 You have an array of singular object. 您有一个单一对象数组。 So let's do some data conversion. 因此,让我们做一些数据转换。 You have: 你有:

[{
  "a": 1,
  "b": 2,
  "c": 3  
}, {
  "d": 4,
  "e": 5
...

But what you need is: 但是您需要的是:

[
  [{
    "key": "a", 
    "value": 1
   }, {
    "key": "b", 
    "value": 2
   }, {
    "key": "c", 
    "value": 3
   }
  ],[{
    "key": "d", 
    "value": 4
   }
   ....
  ]
]

Luckily d3 has an almost builtin function for this, d3.entries . 幸运的是,d3为此具有几乎内置的功能d3.entries

var data = [{
    "a": 1,
    "b": 2,
    "c": 3
},{
    "a": 4,
    "d": 5,
    "e": 6
}];

var fixedData = data.map(function(d){
  return d3.entries(d);
});

Second, you want to make multiple pie charts where your outer array is a chart and your inner array is your slices. 其次,您要制作多个饼图,其中外部数组是图表,内部数组是切片。 This is great place to use a nested selection . 这是使用嵌套选择的好地方。 The outer selection is a g element for each pie chart. 外部选择是每个饼图的g元素。 Inside this selection is the g element for each arc and label: 在此选择的内部是每个弧和标签的g元素:

// create a g for each pie chart
var p = svg.selectAll(".pie")
  .data(fixedData)
  .enter()
  .append("g")
  .attr("class", "pie")
  .attr("transform",function(d,i){
    return "translate(" + (width / 2) + "," + ((radius * i * 2) + radius) + ")"; //<-- place the g down the page
  });

// create an arc for each slice
var g = p.selectAll(".arc") //<-- this is a nested selection
  .data(function(d){
    return pie(d); //<-- d here is each element of the outer array
  })
  .enter().append("g")
  .attr("class", "arc");

Let's put these two ideas together with some working code: 让我们将这两个想法与一些工作代码放在一起:

 <!DOCTYPE html> <meta charset="utf-8"> <style> .arc text { font: 15px sans-serif; text-anchor: middle; } .arc path { stroke: #fff; } </style> <body> <script src="//d3js.org/d3.v3.min.js"></script> <script> var data = [{ "a": 1, "b": 2, "c": 3 },{ "a": 4, "d": 5, "e": 6 },{ "d": 4, "f": 5, "b": 6 }]; var fixedData = data.map(function(d){ return d3.entries(d); }); var width = 500, height = 500, radius = (Math.min(width, height) / 2) / data.length; var color = d3.scale.category10(); var arc = d3.svg.arc() .outerRadius(radius - 10) .innerRadius(0); var labelArc = d3.svg.arc() .outerRadius(radius / 2) .innerRadius(radius / 2); var pie = d3.layout.pie() .sort(null) .value(function(d) { return d.value; }); var svg = d3.select("body").append("svg") .attr("width", width) .attr("height", height); var p = svg.selectAll(".pie") .data(fixedData) .enter() .append("g") .attr("class", "pie") .attr("transform",function(d,i){ return "translate(" + (width / 2) + "," + ((radius * i * 2) + radius) + ")"; }); var g = p.selectAll(".arc") .data(function(d){ return pie(d); }) .enter().append("g") .attr("class", "arc"); g.append("path") .attr("d", arc) .style("fill", function(d) { return color(d.data.key); }); g.append("text") .attr("transform", function(d) { return "translate(" + labelArc.centroid(d) + ")"; }) .text(function(d) { return d.data.key; }); </script> 

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

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