我尝试了很多方法,但我无法在d3中绘制饼图,其中包含以下数据:
"something": [{
"a":"some value",
"b":"another value",
.
.
.
},{
"c":"a value",
"d":"value",
.
.
.
}]
这个数据差不多是55,000行,每组有19个不同的值。 每组以“{”开头,以“}”结尾。我想要的代码应该动态地绘制饼图来读取数据。
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
*/
第二次尝试
//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;
});
有什么想法吗?
答案 0 :(得分:4)
这是一个简单的例子。它涉及一些相对先进的d3概念,所以我试着解释一下。
首先,让我们考虑一下您的数据。 d3喜欢处理对象数组 s 。你有一个奇异的对象数组。因此,让我们进行一些数据转换。你有:
[{
"a": 1,
"b": 2,
"c": 3
}, {
"d": 4,
"e": 5
...
但你需要的是:
[
[{
"key": "a",
"value": 1
}, {
"key": "b",
"value": 2
}, {
"key": "c",
"value": 3
}
],[{
"key": "d",
"value": 4
}
....
]
]
幸运的是,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);
});
其次,您希望制作多个饼图,其中外部数组是图表,内部数组是切片。这是使用nested selection的好地方。外部选择是每个饼图的g
元素。在此选择内部是每个弧和标签的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");
让我们将这两个想法与一些有效的代码结合在一起:
<!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>
&#13;