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

93 lines
2.0 KiB
JavaScript

import React, { Component } from 'react';
import ms from 'ms';
import { ResponsiveLine } from '@nivo/line';
import './Graph.css';
export default class Graph extends Component {
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: unprocessedData } = this.props;
const data = unprocessedData.map(([timestamp, latency]) => ({
x: timestamp,
y: latency,
})).reverse();
return [
{
id: 'latency',
color: 'hsl(220, 100%, 75%)',
data,
},
];
}
isSmallScreen() {
return this.state.screenWidth < 500;
}
render() {
const leftAxis = {
format: (d) => `${d}ms`,
tickCount: 3,
legend: 'latency',
legendPosition: 'center',
legendOffset: -55,
tickSize: 0,
};
return (
<div className="graph-container">
<ResponsiveLine
data={this.processData()}
margin={{ top: 30, left: this.isSmallScreen() ? 0 : 70, bottom: 50 }}
maxY="auto"
curve="monotoneX"
tooltipFormat={(d) => `${d}ms`}
axisLeft={this.isSmallScreen() ? null : leftAxis}
axisBottom={{
format: (epoch) => {
const interval = this.isSmallScreen() ? 7 : 5;
const minutesAgo = Math.floor((Date.now() - epoch) / (1000 * 60));
if (minutesAgo % interval !== 0 || minutesAgo === 0) {
return undefined;
}
return ms(Date.now() - epoch);
},
tickSize: 0,
legend: 'time ago',
legendPosition: 'center',
legendOffset: 40,
}}
enableDots={false}
enableArea
/>
</div>
);
}
}