-
-
Save enjalot/1203641 to your computer and use it in GitHub Desktop.
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta http-equiv="Content-type" content="text/html; charset=utf-8"> | |
<title>Testing Pie Chart</title> | |
<script type="text/javascript" src="http://mbostock.github.com/d3/d3.js?2.1.3"></script> | |
<script type="text/javascript" src="http://mbostock.github.com/d3/d3.geom.js?2.1.3"></script> | |
<script type="text/javascript" src="http://mbostock.github.com/d3/d3.layout.js?2.1.3"></script> | |
<style type="text/css"> | |
.slice text { | |
font-size: 16pt; | |
font-family: Arial; | |
} | |
</style> | |
</head> | |
<body> | |
<script type="text/javascript"> | |
var w = 300, //width | |
h = 300, //height | |
r = 100, //radius | |
color = d3.scale.category20c(); //builtin range of colors | |
data = [{"label":"one", "value":20}, | |
{"label":"two", "value":50}, | |
{"label":"three", "value":30}]; | |
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> | |
</body> | |
</html> |
and here is a fork to display the value in the slice: https://gist.github.com/MohamedAlaa/246b7d45e20be8680394
Is there a way to customize the text that shows up in the label? color, font-size, etc?
I was able to answer my own question. Some styles, like font-size you can adjust in the CSS. You can also add the border between the slices with CSS by using stroke (in Less for simplicity):
.slice {
path {
stroke:#fff;
stroke-width:0.5;
}
text {
font-size:0.9em;
}
}
But for the text color, you need to add another attribute called "fill" to the arcs as such:
.attr("fill", "white")
"simple" example? I think not
@stevematdavies The resulting pie chart is quite simple.
How can I get the data from a Backbone model?
Question: why do you have to put [data] in the extra level of array when creating the outer svg element? The code doesn't work if you just pass data to the data() function:
.data(data) // fails
but
.data([data]) // works
I really don't understand this.
How do i assign the code to a function so i can just call it on a different data set later
@bethrobson The current selection only contains 1 element, the svg
tag. You want to attach the whole of data so it will be passed on to the child tags of svg
. You do this by creating an array with 1 element and bind that to the selection. If you do .data(data)
you only bind the first data-point to the svg.
An alternative is not to bind anything to the svg
var vis = d3.select("body")
.append("svg:svg")
.attr("width", w)
.attr("height", h)
.append("svg:g")
.attr("transform", "translate(" + r + "," + r + ")");
and add the data to the call to pie
var arcs = vis.selectAll("g.slice")
.data(pie(data))
.enter()
.append("svg:g")
.attr("class", "slice");
how can i add more slices?