D3 Responsive React TypeScript Boilerplate
Copy paste this to get a solid foundation for a responsive D3 React TypeScript chart. The dimensions of the chart are determined by the CSS controlling the chart-container
, and the chart within will dynamically resize to accomodate that container.
import React, {useEffect, useRef, useState, useMemo} from 'react';
import * as d3 from 'd3';
interface Dimensions {
width: number;
height: number;
margins: number;
containerWidth: number | null;
containerHeight: number | null;
}
const SomeChart = () => {
const svgRef = useRef(null);
const svgContainer = useRef(null); // The PARENT of the SVG
// State to track width and height of SVG Container
const [width, setWidth] = useState(0);
const [height, setHeight] = useState(0);
// memoize full dimensions
const dimensions: Dimensions = useMemo(() => {
let dimensions = {
width: width,
height: height,
margins: 0,
containerWidth: null,
containerHeight: null,
};
dimensions.containerWidth = dimensions.width - dimensions.margins * 2;
dimensions.containerHeight = dimensions.height - dimensions.margins * 2;
return dimensions;
}, [width, height]);
// detect size of svg container
useEffect(() => {
const getSvgContainerSize = () => {
const newWidth = svgContainer.current?.clientWidth || 0;
setWidth(newWidth);
const newHeight = svgContainer.current?.clientHeight || 0;
setHeight(newHeight);
};
getSvgContainerSize();
window.addEventListener('resize', getSvgContainerSize);
return () => window.removeEventListener('resize', getSvgContainerSize);
}, []);
// memoize svg element
const svg = useMemo(() => {
return d3
.select(svgRef.current)
.classed('some-chart-svg', true)
.attr('width', dimensions.width)
.attr('height', dimensions.height);
}, [dimensions]);
// memoize container element
const container = useMemo(() => {
return svg
.append('g')
.classed('some-chart-inner-container', true)
.attr(
'transform',
`translate(${dimensions.margins}, ${dimensions.margins})`,
);
}, [svg, dimensions]);
// draw chart
useEffect(() => {}, [svg, container]);
return (
<div className="chart-container">
<div ref={svgContainer} className="chart-svg-container">
<svg ref={svgRef} />
</div>
</div>
);
};
export default SomeChart;
Comments
Recent Work
Basalt
basalt.softwareFree desktop AI Chat client, designed for developers and businesses. Unlocks advanced model settings only available in the API. Includes quality of life features like custom syntax highlighting.
BidBear
bidbear.ioBidbear is a report automation tool. It downloads Amazon Seller and Advertising reports, daily, to a private database. It then merges and formats the data into beautiful, on demand, exportable performance reports.