2018-10-15 04:24:18 +08:00
|
|
|
// Libraries
|
|
|
|
import $ from 'jquery';
|
|
|
|
import React, { PureComponent } from 'react';
|
|
|
|
|
|
|
|
// Types
|
2018-12-24 21:14:06 +08:00
|
|
|
import { TimeRange, TimeSeriesVMs } from '../../types';
|
2018-10-15 04:24:18 +08:00
|
|
|
|
|
|
|
interface GraphProps {
|
2018-10-15 14:22:20 +08:00
|
|
|
timeSeries: TimeSeriesVMs;
|
2018-10-15 04:24:18 +08:00
|
|
|
timeRange: TimeRange;
|
2018-11-06 00:46:09 +08:00
|
|
|
showLines?: boolean;
|
|
|
|
showPoints?: boolean;
|
|
|
|
showBars?: boolean;
|
2018-11-14 01:50:12 +08:00
|
|
|
width: number;
|
|
|
|
height: number;
|
2018-10-15 04:24:18 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
export class Graph extends PureComponent<GraphProps> {
|
2018-11-06 00:46:09 +08:00
|
|
|
static defaultProps = {
|
|
|
|
showLines: true,
|
|
|
|
showPoints: false,
|
|
|
|
showBars: false,
|
|
|
|
};
|
|
|
|
|
2018-12-25 15:55:44 +08:00
|
|
|
element: HTMLElement | null;
|
2018-10-15 04:24:18 +08:00
|
|
|
|
2018-11-14 01:50:12 +08:00
|
|
|
componentDidUpdate() {
|
|
|
|
this.draw();
|
2018-10-15 04:24:18 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
componentDidMount() {
|
|
|
|
this.draw();
|
|
|
|
}
|
|
|
|
|
|
|
|
draw() {
|
2018-12-25 15:55:44 +08:00
|
|
|
if (this.element === null) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2019-01-08 20:32:08 +08:00
|
|
|
const { width, timeSeries, timeRange, showLines, showBars, showPoints } = this.props;
|
2018-10-15 04:24:18 +08:00
|
|
|
|
2018-11-14 01:50:12 +08:00
|
|
|
if (!width) {
|
2018-10-15 14:22:20 +08:00
|
|
|
return;
|
|
|
|
}
|
2018-10-15 04:24:18 +08:00
|
|
|
|
2018-11-14 01:50:12 +08:00
|
|
|
const ticks = width / 100;
|
2018-10-15 04:24:18 +08:00
|
|
|
const min = timeRange.from.valueOf();
|
|
|
|
const max = timeRange.to.valueOf();
|
|
|
|
|
2018-11-06 00:46:09 +08:00
|
|
|
const flotOptions = {
|
|
|
|
legend: {
|
|
|
|
show: false,
|
|
|
|
},
|
|
|
|
series: {
|
|
|
|
lines: {
|
|
|
|
show: showLines,
|
|
|
|
linewidth: 1,
|
|
|
|
zero: false,
|
|
|
|
},
|
|
|
|
points: {
|
|
|
|
show: showPoints,
|
|
|
|
fill: 1,
|
|
|
|
fillColor: false,
|
|
|
|
radius: 2,
|
|
|
|
},
|
|
|
|
bars: {
|
|
|
|
show: showBars,
|
|
|
|
fill: 1,
|
|
|
|
barWidth: 1,
|
|
|
|
zero: false,
|
|
|
|
lineWidth: 0,
|
|
|
|
},
|
|
|
|
shadowSize: 0,
|
|
|
|
},
|
2018-10-15 04:24:18 +08:00
|
|
|
xaxis: {
|
|
|
|
mode: 'time',
|
|
|
|
min: min,
|
|
|
|
max: max,
|
|
|
|
label: 'Datetime',
|
|
|
|
ticks: ticks,
|
2018-12-25 15:55:44 +08:00
|
|
|
timeformat: timeFormat(ticks, min, max),
|
2018-10-15 04:24:18 +08:00
|
|
|
},
|
2018-11-06 00:46:09 +08:00
|
|
|
grid: {
|
|
|
|
minBorderMargin: 0,
|
|
|
|
markings: [],
|
|
|
|
backgroundColor: null,
|
|
|
|
borderWidth: 0,
|
|
|
|
// hoverable: true,
|
|
|
|
clickable: true,
|
|
|
|
color: '#a1a1a1',
|
|
|
|
margin: { left: 0, right: 0 },
|
|
|
|
labelMarginX: 0,
|
|
|
|
},
|
2018-10-15 04:24:18 +08:00
|
|
|
};
|
|
|
|
|
2018-11-06 00:46:09 +08:00
|
|
|
try {
|
2018-11-14 19:03:25 +08:00
|
|
|
console.log('Graph render');
|
2018-11-06 00:46:09 +08:00
|
|
|
$.plot(this.element, timeSeries, flotOptions);
|
|
|
|
} catch (err) {
|
|
|
|
console.log('Graph rendering error', err, flotOptions, timeSeries);
|
2019-01-08 20:32:08 +08:00
|
|
|
throw new Error('Error rendering panel');
|
2018-11-06 00:46:09 +08:00
|
|
|
}
|
2018-10-15 04:24:18 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
render() {
|
|
|
|
return (
|
|
|
|
<div className="graph-panel">
|
|
|
|
<div className="graph-panel__chart" ref={e => (this.element = e)} />
|
|
|
|
</div>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-11-06 14:23:02 +08:00
|
|
|
// Copied from graph.ts
|
2018-12-25 15:55:44 +08:00
|
|
|
function timeFormat(ticks: number, min: number, max: number): string {
|
2018-11-06 14:23:02 +08:00
|
|
|
if (min && max && ticks) {
|
|
|
|
const range = max - min;
|
|
|
|
const secPerTick = range / ticks / 1000;
|
|
|
|
const oneDay = 86400000;
|
|
|
|
const oneYear = 31536000000;
|
|
|
|
|
|
|
|
if (secPerTick <= 45) {
|
|
|
|
return '%H:%M:%S';
|
|
|
|
}
|
|
|
|
if (secPerTick <= 7200 || range <= oneDay) {
|
|
|
|
return '%H:%M';
|
|
|
|
}
|
|
|
|
if (secPerTick <= 80000) {
|
|
|
|
return '%m/%d %H:%M';
|
|
|
|
}
|
|
|
|
if (secPerTick <= 2419200 || range <= oneYear) {
|
|
|
|
return '%m/%d';
|
|
|
|
}
|
|
|
|
return '%Y-%m';
|
|
|
|
}
|
|
|
|
|
|
|
|
return '%H:%M';
|
|
|
|
}
|
|
|
|
|
2018-11-14 01:50:12 +08:00
|
|
|
export default Graph;
|