highcharts 图表插件与Struts2结合应用,用图表直观展现后台数据分析结果

零 基本介绍

Highcharts 是一个用纯JavaScript编写的一个图表库, 能够很简单便捷的在web网站或是web应用程序添加有交互性的图表,并且免费提供给个人学习、个人网站和非商业用途使用。HighCharts支持的图表类型有曲线图、区域图、柱状图、饼状图、散状点图和综合图表。 

推荐几个web中常用js图表插件

本例中除用到Highcharts表格插件外,还用到ajax网页异步刷新技术,指定Action method属性并使用通配符,采用JSON数据格式进行数据集的传输。

一 功能描述

通过ajax调用action从后台获取数据集,应用highcharts图表插件,在前端以柱状图或折线图的形式对数据进行直观展示。

二 实现流程

1 JSP页面布局

2 Action业务逻辑编写

3 struts.xml配置

4 ajaxhighcharts图表js脚本编写

三 解决问题

1 highcharts应用 

action指定method属性及使用通配符

通过<s:select></s:select>标签指定请求参数

四 详细设计

1 JSP页面布局

JSP页内放置两个highchart图表

第一个图表以line style展示 不同尺寸的图像在不同压缩方式下的压缩总时间对比

第二个图表一column style展示 某一尺寸图像在不同压缩方式下的压缩各部分时间对比

chart.jsp

<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
<%@taglib prefix="s" uri="/struts-tags" %>
<html>

<head>
<title>highcharts图表插件应用</title>
	<script type="text/javascript" src="js/jquery-*.**.*.min.js"></script>
<!--自己编写的js脚本 -->
	<script type="text/javascript" src="js/analysis.js"></script>
</head>
<body style="background: #fac234">
<!--highcharts表格插件需要的js脚本 -->
<script src="js/test/highcharts.js"></script>
<script src="js/test/exporting.js"></script>

<s:submit style="float:left;" id="drawLine" value="查询历史数据" ></s:submit>
<div id="container" style="width:60%; height: 400px; margin: 0 auto"></div>

<s:select id="sizeSelect" list="{256,512,1024,2048,4096}"></s:select>
<s:submit style="float:left;" id="drawBar" value="查询历史数据" ></s:submit>
<div id="partTimeCompare" style="width:60%; height: 400px; margin: 0 auto"></div>

</body>

</html>

2 Action业务逻辑编写

Action业务逻辑有两个功能,对应Action内的两个函数方法。

TotalTimeLine()方法用于从数据库中查询全部历史压缩时间数据,并统计不同尺寸图像大小不同压缩方式下的平均时间。

partTimeCompare()方法根据传入的图片尺寸参数,从数据库中查询该尺寸图像的所有历史时间数据,并分类整理(这部分和我要实现的实际需求有关,不赘述)

下面将使用通配符的方式为action指定method方法,对struts.xml中配置的同一个action映射不同方法,以精简代码。


----注意----

对数据库进行相关操作需要导入sqljdbc.jar

本类中所用的Variable.javaDBTools.java将不被列出

DrawPictrueAction.java

package com.wlkfz.action;

import java.io.IOException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletResponse;

import net.sf.json.JSONObject;

import org.apache.commons.lang.Validate;
import org.apache.struts2.ServletActionContext;
import org.apache.struts2.views.xslt.ArrayAdapter;

import com.opensymphony.xwork2.Action;
import com.wlkfz.bean.DBTools;
import com.wlkfz.bean.Variable;

public class DrawPictrueAction implements Action {
	
	private Connection conn = null;  
	private Statement state = null; 		
	private ResultSet rs = null;
	
	
	private JSONObject data = new JSONObject();
	private int imgSize ;
	private int cpsWays = Variable.cpsWays;
	
	@Override
	public String execute() throws Exception {
		//action 默认调用方法 JSON template
		queryAndAnalysisTotalTime();
		HttpServletResponse response=ServletActionContext.getResponse();
		response.setContentType("text/html;charset=UTF-8");
		
		response.getWriter().write(data.toString());
		
		return null;
	}
	
