By John Muyskens (@JohnMuyskens) and Leslie Shapiro (@lmshap). We are members of the Washington Post graphics team (@postgraphics) who specialize in data journalism.
Goal is to structure your data the way you want your DOM to look.
Nest
is like "groupBy" in other functional programming languages
.entries
returns an array
.map
returns an object which is useful for creating lookup tables. There's also .object
which you can use if you are sure your data doesn't collide with js reserved words. JS objects not equal to hash tables like python dicts but can be used in much the same way.
d3.dateParse
returns a function that turns a String into a Date
d3.dateFormat
returns a function that turns a Date into a String
The format DSL is like strptime in other programming languages. It's worth learning the most common arguments.
var parseTime = d3.timeParse('%a %b %d %H:%M:%S +0000 %Y'); var formatTime = d3.timeFormat('%Y-%m-%d'); var parseFormattedTime = d3.timeParse('%Y-%m-%d');
Add a .rollup()
function that counts number of tweets per day.
Fork this block: http://blockbuilder.org/jmuyskens/e81ad8e9a3b700bde6c2c45e4421ec79
Copy in your d3.nest()
code and store the nested data in a variable called nestedData
.
Modify domain of the x and y-axis using d3.extent()
.
Change reference in .data()
to nestedData
.
Your code will look something like this when you are done: http://blockbuilder.org/jmuyskens/e6dd5b14f7de3bd690a32c414daa4f3a
d3.scaleLinear
may not be the most appropriate choice for our x axis. Let's try using d3.scaleTime
instead.
Extra credit: change the y-axis scale to begin at zero. Hint: use d3.max()
.
Your code will look something like this when you are done: http://blockbuilder.org/jmuyskens/278992910f1668f670f5d32d63645cb1
Play with the following:
.tickSize
to specify length of ticks. Try making your axes as wide and tall as your chart.
.ticks
to specify number of ticks
.tickFormat
format the tick
Use .attr('transform', 'translate(TK, TK)')
to move your axis around.
The backbone of the axis is a <path>
while the ticks are <line>
s so you can easily style them separately with CSS.
We can make a dashed line with stroke-dasharray: TKpx TKpx;
.
Add a new <g>
container for our annotation.
To the <g>
add a <line>
.
Also add to the <g>
a <text>
to label our line. Use .text()
to specify your label text.
Translate the <g>
to a relevant date (for instance, inauguration day, Jan. 20, 2017) using .attr('translate', 'transform(TK, TK)')
. Hint: use a scale.
Use the svg attributes text-anchor
(values can be start
, middle
, end
) to justify the text, dx
and dy
to adjust the position of the label.
Your code will look something like this when you are done: http://blockbuilder.org/jmuyskens/a67754e7b5e21e55abbf768fb1f6c5ed
With the same data, we'll change from a line chart to a scatterplot.
First let's change the y-axis to chart the variable favorite_count
. What other line of code do we also need to update?
As opposed to a line, we don't get a handy generator from d3 to make a scatter plot. Instead, we'll use the selectAll() + enter() pattern to add <circle>
s.
TK circle svg docs link.
You need to specify the following attributes:
cx
(x position)cy
(y position)r
(radius)
Set a class using the source
value in the data and use CSS to change the fill
on the <circle>
s.
Your code will look something like this when you are done: http://blockbuilder.org/jmuyskens/12079dc0dcd8d24138b8814afe6659a9
Extra credit: use the area of the circle to represent a data attribute.
When entering or adding elements chain .on(EVENTNAME, callback)
. Similar to jQuery, this calls a function when an event happens.
D3 will call your callback function with the datum like you get in other accessor functions. Use d3.select(this)
to select the element that was triggered.
TK mouse events
Some events:
- mouseenter
- mouseleave
- mouseover
- click
http://blockbuilder.org/jmuyskens/df89fd5d8a5ac0e2890d030f4db5d6cb
First, add a new linear scale for the x axis. Set the domain of this scale based on retweet_count
.
Then on our enter()
code for <circle>
chain .transition()
. After this, we can change different attributes and d3 will transition them for us.
To slow down the transition, use .duration(TK ms)
.
Your code will look something like this when you are done: http://blockbuilder.org/jmuyskens/372c0661614876ca736cc6af475a3840
- Transitions
- Voronoi
- Layouts (force, heirarchy)
- Geo tools
- Modules
- Behaviors (drag and zoom)
- Canvas
crowbar to download your chart as an SVG. You can then edit it using vector graphics software such as Adobe Illustrator.
d3-jetpack for convenience functions that will save you a lot of repetitive typing.
d3-legend to make convenient legends based on your scales.
Textures.js to use patterns in your visualizations.
Swoopy drag for interactive annotations.