使用fusioncharts实时数据库来生成报表,描述趋势

    最近搞无线定位问题,碰到了一个问题,监听用户设备,实时的发送UDP报文,并将报文进行解析,解析完事存入数据库中,该数据库是实时动态更新的。其次就是用户输入设备点击显示去世的时候,给用户一个动态的报表趋势图,用来展示趋势图。

    由于第一次接触网络,第一次接触报表,第一次使用springmvc框架,所以干了将近一周的时间,才算解决问题。我设计的这个实时动态更新数据,说白了就是刷新chart或者说是重新绘制chart,友谊都是第一次接触,所有做的不是很好,只是给同我一样处于迷茫状态的朋友,点一下。下面就讲述一下具体过程:

注:如果想看的明白,一定要仔细看注释,我大多都写在代码的注释中了

1、页面   useChart.jsp

<%@ page language="java" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
		<script src="js/jquery-1.7.2.min.js"></script>
		<script src="fusioncharts/js/FusionCharts.min.js" type="text/javascript"></script>
		<script type="text/javascript" src="fusioncharts/js/FusionCharts.js"></script>
		<title>aotelan测试接口</title>
		
		<script type="text/javascript">
		var typeList = null;
		var modelList = null;
		var param = null;

		var datelist = [];
		var vulelist = [];
		var namelist = [];
		var staMac ;
		// 点击事件
		function getAllAp(){
			
			staMac =  document.getElementById("publishTime").value;
			var w = $("#tongji").width();
			var h = $(window).height() - 35;
			
			lineChartUrl("ScrollLine2D.swf?ChartNoDataText=暂无数据显示!", w, (h - 65),
					"usersiteTypeTrend");

		}
		
		// 数据处理
		function lineChartUrl(swf, chartWidth, chartHeight, chartDiv, chartName) {
			
			var namelist2=namelist;
			var vulelist2=vulelist;
			var datelist2=datelist;
			
			$.ajax({
				url : "showListener.do",
				type : "post",
				async : false,
				data : "staMac="+staMac,
				dataType:"json",
				success : function(data) {
					namelist2 = data.apList;
					vulelist2 = data.rssiList;
					datelist2 = data.collTimeList;
				}
			});
				
			
			var chartStyle = " numdivlines='9' alternateHGridAlpha='0' canvasBgAlpha='0,0' canvasBorderAlpha='20' lineThickness='2' showValues='0'  chartLeftMargin='0' chartRightMargin='15'chartTopMargin='5' chartBottomMargin='0' anchorRadius='3' anchorBgAlpha='100' numVDivLines='24' toolTipBgColor='304e79'  showAlternateVGridColor='1' alternateVGridAlpha='3' showLegend='0' baseFontSize='14' showBorder='0' baseFontColor='00FFFF' animation='0' bgAlpha='0,0' "
			var chartXMLData = "<chart caption='用户定位数据趋势图' >";
			chartXMLData += "<categories >";
			for ( var int = 0; int < datelist2.length; int++) {
				chartXMLData += "<category name='" + datelist2[int] + "'/>";
			}
			chartXMLData += "</categories >";
			for ( var int = 0; int < namelist2.length; int++) {
				chartXMLData += "<dataset seriesName='" + namelist2[int] + "'>";
				var vallist = vulelist2[int];
				//var columncolor = colormap.get(namelist2[int]);
				// alert(columncolor);
				for ( var i = 0; i < vallist.length; i++) {
					var values = vallist[i];
					chartXMLData += "<set  value='" + values
							+ "' />";
				}
				chartXMLData += " </dataset>";
			}

			chartXMLData += "</chart>";
			// alert("linexml:"+chartXMLData);
			drawChart(chartDiv, swf, chartWidth, chartHeight, chartXMLData);
			setInterval("getAllAp()",5000);
		}
		     
		
		// 画图 (以指定 xml格式字符串为数据源)
		function drawChart(divId, flashFileName, width1, height1, chartXMLData) {
			var myChartId = new Date().getTime();
			var myChart = new FusionCharts("charts/"
					+ flashFileName, myChartId, width1, height1, "0", "1");
			myChart.setDataXML(chartXMLData);
			myChart.setTransparent(true);
			myChart.addParam("wmode", "Opaque");
			myChart.render(divId);
		}
		
		//转换日期格式
		Date.prototype.format = function(format) {
			var o = {
				"M+" : this.getMonth() + 1, // month
				"d+" : this.getDate(), // day
				"h+" : this.getHours(), // hour
				"m+" : this.getMinutes(), // minute
				"s+" : this.getSeconds(), // second
				"q+" : Math.floor((this.getMonth() + 3) / 3), // quarter
				"S" : this.getMilliseconds()
			// millisecond
			}
			if (/(y+)/.test(format))
				format = format.replace(RegExp.$1, (this.getFullYear() + "")
						.substr(4 - RegExp.$1.length));
			for ( var k in o)
				if (new RegExp("(" + k + ")").test(format))
					format = format.replace(RegExp.$1, RegExp.$1.length == 1 ? o[k]
							: ("00" + o[k]).substr(("" + o[k]).length));
			return format;
		}
		
		
		function listenerStart(){
			var staMac =  document.getElementById("publishTime").value;
			$.ajax({
				url : "login.do",
				type : "post",
				async : true,
				data : "staMac="+staMac,
				dataType:"json",
				success : function(data) {
					
				}
			});
				
		}
		</script>
		
	</head>
	<body>
		<div class="content" id="tongji">
			<div class="content_data">
				<div>
				<fieldset class="query_fields">
					<legend style="color: white;">
						STA:
					</legend>
							
					<div>
						起报时间:
					<input id="publishTime" name="publishTime"
						 style="width: 100px" type="text"/>
					<input style="width: 60px"  value="启动监听" id="submit" type="button" οnclick="listenerStart();"/>	
					<input style="width: 60px"  value="绘制报表" id="submit" type="button" οnclick="getAllAp();"/>
					</div>
				</fieldset>
				<div id="usersiteTypeTrend" style="width: 800px; margin-top: 10px;hight:600px"></div>
				</div>
			</div>
		</div>
	</body>
</html>
以上的就是jsp页面的所有内容,为了大家能够更方便的了解,我就拆分一下代码:

页面展现如图:


(1)、很明显我把jsp页面做的比较简单,简单到不能再简单了。

            

<div class="content" id="tongji">
	<div class="content_data">
	<span style="white-space:pre">	</span><div>
		<span style="white-space:pre">	</span><fieldset class="query_fields">
				<legend style="color: white;">STA:</legend>
							
				<div>起报时间:
				<span style="white-space:pre">	</span><input id="publishTime" name="publishTime" style="width: 100px" type="text"/>
					<input style="width: 60px"  value="启动监听" id="submit" type="button" οnclick="listenerStart();"/>	
					<input style="width: 60px"  value="绘制报表" id="submit" type="button" οnclick="getAllAp();"/>
				</div>
			</fieldset>
			<div id="usersiteTypeTrend"style="width: 800px; margin-top: 10px;hight:600px"></div>
		</div>
	</div>
</div>


2)、真正起作用的在js里面

      用户点击启动监听,然后后台开始几首UDP报文,然后将UDP报文解析,解析之后,存入数据库。

      用户点击绘制报表,才开始去画图。

      流程如下:用户点击-----》获取输入框的值,通过ajax事件去请求后台------》后台调用业务逻辑层,然后业务逻辑层电泳数据库操作取数据-------》之后返回数据封装成json格式打印到前端---------》ajax接收到数据,开始赋值,绘制组装报表。

       实时鼎泰刷新,其实就是js写的定时器,定时去请求ccontroller,然后,返回数据,在组装,再绘制chart,重复如此。

      对应如下:

 a、用户点击事件:

       需要注意的是

// 点击事件
		function getAllAp(){
			
			staMac =  document.getElementById("publishTime").value;//获取输入框的值
			var w = $("#tongji").width();//设置chart的宽度
			var h = $(window).height() - 35;//设置chart的高度
			
			lineChartUrl("ScrollLine2D.swf?ChartNoDataText=暂无数据显示!", w, (h - 65),
					"usersiteTypeTrend");//这里注意了,<span style="font-family: Arial, Helvetica, sans-serif;">usersiteTypeTrend对应的就是按钮下面的那个存放chart的div的id</span>


		}

b、ajax请求后台

      

$.ajax({
				url : "showListener.do",
				type : "post",
				async : false,//这里需要设置为同步,否则加载不出来,意思就是,必须要等数据出来,才可以画图
				data : "staMac="+staMac,
				dataType:"json",//这里需要转换为json格式
				success : function(data) {//数据组装之后的json
					namelist2 = data.apList;//这里定义的是,每条线的名字
					vulelist2 = data.rssiList;//这里存放的是数据
					datelist2 = data.collTimeList;//这里存放的是横坐标,我的是时间轴
				}
			});

c、后台代码

        这个其实用什么都一样,我是用的springmvc,主要是数据封装的格式,其他的没啥

Java代码

package com.chenqk.springmvc.controller;


import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;

import net.sf.json.JSONObject;
import org.apache.log4j.Logger;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.chenqk.springmvc.entity.Location;
import com.chenqk.springmvc.service.LocationService;
import com.chenqk.springmvc.util.StationEntity;
import com.chenqk.springmvc.util.UDPReceiver;
/**
 * 控制类
 * @author chenqk
 *
 */
@Controller  
@RequestMapping("/")
public class UserController{

	
	@Autowired
	@Qualifier("LocationService")
	private LocationService locationService;
	
	private String staMac;
	
	private static Logger logger = Logger.getLogger(UserController.class);
	
	
	public LocationService getLocationService() {
		return locationService;
	}


	public void setLocationService(LocationService locationService) {
		this.locationService = locationService;
	}


	public String getStaMac() {
		return staMac;
	}


	public void setStaMac(String staMac) {
		this.staMac = staMac;
	}

	/**
	 * 启动监听
	 * @param staMac
	 */
	@RequestMapping("/login")
	public void login(@RequestParam("staMac") String staMac){
		logger.info("启动监听--------------------"+staMac);	
		// 启动接受udp报文,将参数传递给报文解析模块
		UDPReceiver receiver = UDPReceiver.getInstance();
		receiver.receiveToCache(staMac);
	}
	
	/**
	 * 准备数据
	 * 要求数据格式
	 * 时间轴:["time1","time2","time3"]
	 * ap名:["ap1","ap2","ap3","ap4","ap5"]
	 * 数据:{[num1,num2,num3],[num4,mun5,num6],[num7,num8,num9],[num10,num11,num12],[num13,num14,num15]}
	 * 其中数据的对一个格式为:集合大小为ap集合大小,每个集合的大小和时间的大小一致,用于前端生成报表
	 * @param staMac 用于启动监听将参数传递给解析报文
	 * @param printWriter 用于将json数据打印到前端
	 */
	@RequestMapping("/showListener")
	@ResponseBody
	public void showListener(@RequestParam("staMac")  String staMac, PrintWriter printWriter){
		
		Location location = new Location();
		
		// 存放数据值
		List<List<Double>> rssiList = new ArrayList<List<Double>>();
		// 获取时间轴坐标数据
		List<String> collTimeList = locationService.searchColltime(staMac);
		// 取最近一秒
		String colltime = collTimeList.get(collTimeList.size()-1);
		// 取最近一秒的ap集合,并按照ap去绘制在时间轴上的趋势
		location.setCollTime(colltime);
		location.setStaMac(staMac);
		List<Location> apList = locationService.getAllStaMacByTime(location);
		// 存放ap的集合
		List<String> ap = new ArrayList<String>();
		
		// 设置数据
		for (int i = 0; i < apList.size(); i++) {// 遍历很据ap和时间取数据值
			List<Double> numTemp = new ArrayList<Double>();// 对应的是每个ap在时间轴的数据的数据
				for (int j = 0; j < collTimeList.size(); j++) {					
					location.setApMac(apList.get(i).getApMac());
					double rssi = 0.0;
					location.setCollTime(collTimeList.get(j));
					System.out.println("时间:="+collTimeList.get(j)+"-----ap="+apList.get(i).getApMac());
					Location c = locationService.serchByApAndTime(location);
					if(c!=null){// 如果该对象存在,则将rssi值添加到集合中
						rssi = c.getRssi();
					}
					numTemp.add(rssi);
				}
				ap.add(apList.get(i).getApMac());// 将最近一秒的ap放到集合中
			
			rssiList.add(numTemp);// 将5个ap对应的数值放到集合中
		}
		
		
		// 实体类封装集合,组装成指定的格式
		StationEntity stationEntity = new StationEntity();
		stationEntity.setApList(ap);
		stationEntity.setCollTimeList(collTimeList);
		stationEntity.setRssiList(rssiList);
		
		// 将组合的数据对象转为json格式
		JSONObject jSONObject = JSONObject.fromObject(stationEntity);
		logger.info("获得数据为:"+jSONObject.toString());
		// 将json打印到前台
		printWriter.print(jSONObject);
		printWriter.close();

	}
}

 主要是第二个方法;数据格式,我都加在注释中了。其中封装三个集合的bean如下:

   

package com.chenqk.springmvc.util;

import java.util.List;

/**
 * 封装数据Bean
 * @author chenqk
 *
 */
public class StationEntity {
	
	/**
	 * ap集合,每条线代表的名字集合
	 */
	private List<String> apList;
	
	/**
	 * 数据值集合
	 */
	private List<List<Double>> rssiList;
	
	/**
	 * 时间轴集合
	 */
	private List<String> collTimeList;
	
	
	
	
	public List<String> getApList() {
		return apList;
	}
	public void setApList(List<String> apList) {
		this.apList = apList;
	}
	public List<List<Double>> getRssiList() {
		return rssiList;
	}
	public void setRssiList(List<List<Double>> rssiList) {
		this.rssiList = rssiList;
	}
	public List<String> getCollTimeList() {
		return collTimeList;
	}
	public void setCollTimeList(List<String> collTimeList) {
		this.collTimeList = collTimeList;
	}
}
有个对应关系说一下:数据这个集合是跟句时间轴和每条线代表的名字集合构建的,其中数据值集合的大小为,名字集合的大小。数据值中每个小的集合里面的大小是根据时间轴的集合大小来的。

d、ajax获得返回值,然后赋值组装chart

	// 数据处理
		function lineChartUrl(swf, chartWidth, chartHeight, chartDiv, chartName) {
			
			var namelist2=namelist;
			var vulelist2=vulelist;
			var datelist2=datelist;
			
			$.ajax({
				url : "showListener.do",
				type : "post",
				async : false,
				data : "staMac="+staMac,
				dataType:"json",
				success : function(data) {
					namelist2 = data.apList;
					vulelist2 = data.rssiList;
					datelist2 = data.collTimeList;
				}
			});
				
			//这里开始组装报表
			var chartStyle = " numdivlines='9' alternateHGridAlpha='0' canvasBgAlpha='0,0' canvasBorderAlpha='20' lineThickness='2' showValues='0'  chartLeftMargin='0' chartRightMargin='15'chartTopMargin='5' chartBottomMargin='0' anchorRadius='3' anchorBgAlpha='100' numVDivLines='24' toolTipBgColor='304e79'  showAlternateVGridColor='1' alternateVGridAlpha='3' showLegend='0' baseFontSize='14' showBorder='0' baseFontColor='00FFFF' animation='0' bgAlpha='0,0' "
			var chartXMLData = "<chart caption='用户定位数据趋势图' >";
			chartXMLData += "<categories >";
			for ( var int = 0; int < datelist2.length; int++) {
				chartXMLData += "<category name='" + datelist2[int] + "'/>";
			}
			chartXMLData += "</categories >";
			for ( var int = 0; int < namelist2.length; int++) {
				chartXMLData += "<dataset seriesName='" + namelist2[int] + "'>";
				var vallist = vulelist2[int];
				//var columncolor = colormap.get(namelist2[int]);
				// alert(columncolor);
				for ( var i = 0; i < vallist.length; i++) {
					var values = vallist[i];
					chartXMLData += "<set  value='" + values
							+ "' />";
				}
				chartXMLData += " </dataset>";
			}

			chartXMLData += "</chart>";
			// alert("linexml:"+chartXMLData);
			drawChart(chartDiv, swf, chartWidth, chartHeight, chartXMLData);
<span style="white-space:pre">			</span>//生成报表之后,设置定时器
			setInterval("getAllAp()",5000);
		}

调用下面方法需要注意:还有个问题就是,可能你的版面是白色的,而你chart的字体也是白色的,会在页面不显示,你需要在chartType中设置一下字体颜色。

drawChart(chartDiv, swf, chartWidth, chartHeight, chartXMLData)

// 画图 (以指定 xml格式字符串为数据源)
		function drawChart(divId, flashFileName, width1, height1, chartXMLData) {
			var myChartId = new Date().getTime();
<span style="white-space:pre">			</span>//下面的路径值得是你chart插件放的位置,我的如下图所示:
			var myChart = new FusionCharts("charts/"
					+ flashFileName, myChartId, width1, height1, "0", "1");
			myChart.setDataXML(chartXMLData);
			myChart.setTransparent(true);
			myChart.addParam("wmode", "Opaque");
			myChart.render(divId);
		}


至此,报表就画完了!代码已上传,需要的朋友可以去下载!使用的框架技术为springmvc+mybatis,插件为fusioncharts,数据库为mysql,附带sql脚本。



一天一点进步-------------------------2014年11月15日17:09:49 (不醉怎能入睡)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值