Introduction to Data Visualization with d3.js v4
d3.js
Introduction
- AGENDA
- D3 Ecosystem
- Selections
- Data binding
- Enter-append
- Scales
- Shapes
- Update & Exit
- Transitions
- Forces
d3.js Introduction
- D3 Ecosystem
API Reference
Selection and Data
Selection adn Data Demo
HTML
1 | <svg> |
JS
1 | import { selectAll } from 'd3' |
CSS
1 | body { |
Enter-Append
1 | <svg></svg> |
- 可以发现,上述代码中HTML结构中并没有rect元素,那么我们在使用selectAll选取了什么?
- 答案是空的选择,类似promise,提供了一个占位符
- 我们在之后使用了
.enter().append('rect')
来追加rect元素并在之后对其属性值进行操作
Scales and Axes
1 | d3.scaleLinear() |
- scale
- mapping from data attributes(domain) to display(range)
- data -> x-value
- value -> y-value
- value -> opacity
- etc.
- mapping from data attributes(domain) to display(range)
1 | // get min/max |
- Scales use often
1 | // continuous |
- Axes
1 | var yAxis = d3.axisLeft() |
Challenge: Creating a Chart
Shapes
Shapes Introduction
- SVG elements
- rect
- x: x-coordinate of top-left
- y: y-coordinate of top-left
- width
- height
- circle
- cx: x-coordinate of center
- cy: y-coordinate of center
- r: radius
- text
- x: x-coordinate
- y: y-coordinate
- dx: x-coordinate offset
- dy: y-coordinate offset
- text-anchor: horizontal text
- alignment
- path
- d: path to follow
- Moveto, Lineto, Curveto, Arcto
- SVG Paths
- SVG Transform
- rect
d3-shape Module
d3-shape calculates the path attribute so we don’t have to
d3.line()
1 | // input: array of objects |
- d3.pie()
1 | const pie = d3.pie() |
- d3.arc()
1 | const pie = { |
Challenge: Line Graph
Update and Exit
enter() and update()
1 | // bars includes update selection |
exit() and merge()
- Exit selection
1 | // exit |
- Enter selection: chain attributes that don’t depend on data
1 | // enter |
- Combines 2 selections into one
1 | bars = enter.merge(bars) |
Transitions
Animating Transitions
1 | const t = d3.transition().duration(1000) // Define transition, syncs animation everywhere it's used |
Transitions
- go from state A to state B
Challenge: Animating Transitions
Force Layout
d3-force Module
Position and Collision
D3 + React
Working Together
D3 | React |
---|---|
interactive dataviz | single-page apps whose data change over time |
enter-update-exit pattern | virtual DOM diffing |
They both solve the same problem
Approach #1
- Use case: App with a small dataset and simple visualization
- React for structure
- D3 for data calculation
- React for rendering
- Pro
- Clean, easy to reason about
- Con
- lifecycle for every tick -> unperforment
- Cannot use D3 functions that need access to DOM
- Use case: App with a small dataset and simple visualization
Approach #2
- Use case: App with a small dataset but highly interactive visualization
- React for structure
- D3 for data calculation
- D3 and React for rendering
- React for element
- D3 for attribute
- On D3, React, and a little bit of Flux
- Pro
- Takes advantage of respective strengths
- Con
- React component around all the nodes -> unperforment
- Makes people uncomfortable
- Use case: App with a small dataset but highly interactive visualization
Approach #3
- Use case: App with a large dataset and frequently updating visualization
- React for structure
- D3 for data calculation
- D3 for rendering
- Pro
- The visualization scales!
- Use all the d3 functions
- Con
- Why you even React, bro?
- Use case: App with a large dataset and frequently updating visualization
Lessons learned
- Never ever have React and D3 controlling same parts of the DOM(or else nasty bugs)
- Know the rules to break them
- Assess the needs of the project, then figure out the combination of D3 + React that make sense