环境:Highcharts 5.0.6
第一:x轴是时间点(形如 23:12:29 格式)
第二:x轴是变化的
第三:x轴的值是从服务中获取
这里贴上最核心的逻辑(因为时间比较赶,没有深入研究官方文档,只经过测试,这里是核心)
大概实现逻辑,是通过
window.setInterval(getForm, 500);
定时的向服务器发送请求(getForm函数里面是个ajax请求),不断获取最新的数据点信息(包含x轴、y轴信息),将数据点插入图表数据集合中,然后重新渲染图表。
接着,上图中的函数getForm,内容如下:
var value = Number(data[i].c_tagval);
//alert(tval);
var createtime = data[i].c_createtime;
//获取服务器的数字型的时间,应为highcharts处理时间,用long,
createtime = parseInt(createtime);
console.info(createtime);
/*
//生成UI端自己的时间,这样做会和服务器的不一致
var mydate = new Date();
tm = mydate.getTime();
*/
// 第2个参数(是否重绘)个当添加多个值时,应设为false;第3个参数true时,添加时自动将第一个删除
// 其实文档上说是可以传入多个值的,有待测试
series.addPoint([ createtime, value ], false, true);
//图表重新渲染
chart.redraw();
上面的代码是从服务器中获取的点值,createtime 是x坐标,value是y坐标;需要注意的是createtime 是要在x轴上,x轴的type属性是datetime,目前测试,时间只支持int,故需要将服务器的createtime (字符串)转成int(必须手动转换!!!),我这里使用
createtime = parseInt(createtime);
,
又由于我们的x轴格式是形如时:分:秒,故需要将控件的x轴进行如下设置:
xAxis : {
type : 'datetime',
title : {
text : '时间'
},
labels : {
formatter : function() {
//获取当前轴的值
var s = this.value;
//浏览器上输出日志
//console.info(s);
var date = new Date(s);
return date.getHours() + ':' + date.getMinutes() + ':' + date.getSeconds();
}
},
showLastLabel : true,
maxPadding : 0.05
},
还有一点需要注意:
由于从服务器获取数据时,将新的点插入图表时,使用的
// 第2个参数(是否重绘)个当添加多个值时,应设为false;第3个参数true时,添加时自动将第一个删除
// 其实文档上说是可以传入多个值的,有待测试
series.addPoint([ createtime, value ], false, true);
每添加一个新值,就会删除掉第一个值,这是第二个参数为true时的特性。
因为我们不能设为false,不然x轴的坐标会越来越密,这不是我们想要的。
但因为我们设为true了,所以图表初始状态时(图表渲染初期,还为从服务器获取值时),必须提前有一些无效的数据,让图表拥有一个默认的x轴个数,不然图表就永远只有刚刚从服务器获取的那一个点了。
初始化默认值的代码如下:
//设定报表对象的初始数据
series : [ {
data : [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0, 0, 0, 0, 0, 0, 0]
}
下面列出所有js代码(复习时候,值关系核心逻辑即可,不要在意业务细节):
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<script type="text/javascript"
src="${pageContext.request.contextPath}/util/jquery-1.9.1.js"></script>
<script type="text/javascript" src="${pageContext.request.contextPath}/util/Highcharts-5.0.6/highcharts.js"></script>
<script type="text/javascript"
src="${pageContext.request.contextPath}/util/Highcharts-5.0.6/themes/dark-blue.js"></script>
</head>
<body>
<div id="container"
style="min-width: 310px; height: 400px; margin: 0 auto"></div>
</body>
<script type="text/javascript">
//<![CDATA[
$(function() {
//js定时函数的id值
var intv;
var chartType = [
{
yAxis_min:100,yAxis_max:500,
yAxis_tickInterval:50,
yAxis_plotBands_low_from:0, yAxis_plotBands_low_to:200,
yAxis_plotBands_high_from:400, yAxis_plotBands_high_to:500
},{
yAxis_min:0,yAxis_max:80,
yAxis_tickInterval:10,
yAxis_plotBands_low_from:0, yAxis_plotBands_low_to:20,
yAxis_plotBands_high_from:60, yAxis_plotBands_high_to:80
},
{
yAxis_min:0,yAxis_max:5,
yAxis_tickInterval:0.5,
yAxis_plotBands_low_from:0, yAxis_plotBands_low_to:2,
yAxis_plotBands_high_from:4, yAxis_plotBands_high_to:5
},{
yAxis_min:0,yAxis_max:5,
yAxis_tickInterval:1,
yAxis_plotBands_low_from:0, yAxis_plotBands_low_to:1,
yAxis_plotBands_high_from:4, yAxis_plotBands_high_to:5
},{
yAxis_min:0,yAxis_max:3,
yAxis_tickInterval:0.1,
yAxis_plotBands_low_from:0, yAxis_plotBands_low_to:0.5,
yAxis_plotBands_high_from:2, yAxis_plotBands_high_to:3
},{
yAxis_min:5,yAxis_max:20,
yAxis_tickInterval:5,
yAxis_plotBands_low_from:5, yAxis_plotBands_low_to:10,
yAxis_plotBands_high_from:18, yAxis_plotBands_high_to:20
}];
//y轴低值区域的from
var yAxis_plotBands_normal_from = '${min}';
// y轴低值区域的to
var yAxis_plotBands_normal_to = '${max}';
//序号
var index = '${chartType}';
//y轴最小值
var yAxis_min = chartType[index-1].yAxis_min;
// y轴最大值
var yAxis_max = chartType[index-1].yAxis_max;
// y轴步长
var yAxis_tickInterval = chartType[index-1].yAxis_tickInterval;
//y轴低值区域的from
var yAxis_plotBands_low_from = chartType[index-1].yAxis_plotBands_low_from;
// y轴低值区域的to
var yAxis_plotBands_low_to = chartType[index-1].yAxis_plotBands_low_to;
//y轴低值区域的from
var yAxis_plotBands_high_from = chartType[index-1].yAxis_plotBands_high_from;
// y轴低值区域的to
var yAxis_plotBands_high_to = chartType[index-1].yAxis_plotBands_high_to;
Highcharts.setOptions({
global : {
useUTC : false
}
});
//声明报表对象
var chart = new Highcharts.Chart({
chart : {
//将报表对象渲染到层上
renderTo : 'container',
defaultSeriesType : 'spline'
}, //chart end
title : {
text : '实时曲线'
},
yAxis : {
title : {
text : '值'+'${unit}'
},
labels : {
formatter : function() {
if (this.value > 400){
return '<div style="color:red">' + this.value+ '</div>';
}else if(this.value < 200){
return '<div style="color:grey">' + this.value+ '</div>';
}else if(this.value <= 360 && this.value>=340){
return '<div style="color:green">' + this.value+ '</div>';
}
return this.value;
}
},
//tickPositions: [-10,0, 10,20,30,40, 50,60,70,80,90,100,110,120]
min : yAxis_min, //最小
tickInterval : yAxis_tickInterval, //步长
//max : 120,
max:yAxis_max,
/************************begin ************************/
plotBands : [ {
from : yAxis_plotBands_low_from,
to : yAxis_plotBands_low_to,
color : 'rgba(168, 255, 213, 0.3)',
label : {
text : '偏低',
style : {
color : '#ffffff'
}
}
}, {
from : yAxis_plotBands_normal_from,
to : yAxis_plotBands_normal_to,
color : 'rgba(68, 70, 213, 0.3)',
label : {
text : '正常',
style : {
color : '#41C639'
}
}
}, {
from : yAxis_plotBands_high_from,
to : yAxis_plotBands_high_to,
color : 'rgba(255, 97, 0, 0.3)',
label : {
text : '偏高',
style : {
color : '#FF0000'
}
}
} ]
/************************ end ************************/
},
xAxis : {
type : 'datetime',
title : {
text : '时间'
},
labels : {
formatter : function() {
//获取当前轴的值
var s = this.value;
//浏览器上输出日志
//console.info(s);
var date = new Date(s);
return date.getHours() + ':' + date.getMinutes() + ':' + date.getSeconds();
}
},
showLastLabel : true,
maxPadding : 0.05
},
legend : {
enabled : false
},
tooltip : {
headerFormat : '<br/>',
pointFormat : '{point.x} : {point.y} '
},
/* plotOptions: {
spline: {
marker: {
enable: false
}
}
}, */
//设定报表对象的初始数据
series : [ {
data : [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0, 0, 0, 0, 0, 0, 0]
} ]
});
//Highcharts.Chart end
//获取后台数据
function getForm() {
var url = "${pageContext.request.contextPath}/mydemo/xxx.do";
$.ajax({
type : "Post",
//后台获取数据的函数,注意当对该页面重命名时,
//必须手动更改该选项
url : url,
contentType : "application/json; charset=utf-8",
dataType : "json",
//成功获取数据
success : function(dataa) {
addpoint(dataa.result);
},
//显示错误
error : function(err) {
clearInterval(intv);
///alert(err + "调用后台程序出现错误,请尝试刷新!");
}
});
}
function addpoint(data) {
if (data && data.length > 0) {
var series = chart.series[0];
for(var i=0;i<data.length;i++)
{
var value = Number(data[i].c_tagval);
//alert(tval);
var createtime = data[i].c_createtime;
//获取服务器的数字型的时间,应为highcharts处理时间,用long,
createtime = parseInt(createtime);
console.info(createtime);
/*
//生成UI端自己的时间,这样做会和服务器的不一致
var mydate = new Date();
var a = mydate;
a.setSeconds(a.getSeconds()+1);
tm = a.getTime();
*/
// 第2个参数(是否重绘)个当添加多个值时,应设为false;第3个参数true时,添加时自动将第一个删除
// 其实文档上说是可以传入多个值的,有待测试
series.addPoint([ createtime, value ], false, true);
//图表重新渲染
chart.redraw();
}
}
}
$(document).ready(function() {
//只调用一次
//getForm();
//每隔3秒自动调用方法,实现图表的实时更新
intv = window.setInterval(getForm, 500);
});
});
//]]>
</script>
</html>
下面贴上从服务器获取的json的数据格式:
{
"message":"Update Successfully!",
"result":[{
"c_createtime":"1547005150000",
"c_id":"123",
"c_tagid":"1000",
"c_tagval":"30",
"c_wide1":"xxx",
"c_wide2":"xxx",
"c_wide3":"xxx"
}],
"status":"Success"
}
总结:
这里特殊说明,最初我试图使用规范的形如2019/10/10 23:21:30的字符串格式传送给js端处理,但是无效,倒不是实现不了,就是测试发现很复杂:
第一:字符串格式转js的对象日期,构造函数有两种:new Date('字符串')和new Date(多个字符串参数),只有传单纯的毫秒时是一个参数,且两种方式正好统一;其他格式的日期都和浏览器的本地化有关,反正浏览器不认识就返回给你NAN(又是罪恶的IE!!!,Firefox、chrome浏览器没问题,)
第二:即便你碰巧了,使用浏览器本地化格式的日期字符串格式,那么依然存在问题。那就是x轴的默认值无法转换成相应的的日期格式。
故我改成了直接传时间格式为毫秒的字符串。
updateDate:2019/01/10:
后期还发现个问题:
鼠标移动上去,发现x轴的值的日期的毫秒,不是和x轴显示的坐标一致,是日期的毫秒形式.
解决方案:
修改原有的tooltip属性:
tooltip : {
formatter: function () {
var date = new Date(this.x);
var a = date.getHours() + ':' + date.getMinutes() + ':' + date.getSeconds();
//console.info(a);
return "( "+a+" , "+this.y+" )";
//var s = '<b>' + this.x + '---xx</b>';
//return s;
},
shared: true,
//pointFormat : '{point.x} :: {point.y} '
headerFormat : '<br/>',
},
而且发现:原有的xAxis属性中的labels没啥卵用,已经被注视掉了,其他没变化:
xAxis : {
type : 'datetime',
title : {
text : '时间'
},
/*
//没啥卵用
labels : {
formatter : function() {
//获取当前轴的值
var createtime = this.value;
createtime = parseInt(createtime);
console.info(createtime);
var date = new Date(createtime);
return date.getHours() + ':' + date.getMinutes() + ':' + date.getSeconds();
}
}, */
showLastLabel : true,
maxPadding : 0.05
},
贴出所有代码:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<script type="text/javascript"
src="${pageContext.request.contextPath}/util/jquery-1.9.1.js"></script>
<script type="text/javascript" src="${pageContext.request.contextPath}/util/Highcharts-5.0.6/highcharts.js"></script>
<script type="text/javascript"
src="${pageContext.request.contextPath}/util/Highcharts-5.0.6/themes/dark-blue.js"></script>
</head>
<body>
<div id="container"
style="min-width: 310px; height: 400px; margin: 0 auto"></div>
</body>
<script type="text/javascript">
//<![CDATA[
$(function() {
//js定时函数的id值
var intv;
var chartType = [
{
yAxis_min:100,yAxis_max:500,
yAxis_tickInterval:50,
yAxis_plotBands_low_from:0, yAxis_plotBands_low_to:200,
yAxis_plotBands_high_from:400, yAxis_plotBands_high_to:500
},{
yAxis_min:0,yAxis_max:80,
yAxis_tickInterval:10,
yAxis_plotBands_low_from:0, yAxis_plotBands_low_to:20,
yAxis_plotBands_high_from:60, yAxis_plotBands_high_to:80
},
{
yAxis_min:0,yAxis_max:5,
yAxis_tickInterval:0.5,
yAxis_plotBands_low_from:0, yAxis_plotBands_low_to:2,
yAxis_plotBands_high_from:4, yAxis_plotBands_high_to:5
},{
yAxis_min:0,yAxis_max:5,
yAxis_tickInterval:1,
yAxis_plotBands_low_from:0, yAxis_plotBands_low_to:1,
yAxis_plotBands_high_from:4, yAxis_plotBands_high_to:5
},{
yAxis_min:0,yAxis_max:3,
yAxis_tickInterval:0.1,
yAxis_plotBands_low_from:0, yAxis_plotBands_low_to:0.5,
yAxis_plotBands_high_from:2, yAxis_plotBands_high_to:3
},{
yAxis_min:5,yAxis_max:20,
yAxis_tickInterval:5,
yAxis_plotBands_low_from:5, yAxis_plotBands_low_to:10,
yAxis_plotBands_high_from:18, yAxis_plotBands_high_to:20
}];
//y轴低值区域的from
var yAxis_plotBands_normal_from = '${min}';
// y轴低值区域的to
var yAxis_plotBands_normal_to = '${max}';
//序号
var index = '${chartType}';
//y轴最小值
var yAxis_min = chartType[index-1].yAxis_min;
// y轴最大值
var yAxis_max = chartType[index-1].yAxis_max;
// y轴步长
var yAxis_tickInterval = chartType[index-1].yAxis_tickInterval;
//y轴低值区域的from
var yAxis_plotBands_low_from = chartType[index-1].yAxis_plotBands_low_from;
// y轴低值区域的to
var yAxis_plotBands_low_to = chartType[index-1].yAxis_plotBands_low_to;
//y轴低值区域的from
var yAxis_plotBands_high_from = chartType[index-1].yAxis_plotBands_high_from;
// y轴低值区域的to
var yAxis_plotBands_high_to = chartType[index-1].yAxis_plotBands_high_to;
Highcharts.setOptions({
global : {
useUTC : false
}
});
//声明报表对象
var chart = new Highcharts.Chart({
chart : {
//将报表对象渲染到层上
renderTo : 'container',
defaultSeriesType : 'spline'
}, //chart end
title : {
text : '实时曲线'
},
yAxis : {
title : {
text : '值'+'${unit}'
},
labels : {
formatter : function() {
if (this.value > 400){
return '<div style="color:red">' + this.value+ '</div>';
}else if(this.value < 200){
return '<div style="color:grey">' + this.value+ '</div>';
}else if(this.value <= 360 && this.value>=340){
return '<div style="color:green">' + this.value+ '</div>';
}
return this.value;
}
},
//tickPositions: [-10,0, 10,20,30,40, 50,60,70,80,90,100,110,120]
min : yAxis_min, //最小
tickInterval : yAxis_tickInterval, //步长
//max : 120,
max:yAxis_max,
/************************begin ************************/
plotBands : [ {
from : yAxis_plotBands_low_from,
to : yAxis_plotBands_low_to,
color : 'rgba(168, 255, 213, 0.3)',
label : {
text : '偏低',
style : {
color : '#ffffff'
}
}
}, {
from : yAxis_plotBands_normal_from,
to : yAxis_plotBands_normal_to,
color : 'rgba(68, 70, 213, 0.3)',
label : {
text : '正常',
style : {
color : '#41C639'
}
}
}, {
from : yAxis_plotBands_high_from,
to : yAxis_plotBands_high_to,
color : 'rgba(255, 97, 0, 0.3)',
label : {
text : '偏高',
style : {
color : '#FF0000'
}
}
} ]
/************************ end ************************/
},
xAxis : {
type : 'datetime',
title : {
text : '时间'
},
/*
//没啥卵用
labels : {
formatter : function() {
//获取当前轴的值
var createtime = this.value;
createtime = parseInt(createtime);
console.info(createtime);
var date = new Date(createtime);
return date.getHours() + ':' + date.getMinutes() + ':' + date.getSeconds();
}
}, */
showLastLabel : true,
maxPadding : 0.05
},
legend : {
enabled : false
},
tooltip : {
formatter: function () {
var date = new Date(this.x);
var a = date.getHours() + ':' + date.getMinutes() + ':' + date.getSeconds();
//console.info(a);
return "( "+a+" , "+this.y+" )";
//var s = '<b>' + this.x + '---xx</b>';
//return s;
},
shared: true,
//pointFormat : '{point.x} :: {point.y} '
headerFormat : '<br/>',
},
/* plotOptions: {
spline: {
marker: {
enable: false
}
}
}, */
//设定报表对象的初始数据
series : [ {
data : [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0, 0, 0, 0, 0, 0, 0]
} ]
});
//Highcharts.Chart end
//获取后台数据
function getForm() {
var url = "${pageContext.request.contextPath}/mydemo/xx.do";
$.ajax({
type : "Post",
//后台获取数据的函数,注意当对该页面重命名时,
//必须手动更改该选项
url : url,
contentType : "application/json; charset=utf-8",
dataType : "json",
//成功获取数据
success : function(dataa) {
addpoint(dataa.result);
},
//显示错误
error : function(err) {
clearInterval(intv);
///alert(err + "调用后台程序出现错误,请尝试刷新!");
}
});
}
function addpoint(data) {
if (data && data.length > 0) {
var series = chart.series[0];
for(var i=0;i<data.length;i++)
{
var value = Number(data[i].c_tagval);
var createtime = data[i].c_createtime;
//获取服务器的数字型的时间,应为highcharts处理时间,用long,
createtime = parseInt(createtime);
//console.info('---'+createtime);
//生成UI端自己的时间,这样做会和服务器的不一致
//var mydate = new Date();
//createtime = mydate.getTime();
// 第2个参数(是否重绘)个当添加多个值时,应设为false;第3个参数true时,添加时自动将第一个删除
// 其实文档上说是可以传入多个值的,有待测试
series.addPoint([ createtime, value ], false, true);
//图表重新渲染
chart.redraw();
}
}else{
if(pagenum > 3){
pagenum = 0;
}
}
}
$(document).ready(function() {
//只调用一次
//getForm();
//每隔3秒自动调用方法,实现图表的实时更新
intv = window.setInterval(getForm, 500);
});
});
//]]>
</script>
</html>