react and d3: an approach that stays simple
Tom = engineer at Mapbox, building applications, visualizations, standards
Tom = open source zealot, building big, documentation.js, simple-statistics
Tom = d3 enthusiast, worked on iD, one of the largest d3 applications
What to do about visualizations in the React era
tl;dr: Use JSX instead of the d3 selection API and keep everything else.
Modern frameworks are ground-up: build your whole page with them, on server and client
Modern frameworks are ground-up: all-in, they work best when they control everything
Quick history to d3
Stage 1: books
Semiology of Graphics, Jacques Bertin 1967, established principles of visualizations
Semiology of Graphics: how do color, light, form, convey information?
Grammar of Graphics, Leland Wilkinson 2006, established how computer graphics could be made out of small composable parts
Grammar of Graphics: basically Semiology of Graphics of Computers
What do these books have to do with d3?
Semiology of Graphics ⇢ Grammar of Graphics ⇢ ggplot ⇢ Prefuse ⇢ d3
These are the opposite of HighCharts, and not just because of trendy branding
Visualization via Composition
d3 has no d3.lineChart()
It has scales and colors and super low-level parts that you combine
Okay, let's get to corrections
1: d3 has very little to do with SVG
2: you don't need to use d3's data joins when you have React's
3: typing is almost never the problem
4: everyone starts by copy & pasting examples
So let's get to the statement:
Bringing d3 into the React world should not mean higher-level abstractions
Never ever
<LineChart data={foo} />
The magic of d3 is that it is not dependent on higher-level abstractions
It is in the magic long line of visualization with composition, with small interchangeable, fully customizable parts
Use React for putting things on the page
use d3 for visualization-specific, DOM-independent utils
So d3.append('svg') just becomes <svg>
I can state that doesn't suck because we do it (Mapbox Analytics, our internal reports)
Avoiding pitfalls: no more componentDidUpdate hooks
Avoiding pitfalls: don't have to resort to __data__ for d3 and React extension for React-land
Avoiding pitfalls: you don't have to use refs
Avoiding pitfalls: server-rendering can work with charts!
Avoiding pitfalls: never get stuck with some part of a chart that you can't customize through a 'wrapper'
What about animations?
In React,
I don't know if I expect this to become popular, but I expect it to be the way of the pros
d3 abstractions are like kittens
c3, dc.js, nvd3, recharts, graphene, plottable, xcharts, mozaik, react-d3, react-d3-components
This list will get longer, but should it?
Abstractions keep having less expressive power than d3 itself, keep having assumptions you don't want
The catch
There's always a catch
d3 does have some SVG-specific stuff: axes and behaviors
Luckily, rebuilding them is pretty straightforward! They just use the existing d3 API.
| Fin
Reader version: (search for d3)