Skip to content

Instantly share code, notes, and snippets.

@sfrdmn
Created September 28, 2011 21:46
Show Gist options
  • Save sfrdmn/1249346 to your computer and use it in GitHub Desktop.
Save sfrdmn/1249346 to your computer and use it in GitHub Desktop.
DAI523 - Bubble Chart Skeleton
/*
Yo doods. This code creates a bubble chart. It's unfinished, so you gotta finish it.
Use the comments I left to figure things out. Comments are specified by two slashes //
Multiple line comments begin with /asterix and end with asterix/
Commented code does not run.
;\
|' \
_ ; : ;
/ `-. /: : |
| ,-.`-. ,': : |
\ : `. `. ,'-. : |
\ ; ; `-.__,' `-.|
\ ; ; ::: ,::'`:. `.
\ `-. : ` :. `. \
\ \ , ; ,: (\
\ :., :. ,'o)): ` `-. _______________
,/,' ;' ,::"'`.`---' `. `-._ | |
,/ : ; '" `;' ,--`. | YOU CAN DO IT! |
;/ :; ; ,:' ( ,:) < _______________|
,.,:. ; ,:., ,-._ `. \""'/
'::' `:'` ,'( \`._____.-'"'
;, ; `. `. `._`-. \\
;:. ;: `-._`-.\ \`.
'`:. : |' `. `\ ) \
` ;: | `--\__,'
'` ,'
,-'
*/
/*
Here we create two variables, one named w and one named h. These will be the values
we use to specify the width and height of our embedded SVG. Now if we decide to change
the width and height later, we simply change these values and it'll update through the
whole program.
*/
var w = 800; // Note that the spaces in 'w = 1500' are not necessary
var h = 600; // But the space between 'var' and 'h' is! Otherwise it would say 'varh'
var margin = 50; // total margin // and that dont make no sense
/*
The following statement selects the body element in our page and appends a blank svg
element to it. When you use append(), the selection changes to the appended element(s).
So now the newly appended svg element is selected. We give it a width, a height, and
a class. A class is an identifier. Like giving it a name.
When you append svg elements you need to prefix them with 'svg:'. Otherwise, d3 won't
know whether you're trying to add svg or html.
*/
d3.select("body").append("svg:svg")
.attr("width", w+margin)
.attr("height", h+margin)
.attr("class","chart");
/*
Now we save a selection of the blank svg. We could have done this on the last line
since we ended up with the svg selection anyway, but I'm doing it here for clarity.
Before we selected a <body> tag. Now since the svg is named, we'll select it by its name.
To select based on class you put a . at the front of the word
Actually, since we want margins, we make a group called .content which will contain
all the graphics. That way, we can shift the graphics all at once to create a margin.
Our chart selection will be that group.
*/
var chart = d3.select(".chart").append("svg:g") // Without a . it would try to select <chart>, which doesn't exist!
.attr("class","content")
.attr("transform", "translate(" + margin/2 + "," + margin/2 + ")"); // The transform with trasnlate will shift our group down and to the right
/*
The following statement creates a line for our x axis
*/
chart.append("svg:line")
.attr("stroke-width", 1)
.attr( "stroke","gray")
.attr("x1", 0)
.attr("y1", h)
.attr("x2", w)
.attr("y2", h);
/*
The following statement creates a line for our y axis
*/
chart.append("svg:line")
.attr("stroke-width", 1)
.attr( "stroke","gray")
.attr("x1", 1)
.attr("y1", 0)
.attr("x2", 1)
.attr("y2", h-1);
/*
Now we'll place our circles.
The d3.csv line loads our data. Everything after that
runs only after the data is loaded. You only need to worry
about the stuff inside the curly brackets
*/
d3.csv( "data/crimeRatesByState2005.csv", function(csv) {
var xgrid = d3.scale.linear()
.domain([0,9.9])
.range([0,w]);
var ygrid = d3.scale.linear()
.domain([0,256.7])
.range([0,h]);
var radius = function(d,i) {
return Math.sqrt( d.population )/150;
}
var xpos = function(d,i) {
return xgrid( d.murder );
}
var ypos = function(d,i) {
return ygrid( d.robbery );
}
// We still need two functions: one for y position and one for bubble radius
/*
This is the code which places the bubbles.
First, it makes an empty selection of all circles named bubble (none exist yet).
Then it attaches our dataset to that selection.
For every member in that dataset, it adds a new circle to the image.
After that, it is only a matter of adding attributes to those bubbles.
*/
chart.selectAll("circle.bubble").data(csv)
.enter().append("svg:circle")
.attr("class", "bubble")
.attr("cx", xpos ) // Uses a function to specify the x-position of bubbles
.attr("cy", ypos ) // Is a constant number right now. You need to give it a function to get dynamic values.
.attr("r", radius ) // Same deal.
.attr("fill", "steelblue"); // steel blue B)
/*
The following statements create grid lines
In the same way we created functions which changed the attributes of elements
on a per element basis, d3 has functions built in to do the same thing.
This function will just divide the the width and height into appropriate
subsections, i.e. a grid
Don't worry about it!
*/
chart.selectAll("line.xgrid").data( xgrid.ticks(10) )
.enter().insert("svg:line", "circle")
.attr("class", xgrid)
.attr("stroke-width", .5)
.attr("stroke", "lavender")
.attr("x1", xgrid)
.attr("y1", 0 )
.attr("x2", xgrid)
.attr("y2", h-1 );
chart.selectAll("line.ygrid").data( ygrid.ticks(10) )
.enter().insert("svg:line", "circle")
.attr("class", "ygrid")
.attr("stroke-width", .5)
.attr("stroke", "lavender")
.attr("x1", 0)
.attr("y1", ygrid)
.attr("x2", w-1)
.attr("y2", ygrid);
// The following lines create the labels for our axes. Uses the same method as making grid
chart.selectAll("text.xrule").data( xgrid.ticks(10) )
.enter().append("svg:text")
.attr("class", "xrule")
.attr("x", xgrid)
.attr("y", h )
.attr("dx", -7 )
.attr("dy", 15 )
.text( function(d) {
return d;
});
chart.selectAll("text.yrule").data( ygrid.ticks(10) )
.enter().append("svg:text")
.attr("class", "yrule")
.attr("x", 0)
.attr("y", function(d,i) {
return h - ygrid(d,i);
})
.attr("dx", -25)
.attr("dy", 5 )
.text( function(d,i) {
if( i != 0 )
return d;
else
return "";
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment