
@riacarmin
Using
in React applications
D3.js


Agenda
0.
1.
2.
3.
Intro
D3.js 101
with React
[demo]
1
D3.js 101


What is it tho?
🤷♀️


[
{ item: 'apples', quantity: 20 },
{ item: 'oranges', quantity: 12 },
{ item: 'kiwis', quantity: 6 },
{ item: 'bananas', quantity: 4 },
]

[demo]
this.svg = d3
.select(this.element)
.append('svg')
.attr(
'height',
this.height + this.margin.top + this.margin.bottom
)
.attr(
'width',
this.width + this.margin.left + this.margin.right
)
.style('font', '10px sans-serif');
this.canvas = this.svg
.append('g')
.attr(
'transform',
`translate(${this.margin.left}, ${this.margin.top})`
);
// Set scales
// ==========================================================
const xScale = d3
.scaleBand()
.domain(this.data.map((d) => d.item))
.range([0, this.width])
.padding(0.25);
const yScale = d3
.scaleLinear()
.domain([0, d3.max(this.data, (d) => d.quantity)])
.range([this.height, 0]);
const colorScale = d3
.scaleLinear()
.domain([0, d3.max(this.data, (d) => d.quantity)])
.range(['#E2F5E1', '#017E54']);
// General Update Pattern
// ==========================================================
const enter = (enter) =>
enter
.append('rect')
.attr('x', (d) => xScale(d.item))
.attr('width', xScale.bandwidth)
.attr('y', (d) => yScale(d.quantity))
.attr('height', (d) => this.height - yScale(d.quantity))
.attr('fill', (d) => colorScale(d.quantity));
const update = (update) => {}
const exit = (exit) => {}
this.canvas
.selectAll('rect')
.data(this.data)
.join(enter, update, exit);
to VS Code…
2
…with React





React
- Data fetching
- State
- User interaction
D3
- Data mapping
- SVG rendering
<Component />
Architecture
<Chart />
chart.d3.js
import React, { useState, useCallback } from 'react';
import randomNumber from '../../utils/helpers/randomNumber';
import Chart from '../Chart';
import ScatterChart from './d3/scatter';
const DATA = Array.from(Array(6)).map(() => ({
time: randomNumber(1, 20),
points: randomNumber(0, 20),
}));
const Competition = () => {
const [data, setData] = useState(DATA);
return <Chart data={data} d3={ScatterChart} />
};
export default Competition;
<Component />
import React, { useEffect, useRef } from 'react';
const Chart = ({ className, data, d3: D3 }) => {
if (!D3 || !validate(D3)) {
return <div />;
}
const chartRef = useRef(null);
const chartClass = useRef(null);
// Render =================================================
return <div className={className} ref={chartRef}></div>;
};
<Chart />
// Initialize chart svg container =================================
useEffect(() => {
if (!chartRef.current) {
return false;
}
chartClass.current = new D3(chartRef.current);
return () => {
chartClass.current.destroy();
};
}, []);
<Chart />
export default class Chart {
constructor(element) {
this.element = element;
this.data = null;
this.margin = { top: 40, right: 60, bottom: 40, left: 60 };
this.size = element ? element.getBoundingClientRect() : {};
this.init();
}
get height() { … }
get width() { … }
init = () => { … };
setData = (data) => { … };
resize = (element) => { … };
render = () => { … };
destroy = () => { … };
}
chart.d3.js
const debouncedData = useDebounce(data, 150);
// Update chart on changes in data =========================================
useEffect(() => {
debouncedData &&
chartClass.current &&
chartClass.current.setData(debouncedData);
chartClass.current && chartClass.current.render();
}, [debouncedData]);
<Chart />
// Resize chart on window.resize ========================
const isClient = typeof window === 'object';
useEffect(() => {
if (!isClient) {
return false;
}
const handleResize = () =>
chartClass.current.resize &&
chartClass.current.resize(chartRef.current);
window.addEventListener('resize', handleResize);
return () => window.removeEventListener('resize', handleResize);
}, []);
<Chart />
to VS Code…
the end.



@riacarmin
Using d3.js
in React applications
Using D3.js with React
By Ria Carmin
Using D3.js with React
Introduction to integrating D3.js data visualization in React apps using functional components and hooks.
- 628