Skip to content

Instantly share code, notes, and snippets.

@latviancoder
Created October 9, 2018 18:04
Show Gist options
  • Save latviancoder/a1dc59ada3eca0ce9f12e4924ab18d07 to your computer and use it in GitHub Desktop.
Save latviancoder/a1dc59ada3eca0ce9f12e4924ab18d07 to your computer and use it in GitHub Desktop.
import * as React from 'react';
import {
axisBottom, axisLeft, curveCatmullRom,
interpolateRdYlBu,
line,
max,
min,
ScaleLinear,
scaleLinear, scaleSequential,
scaleTime,
select
} from 'd3';
import { createRef, RefObject } from 'react';
import { ScaleTime } from 'd3-scale';
const svgWidth = 1000;
const svgHeight = 700;
interface IEntry {
high: number;
low: number;
date: Date;
}
type Data = IEntry[];
const data: Data = [
{
'high': 3,
'low': -1,
'date': new Date(2018, 0)
},
{
'high': 3,
'low': -2,
'date': new Date(2018, 1)
}
];
const margin = {
top: 30,
right: 30,
bottom: 30,
left: 30
};
const width = svgWidth - margin.left - margin.right;
const height = svgHeight - margin.top - margin.bottom;
class App extends React.Component {
private xAxisRef: RefObject<SVGGElement> = createRef();
private yAxisRef: RefObject<SVGGElement> = createRef();
private xScale: ScaleTime<number, number>;
private yScale: ScaleLinear<number, number>;
render() {
return (
<div>
{this.renderSvg()}
</div>
);
}
renderSvg() {
const yColorScale = scaleSequential(interpolateRdYlBu)
.domain([
40,
0
]);
this.xScale = scaleTime()
.range([0, width])
.domain([
min(data, d => d.date) as Date,
max(data, d => d.date) as Date
]);
this.yScale = scaleLinear()
.range([height, 0])
.domain([
min(data, d => d.low),
max(data, d => d.high)
]);
const highLine = line<IEntry>()
.curve(curveCatmullRom)
.x((e) => this.xScale(e.date))
.y((e) => this.yScale(e.high));
return <svg
width="100%"
height="100%"
preserveAspectRatio="none"
viewBox={`0 0 ${svgWidth} ${svgHeight}`}
>
<g transform={`translate(${margin.left}, ${margin.top})`}>
<g ref={this.xAxisRef} transform={`translate(0, ${height})`}/>
<g ref={this.yAxisRef}/>
<path d={highLine(data)} fill="none" stroke="#333" strokeWidth="3px"/>
{data.map((d, index) => <circle
key={index}
cx={this.xScale(d.date)}
cy={this.yScale(d.high)}
r={10}
fill={yColorScale(d.high)}
onClick={() => {
alert(d.high);
}}
/>)}
</g>
</svg>;
}
componentDidMount() {
select(this.xAxisRef.current).call(
axisBottom(this.xScale).ticks(12, '%B')
);
select(this.yAxisRef.current).call(
axisLeft(this.yScale)
);
}
}
export default App;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment