import React, { Component } from 'react'; import PropTypes from 'prop-types'; import ms from 'ms'; import { ResponsiveLine } from '@nivo/line'; 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: unprocessedData } = this.props; const data = unprocessedData.map(([timestamp, latency]) => ({ x: timestamp, y: latency, })).sort(({ x: a }, { x: b }) => a - b); 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, }; const minutesAllocated = []; return (
`${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 || minutesAllocated.includes(minutesAgo)) { return ''; } minutesAllocated.push(minutesAgo); return ms(Date.now() - epoch); }, tickSize: 0, legend: 'time ago', legendPosition: 'center', legendOffset: 40, }} enableDots={false} enableArea />
); } }