elstat/priv/frontend/src/components/Graph.js

100 lines
2.3 KiB
JavaScript

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import ms from 'ms';
import {
ResponsiveContainer,
AreaChart,
XAxis,
YAxis,
CartesianGrid,
Tooltip,
Area,
ReferenceLine,
} from 'recharts';
import './Graph.css';
export default class Graph extends Component {
static propTypes = {
data: PropTypes.arrayOf(PropTypes.arrayOf(PropTypes.number)).isRequired,
}
state = {
screenWidth: window.innerWidth,
}
componentDidMount() {
window.addEventListener('resize', this.handleScreenChange);
}
componentWillUnmount() {
window.removeEventListener('resize', this.handleScreenChange);
}
handleScreenChange = () => {
this.setState({
screenWidth: window.innerWidth,
});
}
processData() {
const { data } = this.props;
return data.map(([timestamp, latency]) => ({
timestamp,
latency,
})).sort(({ timestamp: a }, { timestamp: b }) => a - b);
}
isSmallScreen() {
return this.state.screenWidth < 500;
}
render() {
return (
<div className="graph-container">
<ResponsiveContainer width="100%" height={175}>
<AreaChart
data={this.processData()}
>
<XAxis
dataKey="timestamp"
tickFormatter={(tick) => ms(Date.now() - tick)}
tickLine={false}
/>
{this.isSmallScreen()
? null
: <YAxis
dataKey="latency"
tickLine={false}
tickFormatter={(tick) => `${tick}ms`}
/>
}
<CartesianGrid strokeDasharray="1 1" />
<Tooltip
isAnimationActive={false}
formatter={(value) => `${value}ms`}
label="DAB"
separator=": "
labelFormatter={() => null}
/>
<ReferenceLine
y={1000}
label="1s"
stroke="pink"
/>
<Area
type="monotone"
dataKey="latency"
stroke="hsla(200, 100%, 55%, 1)"
fill="hsl(200, 100%, 85%)"
isAnimationActive={false}
/>
</AreaChart>
</ResponsiveContainer>
</div>
);
}
}