95 lines
2.2 KiB
JavaScript
95 lines
2.2 KiB
JavaScript
|
import React, { Component } from 'react';
|
||
|
|
||
|
import './Graph.css';
|
||
|
|
||
|
import { curveNatural } from '@vx/curve';
|
||
|
import { GradientOrangeRed } from '@vx/gradient';
|
||
|
import { AxisLeft, AxisBottom } from '@vx/axis';
|
||
|
import { Group } from '@vx/group';
|
||
|
import { AreaClosed } from '@vx/shape';
|
||
|
import { scaleTime, scaleLinear } from '@vx/scale';
|
||
|
import { extent, max } from 'd3-array';
|
||
|
|
||
|
const x = ([timestamp,]) => new Date(timestamp);
|
||
|
const y = ([, latency]) => latency;
|
||
|
|
||
|
const margin = {
|
||
|
top: 0,
|
||
|
bottom: 50,
|
||
|
left: 50,
|
||
|
right: 0,
|
||
|
};
|
||
|
|
||
|
const tick = {
|
||
|
textAnchor: 'middle',
|
||
|
fontSize: 8,
|
||
|
fontFamily: 'system-ui, sans-serif',
|
||
|
};
|
||
|
|
||
|
const leftTick = {
|
||
|
...tick,
|
||
|
dx: '-0.25em',
|
||
|
dy: '0.25em',
|
||
|
textAnchor: 'end',
|
||
|
};
|
||
|
|
||
|
const label = {
|
||
|
...tick,
|
||
|
fontSize: 10,
|
||
|
};
|
||
|
|
||
|
export default class Graph extends Component {
|
||
|
constructor(props) {
|
||
|
super(props);
|
||
|
|
||
|
const { width, height, data } = props;
|
||
|
this.xMax = width - margin.left - margin.right;
|
||
|
this.yMax = height - margin.top - margin.bottom;
|
||
|
|
||
|
this.xScale = scaleTime({
|
||
|
range: [0, this.xMax],
|
||
|
domain: extent(data, x),
|
||
|
});
|
||
|
this.yScale = scaleLinear({
|
||
|
range: [this.yMax, 0],
|
||
|
domain: [0, max(data, y)],
|
||
|
nice: true,
|
||
|
});
|
||
|
}
|
||
|
|
||
|
render() {
|
||
|
return (
|
||
|
<svg className="graph" width={this.props.width} height={this.props.height}>
|
||
|
<GradientOrangeRed id="gradient"/>
|
||
|
|
||
|
<Group top={margin.top} left={margin.left}>
|
||
|
<AreaClosed
|
||
|
data={this.props.data}
|
||
|
xScale={this.xScale} yScale={this.yScale}
|
||
|
x={x} y={y}
|
||
|
stroke=""
|
||
|
fill="url(#gradient)"
|
||
|
curve={curveNatural}
|
||
|
/>
|
||
|
<AxisLeft
|
||
|
scale={this.yScale}
|
||
|
top={0} left={0}
|
||
|
labelProps={label}
|
||
|
tickFormat={(value, index) => `${value}ms`}
|
||
|
tickLabelProps={(value, index) => leftTick}
|
||
|
label=''
|
||
|
/>
|
||
|
<AxisBottom
|
||
|
scale={this.xScale}
|
||
|
top={this.yMax}
|
||
|
tickFormat={(value, index) => `${value.toLocaleTimeString()}`}
|
||
|
labelProps={label}
|
||
|
tickLabelProps={(value, index) => tick}
|
||
|
label=''
|
||
|
/>
|
||
|
</Group>
|
||
|
</svg>
|
||
|
);
|
||
|
}
|
||
|
}
|