	public String partTimeCompare() throws IOException{
		System.out.println("imgSize="+imgSize);
		//同一图片尺寸 不同压缩方式 total dwt spiht时间对比
		try {
			conn = DBTools.getConnection();
			state = conn.createStatement();
			String sql = "select * from mytest..compress_time where image_size="+imgSize;
			rs = state.executeQuery(sql);
//			float time[][] = new float[3][4]; //二维数组
			
			float totalTime[] = new float[cpsWays]; 
			float dwtTime[] = new float[cpsWays];
			float spihtTime[] = new float[cpsWays];
			
			while (rs.next()) {
				
					int cpsWay = rs.getInt("cps_way");
					float tTime = rs.getFloat("total_time");
					float dTime = rs.getFloat("dwt_total");
					float sTime = rs.getFloat("spiht_total");
					if (totalTime[cpsWay]!=0) {
						totalTime[cpsWay] = (totalTime[cpsWay]+tTime)/2;
					}else {
						totalTime[cpsWay] = tTime;
					}
					if (dwtTime[cpsWay]!=0) {
						dwtTime[cpsWay] = (dwtTime[cpsWay]+dTime)/2;
					}else {
						dwtTime[cpsWay] = dTime;
					}
					if (spihtTime[cpsWay]!=0) {
						spihtTime[cpsWay] = (spihtTime[cpsWay]+sTime)/2;
					}else {
						spihtTime[cpsWay] = sTime;
					}
				
			}
			List<List<Float>> cpsPartTimeSet = new ArrayList<List<Float>>();
			for (int i = 0; i < 3; i++) {
				List<Float> temp = new ArrayList<Float>();
				for (int j = 0; j < cpsWays; j++) {
					switch (i) {
					case 0:
						temp.add(dwtTime[j]);
						break;
					case 1:
						temp.add(spihtTime[j]);
						break;
					case 2:
						temp.add(totalTime[j]);
						break;
					default:
						break;
					}
				}
				cpsPartTimeSet.add(temp);
			}
			
			data.put("partTimeList", cpsPartTimeSet); 
			
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			DBTools.closeRs(rs);  
			DBTools.closeState(state);  
			DBTools.closeConn(conn);
		}
		
		
		HttpServletResponse response=ServletActionContext.getResponse();
		response.setContentType("text/html;charset=UTF-8");
		
		response.getWriter().write(data.toString());  
		return null;
	}
	
	public String TotalTimeLine() throws IOException{
		System.out.println("call TotalTimeLine()");
		queryAndAnalysisTotalTime();
		HttpServletResponse response=ServletActionContext.getResponse();
		response.setContentType("text/html;charset=UTF-8");
		
		response.getWriter().write(data.toString());
		
		return null;
	}
	
	private void  queryAndAnalysisTotalTime(){
		//准备数据
		//查询总时间并求平均值
		try {
			conn = DBTools.getConnection();
			state = conn.createStatement();
			String sql = "select * from mytest..compress_time";
			rs = state.executeQuery(sql);
			
			float time[][] = new float[Variable.imgKinds][Variable.cpsWays];			
			while (rs.next()) {
				int cpsWay = rs.getInt("cps_way");
				int iamgeSize = rs.getInt("image_size");
				float totalTime = rs.getFloat("total_time");
				int sizeIndex = (int) (Math.log(iamgeSize/Variable.imgBase)/Math.log(2));
				
				if (time[sizeIndex][cpsWay]!=0) {
					time[sizeIndex][cpsWay] = (time[sizeIndex][cpsWay]+totalTime)/2; 
				}else {
					time[sizeIndex][cpsWay] = totalTime;
				}
			}
			
			List<List<Float>> aveTimeForCpsWay = new ArrayList<List<Float>>();
			for (int i = 0; i < Variable.cpsWays; i++) {
				List<Float> temp = new ArrayList<Float>();
				for (int j = 0; j < Variable.imgKinds; j++) {
					temp.add(time[j][i]);
				}
				aveTimeForCpsWay.add(temp);
			}
			data.put("aveTime", aveTimeForCpsWay);
			
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			DBTools.closeRs(rs);  
			DBTools.closeState(state);  
			DBTools.closeConn(conn);
		}
	}
	

	public int getImgSize() {
		return imgSize;
	}

	public void setImgSize(int imgSize) {
		this.imgSize = imgSize;
	}
}

3 struts.xml配置 

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
	"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
	"http://struts.apache.org/dtds/struts-2.3.dtd">

<struts>

    <constant name="struts.enable.DynamicMethodInvocation" value="false" />
    <constant name="struts.devMode" value="true" />

    <package name="default"   extends="struts-default">
		 <action name="draw_*" class="com.wlkfz.action.DrawPictrueAction" method="{1}">
	 		<result name="success">/welcome.jsp</result>
	 		<result name="fail">/showPic.jsp</result>
		 </action>
    </package>
    
    <!-- Add packages here -->
    
</struts>

在该struts.xml配置中,使用了通配符的方式,在Actionname属性中使用通配符后,可用一个<action.../>元素代替多个逻辑Action

