使用HighCharts实现实时数据展示

在众多的工业控制系统领域常常会实时采集现场的温度、压力、扭矩等数据,这些数据对于监控人员进行现场态势感知、进行未来趋势预测具有重大指导价值。工程控制人员如果只是阅读海量的数据报表,对于现场整个态势的掌控会十分困难,因此往往希望借助一些图表进行展示,其中趋势图是常用的实时数据展示方式之一。目前实现趋势图、曲线图的工具很多也很成熟,一些是通过CS模式开发的,需要在工程控制人员操作的计算机上安装相应软件,这种方式有其特有的优势,但是有时也有不方便的地方。于是一些基于BS模式的展现方式就自然而然的被广泛应用起来。采用BS模式的展现方式工程控制人员可以通过任何一台可以连接Web服务器的PC,通过常用的浏览器就可以实时的查看当前环境现场的各种指标参数,其便利性是显而易见的。下面我就介绍一下这种BS模式的实时数据展现曲线图的方法。由于本文的目的不是去实现一个现场环境可用的应用产品,因此只是针对涉及的技术进行讲解,起一个指导作用,因此参考者请依据自己项目的实际需要对本文章涉及的代码进行优化使用。
     
在通过BS系统实现趋势图、曲线图的可选方案很多,本文主要通过Highcharts.com旗下的Highcharts
API包来实现。由于此包是通过JS脚本实现的,因此个人认为相对来说适应面可能更好,当然通过诸如jFreeChart这类工具也是可以实现的。
     
言归正传,我们来讲解如何通过Highcharts
API实现趋势图在页面上的呈现。
     
首先我们需要简单规划一下我们系统的架构。由于实现实时数据的趋势图呈现,因此系统大致我们可以设计成三层:显示层、逻辑层、数据源。如下图所示:

显示层就是将数据呈现给工程控制人员的的展示页面,这层主要由JSP、JS、CSS等文件构成,工程控制人员通过浏览器(诸如IE、火狐等)就能直接看到希望的曲线图。显示层只负责显示,而显示需要的数据是经过一定清洗、规格化的,显示层拿到符合规格化要求的数据后,就可以直接进行显示,并响应和人的交互。数据的清洗、规格化工作都是在逻辑层中实现,逻辑层通过获取的数据源信息,进行必要的数据逻辑转换、数据清洗、数据规格化处理。数据源是一个复杂的重要的,它可以是直接来自下位机的数据通讯,也可以是下位机将数据存储在中间数据库中,也可以是一系列的数据文件。
     
在本文中只是模拟数据源,并不是实现数据源的读取。并且对应逻辑层的处理,也进行了忽略,这部分内容因为涉及具体的数据获取、清洗、转换、规格化,和具体工程项目的需求有较大关系,加之也不是本文规划的中心,因此此部分代码设计实现本文也不涉及。
     
显示层的实现涉及到JSON、JQuery、Highcharts,我们首先建立一个标准的Web应用(其实如果作为例子,使用一个html文件也行,此处本人计划后期会扩展本案例,实现后续一些诸如逻辑层的功能,因此建立了一个Web应用工程,有点画蛇添足,还请见谅)。本人采用Netbeans
IDE 7.2版本开发(如何用Netbeans IDE开发Web应用请参考本人其它文章),因此建立完成后的工程结构如下:

