Skip to content

Instantly share code, notes, and snippets.

@fasiha
Last active December 30, 2022 07:15
Show Gist options
  • Save fasiha/d23ea4905cf5e4650e8cdeabdd15249f to your computer and use it in GitHub Desktop.
Save fasiha/d23ea4905cf5e4650e8cdeabdd15249f to your computer and use it in GitHub Desktop.
D3, React, and TypeScript. TypeScript generalization of https://stackoverflow.com/a/69044058
/*
This assumes you have a React app. Then,
```bash
npm i d3
npm i -D @types/d3
```
if necessary. Then use this component.
*/
import * as d3 from 'd3';
import { useState, useEffect, useRef } from 'react';
export default function SomeComponent() {
const ref = useRef<SVGSVGElement | null>(null);
useEffect(() => {
if (ref.current) {
const dom = ref.current;
const d3Container = d3.select(dom);
const svg = d3Container
.append('svg')
.attr('width', dom.getBoundingClientRect().width)
.attr('height', dom.getBoundingClientRect().height)
.call(
d3.zoom<SVGSVGElement, unknown>().on('zoom', function (event) {
svg.attr('transform', event.transform);
}),
)
.append('g');
const circle = svg
.append('circle')
.attr('cx', 50)
.attr('cy', 50)
.attr('r', 1)
.attr('fill', '#4CAF50');
function animate() {
let radius = 5;
const distance = 35;
circle
.transition()
.duration(2000)
.attrTween('r', () => d3.interpolate(radius, radius + distance) as any)
.on('end', () => {
radius = +circle.attr('r');
circle
.transition()
.duration(2000)
.attrTween('r', () => d3.interpolate(radius, radius - distance) as any)
.on('end', animate);
});
}
animate();
}
}, [ref]);
return <svg ref={ref} style={{ height: 100, width: 100 }}></svg>;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment