In the previous post, we derived a class from BubbleChart
and this got us started on actually visualizing some meaningful data using bubbles.
There are a couple of things to iron out before a visual can appear.
Color Schemes
I am using Cynthia Brewer color schemes, available for download in colorbrewer.css. This file is available on my GitHub as well.
It consists of entries like:
.Spectral .q0-3{fill:rgb(252,141,89)} .Spectral .q1-3{fill:rgb(255,255,191)} .Spectral .q2-3{fill:rgb(153,213,148)} .Spectral .q0-4{fill:rgb(215,25,28)} .Spectral .q1-4{fill:rgb(253,174,97)} .Spectral .q2-4{fill:rgb(171,221,164)} .Spectral .q3-4{fill:rgb(43,131,186)} .Spectral .q0-5{fill:rgb(215,25,28)} .Spectral .q1-5{fill:rgb(253,174,97)}
Usage is simple: you pick a color scheme and add it to the class of your parent element that will contain the actual SVG elements displayed, e.g.: Spectral. Then, one of the “qi–n classes are assigned to these child elements to get the actual color.
So for instance:
The main SVG element on the Crime Explorer visual looks like this:
<svg class="Spectral" id="svg_vis">...</svg>
Then, each of the “circle” elements inside this SVG container will have one of the qi-9 (I am using 9 total colors to display this visualization so i ranges from 0..8).
<circle r="9.664713682964603" class="q2-9" stroke-width="2" stroke="#b17943" id="city_0" cx="462.4456905180483" cy="574.327856528298"></circle>
(Note the class=”q2-9″ attribute above).
All of this is supported by the BubbleChart
class with some prodding.
You need to:
- Pass the color scheme to the constructor of the class derived from BubbleChart upon instantiation:
allStates = new AllStates('vis', crime_data, 'Spectral')
- Implement a function called color_class in the derived class, that will produce a string of type “qi-n”, given an i. The default function supplied with the base class always returns “q1-6”.
@color_class = d3.scale.threshold().domain(@domain).range(("q#{i}-9" for i in [8..0]))
In my implementation, I am using the d3 threshold scale to map a domain of values to the colors I need based on certain thresholds. The range is reversed only because I want “blue” colors to come out on lower threshold values, and “red” – on higher ones (less crime is “better”, so I use red for higher values). See AllStates.coffe for a full listing.How this is hooked up tho the actual data is discussed in the next section.
Data Protocol
This is key: data you pass to the BubbleChart
class must comply with the following requirements:
- It must be an array (not an associative array, a regular array). Each element of this array will be displayed as a circle (“bubble”) on the screen.
- Each element must contain the following fields:
id
– this is a UNIQUE id of the element. It is used byBubbleChart
to do joins (see d3 documentation for what these are)value
– this is what the “value” of each data element is, and it is used to compute the radius of each bubblegroup
– indicates the “color group” to which the bubble belongs. This is what is fed to thecolor_class
function to determine the color of each individual bubble
With all these conditions satisfied, the array of data is now ready to be displayed.
Displaying It
Now that it is all done, showing the visual is simple:
allStates = new AllStates('vis', crime_data, 'Spectral') allStates.create_vis() allStates.display()
Next time: displaying the auxiliary elements: color and size legends, the search box.
Hi,
Thank you for taking the time to write this blog. I think that visualizing in bubbles give a great high-level perspective that incites the eyes to perform the initial investigation. I don’t think it’s will provide the detailed investigation necessary, but it certainly leads to isolating areas of interest and then using other methods to get to the bottom of it.
Anyways, I know it’s been a while, but were you able to do a part 3 to explain the other elements that you mentioned at the bottom of this post? Also, how is the sorting of the bubbles based on colors/crime per capita from top to bottom was done? I know sometimes it’s not perfect, but it certainly looks like most times it works or attempts to work…
Thanks again for your post and I look forward to more!