数据可视化中经常需要动态更新数据,而且在用户访问进程期间,页面保留历史状态,本文记录项目中使用Highcharts实时绘制数据的实现, 重绘历史数据部分待优化。
适用场景:一个坐标系多条竖曲线,动态从api获取更新的数据并加到曲线上,用户web浏览器在切换页面并回到曲线所在页面时重载所有历史数据,达成保持历史状态的目的。
优点:实现动态更新,不占用客户端浏览器存储
缺点:网络请求频繁
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script src="http://cdn.hcharts.cn/highcharts/highcharts.js"></script>
<div id="ChartContainer" class="chart"></div>
.chart {
height: 300px;
width: auto;
}
Highcharts.setOptions({
global: {
useUTC: false //关闭UTC
},
//图例中两条曲线分别使用的颜色
colors: [
'#78CEFE',
'#556FF6'
]
});
// 在配置文件中定义数据更新间隔
let updateInterval = globalConfig.UpdateInterval;
//时:分:秒数据格式
let format1 = '%H:%M:%S';
//时:分数据格式
let format2 = '%H:%M';
// X轴的起点为当天0点
let startTime = new Date(new Date().toLocaleDateString()).getTime();
// 当天23:59
let endTime = new Date(new Date().toLocaleDateString()).getTime() + 24 * 60 * 60 * 1000 - 1;
//全局定义曲线变量,以便在数据读取函数访问曲线变量
let dataChart;
//用来存储两条曲线的数据集,重载时批量重绘数据点
let data1 = [];
let data2 = [];
//Web页面加载完毕后绘制图表曲线
$(function() {
dataChart = Highcharts.chart('ChartContainer', {
chart: {
backgroundColor: 'transparent', //改变背景颜色
type: 'line',
zoomType: 'x', //在数据点较多时使用缩放
events: {
load: requestChargeData //使用加载事件加载后端历史数据
}
},
title: {
text: '某某曲线',
style: {
fontSize: '14px',
display: 'none'
}
},
xAxis: {
type: 'datetime',
tickPixelInterval: 10,
min: startTime,
max: endTime,
labels: {
style: {
fontSize: '10px',
color: '#707070'
},
formatter: function() {
return Highcharts.dateFormat(format2, this.value);
}
}
},
yAxis: {
reversed: false,
title: {
text: null
},
labels: {
style: {
fontSize: '10px',
color: '#707070'
}
},
lineWidth: 1
},
tooltip: {
formatter: function() {
return '<b>' + this.series.name + '</b><br/>' +
Highcharts.dateFormat('%Y-%m-%d %H:%M:%S', this.x) + '<br/>' +
Highcharts.numberFormat(this.y, 2) + '数据单位';
}
},
credits: {
enabled: false //不显示Highcharts LOGO
},
series: [{
// 设置数据的更新函数
data: (setInterval(async function() {
var result = await fetch('/api/dataset.json');
if (result.ok) {
var data = await chargeDischarge.json();
//读取最新更新的数据
var length = data.length;
var lastpoint1 = [new Date(data.set1[length - 1].time).getTime(), data.set1[length - 1].value * 1.0];
dataChart.series[0].addPoint(lastpoint1);
}
//activeLastPointToolip(dataChart);
}, updateInterval)),
name: '曲线1',
color: '#78CEFE',
marker: {
radius: 2, //曲线点半径,默认是4
}
}, {
//曲线2的data设置,
data: (setInterval(async function() {
var result = await fetch('/api/dataset.json');
if (result.ok) {
var data = await result.json();
//读取最新更新的数据
var length = data.set2.length;
var lastpoint2 = [new Date(data.set2[length - 1].time).getTime(), data.set2[length - 1].value * 1.0];
dataChart.series[1].addPoint(lastpoint2);
}
//activeLastPointToolip(dataChart);
}, updateInterval)),
name: '曲线2',
color: '#556FF6',
marker: {
radius: 2,
}
}]
});
});
//加载事件的回调函数,重绘当天所有数据点
async function requestData() {
var result = await fetch('/api/dataset.json');
if (result.ok) {
var data = await result.json();
//两条曲线都重绘当天所有数据
var i;
for (i = 0; i < data.length; i++) {
var point1 = [new Date(data.set1[i].time).getTime(), data.set1[i].value * 1.0];
data1.push(point1);
}
var j;
for (j = 0; j < data.discharge.length; j++) {
var point2 = [new Date(data.set2[j].time).getTime(), data.set2[j].value * 1.0];
data2.push(point2);
}
dataChart.series[0].setData(data1);
dataChart.series[1].setData(data2);
}
}