datagod/src/charts/Trend.js
2020-12-08 19:03:51 +08:00

289 lines
8.9 KiB
JavaScript

import ReactEcharts from 'echarts-for-react';
import React from 'react';
import { Button, DatePicker, Row } from 'antd';
import {defaultDateFormat, TrendType} from './Base.js';
const { RangePicker } = DatePicker;
class Trend extends React.Component {
// constructor(props) {
// super(props);
// }
static defaultProps = {
datetype: true,
rangetype: true,
}
state = {
data: [],
type: {
current: TrendType.OneDate,
}
};
componentDidMount() {
// console.log(this.props);
if(this.props.datetype) {
var now = new Date()
this.selectDate( defaultDateFormat(now) )
} else if (this.props.rangetype) {
this.selectLately(7)
}
}
getOption(trendtype, data) {
var interval;
var fm ;
if(trendtype.current === TrendType.OneDate) {
interval = 3600 * 1000;
fm = function (value) {
var tp = new Date(value)
return tp.getHours()
};
} else {
interval = 3600 * 1000 * 24;
fm = function (value) {
var tp = new Date(value)
return (tp.getMonth() + 1) + "-" + tp.getDate()
};
}
var title = "趋势";
var title_concat = [];
var option = {
tooltip: {
trigger: 'axis',
// position: function (pt) {
// // console.log(pt);
// return [pt[0], '10%'];
// }
},
title: {
left: 'center',
text: title,
},
legend: {
orient: 'vertical',
x: 'left',
y: 'center',
data: [],
},
// toolbox: {
// feature: {
// dataZoom: {
// yAxisIndex: 'none'
// },
// restore: {},
// saveAsImage: {}
// }
// },
xAxis: {
type: 'time',
boundaryGap: false,
axisTick: {
alignWithLabel: true
},
interval: interval,
// data: tsdata
axisLabel: {
formatter: fm,
},
},
aria: {
show: true
},
yAxis: {
type: 'value',
padding: [10,0,0,0],
boundaryGap: [0, '100%'],
axisLabel: {
formatter: function (value) {
if( typeof value == "number") {
if(value >= 100000000) {
return (value / 100000000).toFixed(4) + "亿"
} else if(value >= 10000) {
return (value / 10000).toFixed(3) + "万"
} else {
return value
}
}
}
},
axisPointer: {
snap: true
}
},
// dataZoom: [{
// type: 'inside',
// start: 0,
// end: 100
// }, {
// start: 0,
// end: 100,
// handleIcon: 'M10.7,11.9v-1.3H9.3v1.3c-4.9,0.3-8.8,4.4-8.8,9.4c0,5,3.9,9.1,8.8,9.4v1.3h1.3v-1.3c4.9-0.3,8.8-4.4,8.8-9.4C19.5,16.3,15.6,12.2,10.7,11.9z M13.3,24.4H6.7V23h6.6V24.4z M13.3,19.6H6.7v-1.4h6.6V19.6z',
// handleSize: '0%',
// handleStyle: {
// color: '#fff',
// shadowBlur: 3,
// shadowColor: 'rgba(0, 0, 0, 0.8)',
// shadowOffsetX: 2,
// shadowOffsetY: 2
// }
// }],
series: [
]
};
for (var i = 0; i < data.length; i++) {
var d = data[i];
var unit = d.unit;
// var color = colors[i];
if(!d.values) {
continue;
}
var tvalues = []
for (var value of d.values) {
tvalues.push([value.time_point * 1000, value.value])
}
// if(trendtype.current === TrendType.OneDate) {
// console.log(tvalues.length);
// }
tvalues.sort();
if(trendtype.current === TrendType.OneDate) {
var last = new Date(tvalues[tvalues.length-1][0]);
last.setMinutes(0);
last.setSeconds(0);
last.setMilliseconds(0);
while(true){
var next = new Date(last.getTime() + 3600 * 1000)
if(last.getDate() === next.getDate()) {
tvalues.push([next.getTime(), 0])
last = next
} else {
// tvalues.push([next.getTime(), 0])
break
}
}
}
title_concat.push(d.name);
option.legend.data.push(d.name);
option.yAxis.name = unit;
var sdata = {
name: d.name,
type: 'line',
smooth: true,
symbol: 'none',
// sampling: 'average',
areaStyle: {
},
data: tvalues
}
option.series.push(sdata)
}
option.title.text = title + `(${title_concat.join(",")})`
return option;
}
selectDate(date) {
if(this.props.trendurl) {
var qdate;
if(this.props.query) {
qdate = this.props.query.date?this.props.query.date:"date";
} else {
qdate = "date"
}
fetch(`${this.props.trendurl}?${qdate}=${date}`).then((response) => {
if (response.ok) {
response.json().then((response) => {
if (response.code === 0) {
this.setState({ data: response.data.trends, type: {current: TrendType.OneDate} })
}
})
}
});
}
}
selectRangeDate(start, end) {
if(this.props.trendurl) {
var qstart, qend;
if(this.props.query) {
qstart = this.props.query.start?this.props.query.start:"start";
qend = this.props.query.end?this.props.query.end:"end";
} else {
qstart = "start"
qend = "end"
}
fetch(`${this.props.trendurl}?${qstart}=${start}&${qend}=${end}`).then((response) => {
if (response.ok) {
response.json().then((response) => {
if (response.code === 0) {
this.setState({ data: response.data.trends, type: {current: TrendType.RangeDate }})
}
})
}
});
}
}
selectLately(days) {
var now = new Date();
var end = defaultDateFormat(now)
now -= 3600 * 24 * 1000 * days
var start = defaultDateFormat(new Date(now))
this.selectRangeDate(start, end);
}
render() {
const { datetype, rangetype } = this.props;
const { data, type } = this.state;
return (
<div id={this.props.id?this.props.id:undefined} style={{height: "100%", pointerEvents: "inherit"}}>
<Row style={{marginLeft: "6%", marginBottom: "10px"}}>
{ (() => { if(datetype) return <Button onClick={ () => this.selectDate(defaultDateFormat(new Date()))} >今天</Button>})() }
{ (() => { if(rangetype) return <Button onClick={ () => {this.selectLately(7);} }>7</Button> })() }
{ (() => { if(rangetype) return <Button onClick={ () => {this.selectLately(30);} }>30</Button> })() }
{ (() => { if(datetype) return <DatePicker onChange = {(moment, daterange) => { this.selectDate(daterange); }} size="small" style={{marginLeft: "5px"}} /> } )()}
{ (() => { if(rangetype) return <RangePicker onChange = {(moment, daterange) => { this.selectRangeDate(daterange[0], daterange[1]) }} size="small" style={{marginLeft: "5px"}} /> })() }
</Row>
<ReactEcharts
notMerge={true}
lazyUpdate={true}
option={this.getOption(type, data)}
style={{ width: "100%", minHeight: "90vh", marginBottom: "50px" }}
/>
</ div>
)
}
}
export default Trend;