上面的<action name="draw_*".../>元素不是定义了一个普通的Action,而是定义了一系列的逻辑Action---只要用户请求的URLdraw_*.action的模式,都可以用该Action来处理。配置该action元素时,还制定了method属性(method属性用于指定处理用户请求的方法),但该method属性使用了一个表达式{1},该表达式的值就是name属性值中第一个*的值,例如,如果用户请求的URLdraw_TotalTimeLine.action,则调用DrawPictrueAction类的TotalTimeLine方法。

4 ajax及highcharts图表js脚本编写

使用jQueryJSP页内的两个按钮监听鼠标点击事件,在按钮click事件的方法内通过AjaxDrawPictrueAction进行交互,并获取Action返回的JSON数据集合。在Ajax的回调函数内调用HighCharts插件提供的表格创建方法。

analysis.js

$(document).ready(function(){
    
      $('#drawLine').click(function() {
           
                $.getJSON("draw_TotalTimeLine.action",
                     function(result){
                         $('#container').highcharts({
                                chart: {
                                    type: 'line'
                                },
                                title: {
                                    text: '针对不同图像大小的不同压缩方式的总压缩时间对比'
                                },
                                subtitle: {
                                    text: 'Source: WorldClimate.com'
                                },
                                xAxis: {
                                    categories: ['256', '512', '1024', '2048', '4096']
                                },
                                yAxis: {
                                    title: {
                                        text: '时间 (ms)'
                                    }
                                },
                                plotOptions: {
                                    line: {
                                        dataLabels: {
                                            enabled: true
                                        },
                                        enableMouseTracking: false
                                    }
                                },
                                series: [{
                                    name: '基于CPU的串行压缩方式',
                                    data: result.aveTime[0]
                                    /*data: [19.64658,34.45484,135.8212,501.099,974.0006]*/
                                }, {
                                    name: '基于GPU的并行压缩方式',
                                    data: result.aveTime[1]
                                    /*data: [26.54384,99.13428,466.198,2225.544,4933.468]*/
                                },{
                                    name: 'CPU多线程并行拆包方案',
                                    data: result.aveTime[2]
                                    /*data: [26.54384,99.13428,466.198,2225.544,4933.468]*/
                                },{
                                    name: '基于GPU的码流段拼接优化方案',
                                    data: result.aveTime[3]
                                    /*data: [26.54384,99.13428,466.198,2225.544,4933.468]*/
                                }]
                            });   
                        });
                        
                        /*getJSON方法必须要传回一个JSON对象*/
          });
    
    $("#drawBar").click(function() {
        var size = $("#sizeSelect option:selected").text();
        /*获取<s:select>当前选中的value值*/
        $.getJSON("draw_partTimeCompare.action",{"imgSize":size},function(result){
             $('#partTimeCompare').highcharts({
                chart: {
                    type: 'column'
                },
                title: {
                    text: 'Monthly Average Rainfall'
                },
                subtitle: {
                    text: 'Source: WorldClimate.com'
                },
                xAxis: {
                    categories: [
                        '基于CPU的串行压缩方式',
                        '基于GPU的并行压缩方式',
                        'CPU多线程并行拆包方案',
                        '基于GPU的码流段拼接优化方案',
                    ],
                    crosshair: true
                },
                yAxis: {
                    min: 0,
                    title: {
                        text: 'Time (ms)'
                    }
                },
                tooltip: {
                    headerFormat: '<span style="font-size:10px">{point.key}</span><table>',
                    pointFormat: '<tr><td style="color:{series.color};padding:0">{series.name}: </td>' +
                        '<td style="padding:0"><b>{point.y:.1f} mm</b></td></tr>',
                    footerFormat: '</table>',
                    shared: true,
                    useHTML: true
                },
                plotOptions: {
                    column: {
                        pointPadding: 0.2,
                        borderWidth: 0
                    }
                },
                series: [{
                    name: 'DWT',
                    data: result.partTimeList[0]
        
                }, {
                    name: 'SPIHT',
                    data: result.partTimeList[1]
        
                }, {
                    name: 'TOTAL',
                    data: result.partTimeList[2]
                }]
            });
            
            
        });
     });
});

最终结果:


总结

HighCharts表格插件嵌入在Web中使用非常方便。该表格插件甚至提供动画效果及交互操作。比如点击某一Legend(图例),可以显示或隐藏该Legend下的数据集合,从而得到部分Legend局部对比图,右上角还提供了在线打印功能。





















猜你喜欢

转载自blog.csdn.net/u012373405/article/details/51289523
今日推荐