`
domain2004
  • 浏览: 6340 次
  • 来自: ...
文章分类
社区版块
存档分类
最新评论

用vert.x与echarts开发实时环境监控

阅读更多

本文旨在用vert.x与echarts开发一个实时环境监控demo。

vert.x参看http://vertx.io

ehcars参看http://echarts.baidu.com/index.html

整个业务流程比较简单,就是页面通过sockJs与后端的web服务器通讯,然后后端服务器实时推送数据到页面。

页面代码如下:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script type="text/javascript" src="/js/jquery-easyui-1.5.2/jquery.min.js"></script>
<script type="text/javascript" src="/js/sockjs.min.js"></script>
<script type="text/javascript" src="/js/vertx-eventbus.min.js"></script>
<script type="text/javascript" src="/js/baidu/echarts-all.js"></script>
</head>

<body>
	<div><b>环境实时监控:</b></div>
	<br>
	<table width="800">
		<tr>
			<td><font color="blue">温度</font></td>
			<td><font color="blue">湿度</font></td>
			<td><font color="blue">CO2</font></td>
			<td><font color="blue">NH3</font></td>
		</tr>
		<tr>
			<td><div id="T"></div></td>
			<td><div id="H"></div></td>
			<td><div id="CO2"></div></td>
			<td><div id="NH3"></div></td>
		</tr>
	</table>
	<br>
	<table>
		<tr>
			<td><div id="T_chart" style="width: 250px;height:250px;"></div></td>
			<td><div id="T_chart_line" style="width: 500px;height:250px;"></div></td>
			<td><div id="H_chart" style="width: 250px;height:250px;"></div></td>
			<td><div id="H_chart_line" style="width: 500px;height:250px;"></div></td>
		</tr>
		<tr>
			<td><div id="CO2_chart" style="width: 250px;height:250px;"></div></td>
			<td><div id="CO2_chart_line" style="width: 500px;height:250px;"></div></td>
			<td><div id="NH3_chart" style="width: 250px;height:250px;"></div></td>
			<td><div id="NH3_chart_line" style="width: 500px;height:250px;"></div></td>
		</tr>
	</table>

	<script>
		// 仪表盘-------------------------------------------------------------------
		var myChart_T = echarts.init(document.getElementById("T_chart"));
		var option_T = {
		    series : [
		        {
		            name:'温度',
		            type:'gauge',
		            detail : {formatter:'{value}℃'},
		            data:[{value: 50, name: '温度'}],
		            min:0,
		            max:50,
		            axisLine:{
	            	    show: true,
	            	    //给每一段指定颜色(本例中温度分低,适宜,高三段),格式:百分比,颜色。
	            	    lineStyle: {
	            	        color: [
	            	            [0.3, '#228b22'],
	            	            [0.7, '#48b'],
	            	            [1, '#ff4500']
	            	        ],
	            	        width: 20
	            	    }
		            },
		            splitLine:{
		            	length :20
		            }
		        }
		    ]
		};
		myChart_T.setOption(option_T);
		
		var myChart_H = echarts.init(document.getElementById("H_chart"));
		var option_H = {
		    series : [
		        {
		            name:'湿度',
		            type:'gauge',
		            detail : {formatter:'{value}%'},
		            data:[{value: 50, name: '湿度'}],
		            axisLine:{
	            	    show: true,
	            	    lineStyle: {
	            	        color: [
	            	            [0.4, '#228b22'],
	            	            [0.75, '#48b'],
	            	            [1, '#ff4500']
	            	        ],
	            	        width: 20
	            	    }
		            },
		            splitLine:{
		            	length :20
		            }
		        }
		    ]
		};
		myChart_H.setOption(option_H);
		
		var myChart_CO2 = echarts.init(document.getElementById("CO2_chart"));
		var option_CO2 = {
		    series : [
		        {
		            name:'CO2',
		            type:'gauge',
		            detail : {formatter:'{value}%'},
		            data:[{value: 0.05, name: 'CO2'}],
		            min:0,
		            max:0.15,
		            splitNumber:5,
		            axisLine:{
	            	    show: true,
	            	    lineStyle: {
	            	        color: [
	            	            [0.33, '#228b22'],
	            	            [0.66, '#48b'],
	            	            [1, '#ff4500']
	            	        ],
	            	        width: 20
	            	    }
		            },
		            splitLine:{
		            	length :20
		            }
		        }
		    ]
		};
		myChart_CO2.setOption(option_CO2);
		
		var myChart_NH3 = echarts.init(document.getElementById("NH3_chart"));
		var option_NH3 = {
		    series : [
		        {
		            name:'NH3',
		            type:'gauge',
		            detail : {formatter:'{value}%'},
		            data:[{value: 0.05, name: 'NH3'}],
		            min:0,
		            max:0.005,
		            splitNumber:10,
		            axisLine:{
	            	    show: true,
	            	    lineStyle: {
	            	        color: [
	            	            [0.9, '#48b'],
	            	            [1, '#ff4500']
	            	        ],
	            	        width: 20
	            	    }
		            },
		            splitLine:{
		            	length :20
		            }
		        }
		    ]
		};
		myChart_NH3.setOption(option_NH3);
		
		var count = 0;
		var date = [];
		
		// 折线图----------------------------------------------------------------------------------
		var myChart_T_line = echarts.init(document.getElementById("T_chart_line"));
		var data_T = [];
		var option_T_line = {
		    xAxis: {
		        type: 'category',
		        boundaryGap: false,
		        data: date
		    },
		    yAxis: {
		        min:0,
		        max:50,
		        type: 'value'
		    },
		    series: [
		        {
		            name:'meanRate',
		            type:'line',
		            smooth:true,
		            areaStyle: {
		                normal: {}
		            },
		            data: data_T
		        }
		    ]
		};
		myChart_T_line.setOption(option_T_line);
		myChart_T_line.hideLoading();
		
		var myChart_H_line = echarts.init(document.getElementById("H_chart_line"));
		var data_H = [];
		var option_H_line = {
		    xAxis: {
		        type: 'category',
		        boundaryGap: false,
		        data: date
		    },
		    yAxis: {
		        min:0,
		        max:100,
		        type: 'value'
		    },
		    series: [
		        {
		            name:'meanRate',
		            type:'line',
		            smooth:true,
		            areaStyle: {
		                normal: {}
		            },
		            data: data_H
		        }
		    ]
		};
		myChart_H_line.setOption(option_H_line);
		myChart_H_line.hideLoading();
		
		var myChart_CO2_line = echarts.init(document.getElementById("CO2_chart_line"));
		var data_CO2 = [];
		var option_CO2_line = {
		    xAxis: {
		        type: 'category',
		        boundaryGap: false,
		        data: date
		    },
		    yAxis: {
		        min:0,
		        max:0.20,
		        type: 'value'
		    },
		    series: [
		        {
		            name:'meanRate',
		            type:'line',
		            smooth:true,
		            areaStyle: {
		                normal: {}
		            },
		            data: data_CO2
		        }
		    ]
		};
		myChart_CO2_line.setOption(option_CO2_line);
		myChart_CO2_line.hideLoading();
		
		var myChart_NH3_line = echarts.init(document.getElementById("NH3_chart_line"));
		var data_NH3 = [];
		var option_NH3_line = {
		    xAxis: {
		        type: 'category',
		        boundaryGap: false,
		        data: date
		    },
		    yAxis: {
		        min:0,
		        max:0.007,
		        type: 'value'
		    },
		    series: [
		        {
		            name:'meanRate',
		            type:'line',
		            smooth:true,
		            areaStyle: {
		                normal: {}
		            },
		            data: data_NH3
		        }
		    ]
		};
		myChart_NH3_line.setOption(option_NH3_line);
		myChart_NH3_line.hideLoading();
		
		// webSocket------------------------------------------------------------------------
		var eb = new EventBus("/eventbus/");
		eb.onopen = function() {
			eb.registerHandler("chartServer.to.client", function(err, msg) {
				$('#T').text(msg.body.T + "\n");
				$('#H').text(msg.body.H + "\n");
				$('#CO2').text(msg.body.CO2 + "\n");
				$('#NH3').text(msg.body.NH3 + "\n");
				
				
				option_T.series[0].data[0].value = msg.body.T;
			    myChart_T.setOption(option_T, true);
			    
			    option_H.series[0].data[0].value = msg.body.H;
			    myChart_H.setOption(option_H, true);
			    
			    option_CO2.series[0].data[0].value = msg.body.CO2;
			    myChart_CO2.setOption(option_CO2, true);
			    
			    option_NH3.series[0].data[0].value = msg.body.NH3;
			    myChart_NH3.setOption(option_NH3, true);

			    date.push(msg.body.time); 
			    count = count + 1;
			    
			    if(count > 100){
			        date.shift();		        
			        data_T.shift();
			        data_H.shift();
			        data_CO2.shift();
			        data_NH3.shift();
			    }
			    
			    data_T.push(msg.body.T);
			    data_H.push(msg.body.H);
			    data_CO2.push(msg.body.CO2);
			    data_NH3.push(msg.body.NH3);
			    
			    myChart_T_line.setOption(option_T_line, true);	
			    myChart_H_line.setOption(option_H_line, true);	
			    myChart_CO2_line.setOption(option_CO2_line, true);
			    myChart_NH3_line.setOption(option_NH3_line, true);
			});
		};
		
	</script>
</body>
</html>

 后台代码如下:

package com.wof.realtimesca.chart;

import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.GregorianCalendar;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import io.vertx.core.json.JsonObject;
import io.vertx.ext.web.handler.sockjs.BridgeEventType;
import io.vertx.ext.web.handler.sockjs.BridgeOptions;
import io.vertx.ext.web.handler.sockjs.PermittedOptions;
import io.vertx.rxjava.core.AbstractVerticle;
import io.vertx.rxjava.core.eventbus.EventBus;
import io.vertx.rxjava.core.eventbus.Message;
import io.vertx.rxjava.core.eventbus.MessageConsumer;
import io.vertx.rxjava.ext.web.Router;
import io.vertx.rxjava.ext.web.handler.StaticHandler;
import io.vertx.rxjava.ext.web.handler.sockjs.SockJSHandler;
import rx.Observable;
import rx.Subscription;


public class ChartVerticle extends AbstractVerticle {
	
	private static final Logger logger = LoggerFactory.getLogger(ChartVerticle.class);

	public void start() throws Exception {
		
		// 路由器
		Router router = Router.router(vertx);

		// 事件总线
		BridgeOptions bridgeOptions = new BridgeOptions()
				.addInboundPermitted(new PermittedOptions().setAddress("tcpServer.to.chartServer"))
				.addOutboundPermitted(new PermittedOptions().setAddress("chartServer.to.client"));
				
		SockJSHandler sockJSHandler = SockJSHandler.create(vertx).bridge(bridgeOptions, event -> {
			if (event.type() == BridgeEventType.SOCKET_CREATED) {
				logger.info("a socket creatae.");
			} else if (event.type() == BridgeEventType.SOCKET_CLOSED){
				logger.info("a socket closed.");
			}
			event.complete(true);
		});
		
		sockJSHandler.socketHandler(sockJSSocket -> {
			sockJSSocket.exceptionHandler(handler -> {
				logger.error(handler.getCause().getMessage());
			});
		});
		
		router.route("/eventbus/*").handler(sockJSHandler);
		router.route().handler(StaticHandler.create());//这种没有任何前缀的静态资源handler一定要放到sockJSHandler后面;否则,jsSocket无法与后台通讯。
		
		EventBus eventBus = vertx.eventBus();
		
		MessageConsumer<String> consumer = eventBus.consumer("tcpServer.to.chartServer");
		Observable<Message<String>> observable = consumer.toObservable();
		//message结构(json): {"type":"rec","address":"char.to.client.push","body":"welcome!"}
		Subscription sub = observable.subscribe(msg -> {
			eventBus.publish("chartServer.to.client", msg.body());
		});
		
		// http server
		vertx.createHttpServer().requestHandler(router::accept).listen(8090);
		
		// 模拟传感器发送数据到服务器	
		SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
		vertx.setPeriodic(500, t -> {
			JsonObject jsonData = new JsonObject();
			String date = sdf.format(GregorianCalendar.getInstance().getTime());
			jsonData.put("time", date);
			
			String data = getDataValue(28, 30, 0, 1);//温度			
			jsonData.put("T", data);
			
			data = getDataValue(70, 75, 0, 1);//湿度
			jsonData.put("H", data);
			
			data = getDataValue(5, 10, 2, 2);//CO2 0.05—0.1%
			jsonData.put("CO2", data);
			
			data = getDataValue(1, 4, 3, 4);//NH3 < 0.004﹪
			jsonData.put("NH3", data);
			
			vertx.eventBus().publish("tcpServer.to.chartServer", jsonData);
		});
	}
	
	/**
	 * 产生随机小数
	 * 
	 * @param min
	 * @param max
	 * @param count 小数位数
	 * @param zeroCount 需要保留的小数位数
	 * @return
	 */
	private String getDataValue(int min, int max, int count, int zeroCount){
		double d = (Math.random() * (max - min + 1) + min);
		
		for(int i = 1; i <= count ; i++){
			d /= 10;
		}
		
		String zero = "0.";
		if(zeroCount < 1) 
			zero = "0.0";
		else {
			for(int i = 1; i <= zeroCount; i++){
				zero += "0";
			}
		}
		
		DecimalFormat Dformat = new DecimalFormat(zero);
		String val = Dformat.format(d);
		
		return val;
	}
}

 

效果图:

 

 

 

  • 大小: 98.9 KB
分享到:
评论

相关推荐

    Vert.x应用开发实例教程

    Vert.x是事件驱动的,其处理请求的高性能也是基于其事件机制。Vert.x的事件机制中有几个非常重要的概念:Event Loop、Event Loop Vertical、Worker Vertical、Event Bus、Vert.x Module。 Event Loop:即事件循环,...

    Vert.x 4 核心手册中文版

    Vert.x 是一个轻量级、高性能的反应式应用开发框架,适用于 Java 和其他多种语言。它的核心组件小巧且灵活,允许开发者只使用需要的部分,并能无缝嵌入到现有的应用程序中,无需按照特定的架构模式进行改造。Vert.x ...

    vert.x结合springboot开发mqtt服务,真实可用

    将Vert.x与Spring Boot结合,我们可以利用Spring Boot的便捷配置和管理特性,以及Vert.x的高性能事件驱动架构,实现高效的MQTT服务器。 下面是一些关键步骤和技术点: 1. **设置项目结构**:创建一个标准的Spring ...

    vert.x中文 PDF 下载

    在阅读《vert.x中文 PDF 下载》这本书时,你会了解到如何配置和启动vert.x环境,创建和部署Verticle,使用事件总线进行通信,以及如何利用vert.x提供的各种组件(如HTTP服务器、TCP服务器、WebSocket)构建网络应用...

    vert.x-2.1.2

    - vert.x 适用于微服务架构、实时大数据处理、物联网(IoT)应用、高并发的Web服务以及任何需要高度并发和低延迟的场景。 总结来说,vert.x-2.1.2 是一个基于Java和NIO的高效应用框架,它为开发人员提供了构建...

    vertx应用开发实例教程-完整版

     《Vert.x应用开发实例教程》旨在为Vert.x的初学者和大中专院校学生提供易于入门,全面了解和掌握Vert.x框架技术和应用的教材和辅导资料,为使用Vert.x开发实时应用和企业级应用打下良好的基础。

    基于Vert.x(java)开发的API网关,是一个分布式,全异步,高性能,可扩展,轻.zip

    标题中的“基于Vert.x(java)开发的API网关”指的是使用Vert.x框架构建的应用程序,该应用程序主要功能是作为API网关。API网关是一种架构模式,它充当客户端(如Web应用、移动应用或IoT设备)与后端服务之间的单一...

    vert.x 3.3.3

    【标签】"Node.Js vertx" 表明这是一个关于比较和使用Node.js与Vert.x的讨论。Node.js以其高效的异步非阻塞I/O和丰富的生态系统而闻名,适合构建Web服务器和实时应用。Vert.x则提供了一个更为通用的工具集,不仅包含...

    Vert.x学习

    Vert.x的核心设计理念是提供一个轻量级的运行时环境,支持多种编程语言,包括Java、JavaScript、Ruby、Groovy等,使得开发者可以灵活地选择适合项目需求的语言。 【描述】"源码下载 博文链接:...

    Vert.x配置项VertxOptions的使用

    在使用Vert.x框架开发分布式应用时,为了更好地控制和优化应用性能,开发者通常需要通过`VertxOptions`类来定制化配置Vert.x实例。`VertxOptions`是用于创建`Vertx`实例时的一个配置对象,它提供了丰富的配置选项来...

    Vert.x 初始demo

    Vert.x 是一个轻量级、高性能且反应式的应用开发框架,主要用于构建现代的、事件驱动的、非阻塞式的Java应用程序。它支持多种编程语言,包括Java、JavaScript、Ruby、Groovy和 Kotlin,提供了一个统一的API来处理...

    使用Eclipse_Vert.x开发响应式应用_英文.pdf

    2. **多语言支持**:虽然主要用Java编写,但Vert.x 提供了API接口,支持其他如JavaScript、Ruby、Groovy、Ceylon等多种语言,这使得开发人员可以选择他们最熟悉的语言进行开发。 3. **模块化系统**:Vert.x 允许...

    Vert.x线程模型揭秘

    #### 四、Vert.x与Netty的线程模型对比 - **Netty**:Netty使用两个线程池:Boss Group和Worker Group。Boss Group负责接收新的连接,而Worker Group则处理连接上的I/O操作。 - **Vert.x**:虽然Netty也是Vert.x的...

    Java vert.x微服务框架资料

    - **开发环境:** 实验建议使用个人笔记本电脑,并安装 Windows、Mac OS 或 Linux 操作系统。此外,还需要安装 Docker,尽管 Vert.x 并不依赖 Docker,但它有助于模拟分布式系统环境。 - **实践目标:** 通过构建...

    vert.x-springboot模版项目

    vert.x是内存占用极小的快速开发框架,springboot模版项目

    Vert.X-generator是基于javafx8开发的图形界面Vert.x代码生成器

    Vert.X-generator是基于javafx8开发的图形界面Vert.x代码生成器,使用 Apache FreeMarker 作为代码文件的模板,用户可以一键将数据库中的表生成为任意风格的.java代码文件(比如经典的三层模型);该工具支持所有实现JDBC...

    Java API 版本的Vert.x Core 手册等三本书

    Java API 版本的Vert.x Core 手册是关于Vert.x框架的重要参考资料,该框架是用Java编写的高度可扩展的事件驱动平台,适用于构建现代的、反应式的微服务和网络应用。 Vert.x Core是其核心组件,提供了低级别的API,...

    Vert.x for Java 开发者

    ### Vert.x for Java 开发者知识点详解 #### 一、简介 **Vert.x** 是一个高性能的异步框架...以上是关于如何使用Vert.x进行Java异步开发的基础知识点。通过学习这些内容,开发者可以构建出高性能、可扩展的应用程序。

    vertx-kue, Vert.x Blueprint项目 Vert.x Kue,这是由 Vert.x 支持的优先级任务队列.zip

    vertx-kue, Vert.x Blueprint项目 Vert.x Kue,这是由 Vert.x 支持的优先级任务队列 Vert.x Kue Vert.x Kue 是用 Vert.x 开发的优先级任务队列,并以的Redis支持。 它是 automattic/kue的Vert.x 实现版本。这个蓝图...

Global site tag (gtag.js) - Google Analytics