Skip to main content

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

Free 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.

Learn More

BidBear

bidbear.io

Bidbear 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.

Learn More