要使用Highcharts,我们需要导入highcharts.js文件。highcharts.js文件可以从Highcharts官网获得(官网地址:http://www.highcharts.com/),从官网下载的压缩文件中包含有我们开发需要的highcharts.js文件外,还包含一些其它的文件,诸如例子文件等。
     
Highcharts是使用js来实现的,同时应用到了JQuery技术,因此还需要去获得最新版的JQuery包(官网地址:http://jquery.com/)。
     
以上两块准备好后,我们将其加入新建的工程中,在工程文件中我们规划了一个放置所有js文件的地方,有一个js目录,将highcharts.js、jquery-1.8.3.min.js文件都放置到此目录下。大家看到我的工程中在js目录下有一个modules子目录,此子目录下放置的exporting.js文件是可有可无的,如果大家要使用将图表导出等功能就需要使用此文件,因此需要导入工程中,否则完全可以不需要。
    
工程环境准备停当,我们就可以打开本工程的默认,也是唯一的一个jsp页面,对此页面做一个编写修改。主要修改有如下几个地方:
    
第一,在jsp页面头部引入highcharts.js、jquery-1.8.3.min.js文件,应用代码参考如下:

<scripttype="text/javascript"src="http://zhaowenbinmail.blog.163.com/blog/js/jquery-1.8.3.min.js"></script>

<scriptsrc="http://zhaowenbinmail.blog.163.com/blog/js/highcharts.js"></script>

第二,在jsp页面的Body体中加入一个div元素,highcharts将在这个div元素中绘制曲线图。

<divid="container"style="min-width:100px;
height:400px; margin:0auto"></div>

注意:我们为这个div指定了一个id值,这个id值将来对我们很有用,它是使highcharts知道在何处绘制图表的根源。
    
第三,我们需要在jsp页面中加入我们自己的js文件。这个文件用来实现特定的业务呈现逻辑。

<scripttype="text/javascript"src="http://zhaowenbinmail.blog.163.com/blog/js/chart.js"></script>

现在我来讲解一下我需要实现的业务的大体需求。我需要在页面上显示大桥表面一天24小时的温度变化情况(当然这些温度值的变化本案例中都是通过随机数来产生的)。在我们的很轴方向上需要显示从0点开始到晚上23点的时间刻度,并且要求固定就显示0到23这24个刻度,在纵轴方向显示桥面传感器检测到的本小时内温度最大值,然后模拟时间推移显示每小时的温度变化曲线图。
    
依据以上需求分析,在页面呈现时,我们就要去读取本天从0点开始到当前时刻的数据,并将数据绘制显示成曲线图。因此我们接下来就要编辑我们自己的js文件——chart.js。在此文件中创建Highcharts对象,通过设置相关的属性来影响曲线图的呈现,使其满足我们的需求要求。
    
我们首先定义一个全局的图表对象,我们命名为chart,同时示例化Highcharts对象,具体见下面代码:

var chart;

$(function(){
$(document).ready(function(){

chart =newHighcharts.Chart({
chart:{
renderTo:‘container‘,
type:‘line‘,

marginRight:130,

marginBottom:80,
events:{

load:loadTime
}
},
title:{
text:‘大桥采集数据‘,
x:-20
},

subtitle:{
text:‘传感器编号: 传感器1‘,
x:-20
},
xAxis:{
title:{

enabled:true,

text:‘时间(小时)‘
},
max:23,
min:0,

tickPixelInterval:50
},

yAxis:{
title:{
text:‘压力 (℃)‘
},

plotLines:[{
value:0,
width:1,
color:‘#808080‘
}]
},

tooltip:{
formatter:function(){
return‘<b>‘+this.series.name
+‘</b><br/>‘+
this.x
+‘: ‘+this.y +‘℃‘;
}
},
legend:{
x:-50,
y:10,

enabled:true
},

exporting:{
enabled:false
},
plotOptions:{

line:{
gapSize:100
}
},
series:[{
name:‘最大值‘,
data: getFirstData()
}]
});
});

});

在上面代码中我们实例化了一个Highcharts对象,并指定了此对象一些属性。在定义中我们可以看到如下代码:

     chart:{
renderTo:‘container‘,
type:‘line‘,
marginRight:130,
marginBottom:80,
events:{
load:loadTime
}
}

在这段代码中就知道了图表需要绘制到的div元素,注意看上面红色字体部分。这个地方的container就是jsp页面上div的id值(大家可以回过去查看一下我前面的代码)。
     
其后指定了这个图表的类型(见上面代码中蓝色字体部分)。这里指定的Line类型,这就会绘制成曲线。
     
代码中还指定了图表的事件,目前只指定了一个load事件,在图表装载时将会调用执行load时间对应的函数。代码后面的loadTime是我编写的一个js函数,这个函数后面介绍。
     
通过title、subtitle指定图表的标题、子标题,见下面代码:

     title:{
text:‘大桥采集数据‘,
x:-20
},
subtitle:{
text:‘传感器编号: 传感器1‘,
x:-20
},

通过改变这里的设置可以影响图表上显示的效果,显示效果如下图红框选中部分内容。

     
通过xAxis、yAxis设定图表中横坐标、纵坐标的属性。

      xAxis:{
title:{
enabled:true,
text:‘时间(小时)‘
},
max:23,
min:0,
tickPixelInterval:50
},
yAxis:{
title:{
text:‘压力 (℃)‘
},
plotLines:[{
value:0,
width:1,
color:‘#808080‘
}]
},

通过在xAxis、yAxis中设置title属性控制横坐标、纵坐标上的文字描述显示。
      
在横坐标中有时我们是需要指定坐标上每个坐标点需要显示的文字内容的,这时我们需要使用到一个categories属性,通过将一个数组值传给categories属性,这样在横坐标上的每个坐标点就会按照指定的属性内容显示坐标点信息。为了实现如上目的,我们需要再设置一个变量,并将这个变量赋予categories属性。详见下:

var x_arr=[‘0:00‘,‘1:00‘,‘2:00‘,‘3:00‘,‘4:00‘,‘5:00‘,
‘6:00‘,‘7:00‘,‘8:00‘,‘9:00‘,‘10:00‘,‘11:00‘,
‘12:00‘,‘13:00‘,‘14:00‘,‘15:00‘,‘16:00‘,‘17:00‘,
‘18:00‘,‘19:00‘,‘20:00‘,‘21:00‘,‘22:00‘,‘23:00‘];

通过上面代码段我们定义了一个变量,然后看看如何指定到chart对象中,请注意如下代码端中红色部门,就是较前面代码端增加的地方:

xAxis:{
title:{

enabled:true,

text:‘时间(小时)‘
},
categories:x_arr,

max:23,

min:0,
tickPixelInterval:50
},

现在页面上显示的图表效果如下图所示:

       
横坐标上就是按照我们在x_arr变量中设定的内容显示的。如果设定的内容少于横坐标的坐标点,则前面的坐标点将按x_arr变量中设定内容显示,后面的坐标点将按默认的坐标点信息显示。
       
工程控制人员通过此曲线图可以知道每个时间点的最高温度情况,但是具体某个点温度是多少,工程人员希望通过将鼠标指向图表中采集点就可以展现出来。要实现这个功能,我们需要在chart对象中指定tooltip属性,见下面代码:

tooltip:{
formatter:function(){
return‘<b>‘+this.series.name
+‘</b><br/>‘+
this.x
+‘: ‘+this.y +‘℃‘;
}
},

配置上了这个属性就能得到下图显示的效果:

        
当鼠标移动到10点中的采集点时,屏幕上会立即显示当时的温度值。
        
针对有些应用场合,我们在一个图表中将展示多个线条代表不同的含义,这时就需要通过图例来说明什么颜色线条代表什么含义,这种情况下就需要启用图例说明,要启用图例说明就必须通过如下属性进行配置:

    egend:{
x:-50,
y:10,
enabled:true
},

只要使egend对象中的enabled属性设置为true就可以。设置为false,将不显示图例。
      
上面介绍的是图例基本的属性设置,现在我们需要模拟一些大桥传感器获得的数据,依据这些数据来显示曲线图。在这里我们首先要定义两个js函数,这三个函数就是模拟获取数据的,请看下面:

function loadTime(){
window.setTimeout(getData,TIMEOUT);
}

上面这个函数就是我们在chart对象中设置events中的load事件指定的函数。在本函数中主要启动了一个定时器,在超过指定时间计秒后,将调用函数getData。

function getFirstData(){
var data
=[];
var y_mx=Math.round(Math.random()*10);
var i;

for(i =0; i <=0; i++){
data.push({
x: current_time,
y: y_mx
});
if(current_time<=23){
current_time++;
}
}
return
data;
}

这个函数是用来模拟初始化chart对象时,获得的大桥桥面温度值。其返回的是一个数组对象,数组中的每个对象包含x、y属性,这两个属性用来告诉chart对象x轴的某个坐标上面的y值是多少,并在此处显示一个坐标点,同时将连接相邻两个坐标点形成曲线。代码中的current_time是一个全局变量,用来对当前采集显示次数进行计数。

function getData(){
var current_x=x_arr[current_time];

//获取最大值
var series_mx = chart.series[0];
var y_mx=Math.round(Math.random()*10);

series_mx.addPoint([current_time, y_mx],true,false);

current_time++;

if(current_time<=23){
window.setTimeout(getData,TIMEOUT);
}
}

上面这个函数其它部分都很简单,关键的一个重点代码是

series_mx.addPoint([current_time, y_mx],true,false);

这一段,这段代码是在chart图表中加入一个新的坐标点。
      
截至到目前,全部的代码就编写完成,现在运行它,就可以模拟出大桥桥面稳定24小时检测情况的实时趋势图。

      
其实使用highcharts来做实时趋势图简单的处理还是比较简单的,更多的应用还可以在这些基础应用上进行拓展

<script type="text/javascript">
var x_arr = [‘0:00‘, ‘1:00‘,
‘2:00‘, ‘3:00‘, ‘4:00‘, ‘5:00‘,‘6:00‘, ‘7:00‘, ‘8:00‘, ‘9:00‘, ‘10:00‘,
‘11:00‘,‘12:00‘, ‘13:00‘, ‘14:00‘, ‘15:00‘, ‘16:00‘, ‘17:00‘,‘18:00‘, ‘19:00‘,
‘20:00‘, ‘21:00‘, ‘22:00‘, ‘23:00‘];
var chart;
var
current_time = 0;
var TIMEOUT = 1000;
$(function () {

$(document).ready(function () {
chart = new
Highcharts.Chart({
chart: {

renderTo: ‘container‘,
type: ‘line‘,

marginRight: 130,
marginBottom: 80,

events: {
load: loadTime

}
},
title:
{
text: ‘大桥采集数据‘,
x: -20

},
subtitle: {
text: ‘传感器编号:
传感器‘,
x: -20
},
xAxis: {

title: {
enabled: true,

text: ‘时间(小时)‘

},
categories: x_arr,
max: 23,

min: 0,
tickPixelInterval: 50

},
yAxis: {
title: {

text: ‘压力 (℃)‘
},

plotLines: [{
value: 0,

width: 1,
color:
‘#808080‘
}]
},

tooltip: {
formatter: function () {

return ‘<b>‘ + this.series.name +
‘</b><br/>‘ +
this.x + ‘: ‘ + this.y
+ ‘℃‘;
}
},

legend: {
x: -50,
y:
10,
enabled: true
},

exporting: {
enabled: false

},
plotOptions: {

line: {
gapSize: 100

}
},
series: [{

name: ‘最大值‘,
data: getFirstData()
}]

});
});

});

function loadTime() {
window.setTimeout(getData,
TIMEOUT);
}

function getFirstData() {
var data = [];

var y_mx = Math.round(Math.random() * 10);
var i;

for (i = 0; i <= 3; i++) {
data.push({

x: current_time,
y: y_mx

});
if (current_time <= 23) {

current_time++;
}
}
return
data;
}

function getData() {
var current_x =
x_arr[current_time];

//获取最大值
var series_mx = chart.series[0];
var
y_mx = Math.round(Math.random() * 10);

series_mx.addPoint([current_time, y_mx], true, false);

current_time++;

if (current_time <= 23) {

window.setTimeout(getData, TIMEOUT);
}
}

</script>

时间: 2024-10-23 00:35:16

使用HighCharts实现实时数据展示的相关文章

性能测试五十:Jmeter+Influxdb+Grafana实时数据展示系统搭建

上Grafana官网下载Grafana,此产品只有64位的版本,没有32位的 Influxdb:InfluxDB是一个开源的时序数据库,使用GO语言开发,特别适合用于处理和分析资源监控数据这种时序相关数据.而InfluxDB自带的各种特殊函数如求标准差,随机取样数据,统计数据变化比等,使数据统计和实时分析变得十分方便.上官网下载 因为jmeter要往infuxdb里面写数据,所以最好把这两个放在一台机器上,grafana只做展示infuxdb里面的数据,可以另外部署 jmeter实时数据展示系统

数据可视化中数据展示效果,基于highcharts的图表数据展示

最近在公司里搞对外的大屏展示,效果需要比较酷炫. 因为只是单纯的数据展示+效果,而且时间比较紧(2天时间基于一个原先的3D地球模型,制作配套十来个页面),采用jquery+highcharts (效果1) (效果2) 上面就是效果图,直接上代码,文件引入这样的问题就不说了 1 render_chart: function (chartid, type) { 2 let chartOption = {}; 3 switch (type) { 4 case "areaspline" : 5

项目总结[2]_svg+ajax+webservice+pSpace sdk实现实时数据的web展示

1.使用svg实现组态画面和动态数据展示 通过js的定时器调用webservice方法获取数据后更新节点数据 /// <summary>启动定时刷新</summary> function Start() { InitSvgElement(); this.timer = setInterval("GetTagValues()", 1000); } /// <summary>启动定时刷新</summary> function Stop() {

使用Socket通信实现Silverlight客户端实时数据的获取(模拟GPS数据,地图实时位置)

原文:使用Socket通信实现Silverlight客户端实时数据的获取(模拟GPS数据,地图实时位置) 在上一篇中说到了Silverlight下的Socket通信,在最后的时候说到本篇将会结合地图.下面就来看看本文实现的功能: Silverlight 与服务器利用Socket通讯,实时从服务器获取数据(本文中的数据是地理坐标),由于没有GPS,所以本文在服务器写了一个构造新坐标的函数(本文是一个三角函数),然后利用Timer组件,实时调用,得到新的坐标,并将新的坐标发送给客户端,客户端接收到发

数据展示工具

数据最终是需要一套UI来展示的,而这种实时数据的展示,已经有不少项目了. 比如: + 官方的Chronograf Grafana 其它...

Exchange Server 2013就地电子数据展示

9.2 就地电子数据展示 如果您的组织遵循法定发现要求(与组织策略.合规性或诉讼相关),Microsoft Exchange Server 2013 和 ExchangeOnline 中的就地电子数据展示可以帮助您对邮箱内的相关内容执行发现搜索.Exchange 2013 和 Exchange Online 还提供联合搜索功能以及与 MicrosoftSharePoint 2013 和 Microsoft SharePoint Online 的集成.您可以使用 SharePoint 中的电子数据

在DevExpress程序中使用PopupContainerEdit和PopupContainer实现数据展示

在一些数据的即时查询场景中,我们可能需要对输入信息进行模糊查询并进行选择,例如在一些文本输入场景,如输入某个站点编码或者设备编码,然后获取符合的列表供用户选择的场景,本篇随笔介绍在DevExpress程序中使用PopupContainerEdit和PopupContainer实现数据展示. 1.回顾SearchLookupEdit控件使用 在DevExpress中,我们如果需要好的体验效果也可以用SearchLookupEdit来实现数据的查询及展示,不过这个控件,需要提前准备好数据源,然后是基

微信二八杠源码》用elasticsearch和kibana 进行简单的实时数据报表分析

微信二八杠源码(h5.hxforum.com) 联系方式170618633533企鹅2952777280 微信Tel17061863533 源码出售,平台出租,房卡出售有意者私聊 elasticsearch公司已经渐渐把ES变成为实时分析的工具,相比solr,es在实用产品化上确实领先很多.ES公司主推的ELK套件就是完成实时日志分析的完整解决方案,其中的kibana是一个简易报表工具,完全针对es进行开发,同类型产品几乎没有竞争者:logstash是日志拉取采集的工具,有很多同类产品,比如fl

如何设计实时数据平台(设计篇)

我抽数故我存在 | DBus 人人玩转流处理 | Wormhole 就当吾是数据库 | Moonbox 颜值最后十公里 | Davinci 导读:实时数据平台(RTDP,Real-time Data Platform)是一个重要且常见的大数据基础设施平台.在上篇(设计篇)中,我们从现代数仓架构角度和典型数据处理角度介绍了RTDP,并探讨了RTDP的整体设计架构.本文作为下篇(技术篇),则是从技术角度入手,介绍RTDP的技术选型和相关组件,探讨适用不同应用场景的相关模式.RTDP的敏捷之路就此展开