Echart+jsp+mysq实现多条曲线实时动态展示。

Echart+jsp+mysq实现多条曲线实时动态展示

背景

接到领导命令,原项目中.net.缺少一个事实展示数据库数据库的曲线图,因为我以前用过java,他让我在java中寻找建立曲线图的快捷方法,可以通过网页浏览曲线图。

源代码:源代码

废话不多说直接开搞:

1.数据源

要显示数据必须要有数据源,由于项目中采用Oracle数据库,但是由于我是实验目的不让我直接连接项目数据库,因此我采用免费的mysql数据库新建了一个数据源。
下载mysql安装mysql不在多说了。
mysql下载
mysql安装参考

安装完新建数据实例

创建数据库实例
新建数据表
在表中按照数据格式插入一些数据。

2.创建项目

  1. 采用MyEclipse创建一个webserver项目。
  2. 项目中添加依赖文件和包:新建js文件夹添加echart.js在lib文件夹下添加外部依赖包。如图
    项目结构
    3.创建网页showInfoIndex.html

网页中主要采用HTML-jsp方法实现。

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html lang="zh-CN">
	<head>
	
		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
		<meta http-equiv="X-UA-Compatible" content="IE=edge">   <!-- 在IE运行最新的渲染模式 -->
		<meta name="viewport" content="width=device-width, initial-scale=1">    <!-- 初始化移动浏览显示  -->
		<meta name="Author" content="Dreamer-1.">		
		
		<script type="text/javascript" src="js/jquery-1.12.3.min.js"></script>
		<script type="text/javascript" src="js/echarts.common.min.js"></script>
	
	<title>- 观测数据 -</title>
	</head>

	<body>

		<!-- 显示Echarts图表 -->
		<div style="height:410px;min-height:100px;margin:0 auto;" id="main"></div>						
            		
  	
  
		<script type="text/javascript">
			
		// 基于准备好的dom,初始化echarts实例
        var myChart = echarts.init(document.getElementById('main'));

        // 指定图表的配置项和数据
        var option = {
            title: {	//图表标题
                text: '过去五天数据图表'
            },
            tooltip: {
                trigger: 'axis', //坐标轴触发提示框,多用于柱状、折线图中
                /*
 				控制提示框内容输出格式
                formatter: '{b0}<br/><font color=#FF3333>&nbsp;●&nbsp;</font>{a0} : {c0} ℃ ' + 
               				'<br/><font color=#53FF53>●&nbsp;</font>{a1} : {c1} % ' +          
               				'<br/><font color=#68CFE8>&nbsp;●&nbsp;</font>{a3} : {c3} mm ' +
               				'<br/><font color=#FFDC35>&nbsp;●&nbsp;</font>{a4} : {c4} m/s ' +
               				'<br/><font color=#B15BFF>&nbsp;&nbsp;&nbsp;&nbsp;●&nbsp;</font>{a2} : {c2} hPa ' 
                */
            },
            dataZoom: [
                 {
                     type: 'slider',	//支持鼠标滚轮缩放
                     start: 0,			//默认数据初始缩放范围为10%到90%
                     end: 100
                 },
                 {
                     type: 'inside',	//支持单独的滑动条缩放
                     start: 0,			//默认数据初始缩放范围为10%到90%
                     end: 100
                 }
            ],
            legend: {	//图表上方的类别显示           	
            	show:true,
            	data:['温度(℃)','湿度(%)','雨量(mm)','风速(m/s)','压强(hPa)']
            },
            color:[
                   '#FF3333',	//温度曲线颜色
                   '#53FF53',	//湿度曲线颜色
                   '#B15BFF',	//压强图颜色
                   '#68CFE8',	//雨量图颜色
                   '#FFDC35'	//风速曲线颜色
                   ],
            toolbox: {	//工具栏显示         	
                show: true,
                feature: {                
                    saveAsImage: {}		//显示“另存为图片”工具
                }
            },
            xAxis:  {	//X轴       	
                type : 'category',
                data : []	//先设置数据值为空,后面用Ajax获取动态数据填入
            },
            yAxis : [	//Y轴(这里我设置了两个Y轴,左右各一个)
						{
            				//第一个(左边)Y轴,yAxisIndex为0
	                         type : 'value',
	                         name : '温度',
	                         /* max: 120,
	                         min: -40, */
	                         axisLabel : {
	                             formatter: '{value} ℃'	//控制输出格式
	                         }
	                     },
	                     {
	                    	//第二个(右边)Y轴,yAxisIndex为1
	                         type : 'value',
	                         name : '压强',
	                         scale: true,
	                         axisLabel : {
	                             formatter: '{value} hPa'
	                         }
	                     }
	                 
            ],
            series : [	//系列(内容)列表                      
						{
		                    name:'温度(℃)',
		                    type:'line',	//折线图表示(生成温度曲线)
		                    symbol:'emptycircle',	//设置折线图中表示每个坐标点的符号;emptycircle:空心圆;emptyrect:空心矩形;circle:实心圆;emptydiamond:菱形	                    
		                    data:[]		//数据值通过Ajax动态获取
		                },
		                
		                {
		                    name:'湿度(%)',
		                    type:'line',
		                    symbol:'emptyrect',
		                    data:[]
		                },
		                
		                {
		                    name:'压强(hPa)',
		                    type:'line',
		                    symbol:'circle',	//标识符号为实心圆
		                    yAxisIndex: 1,		//与第二y轴有关
		                    data:[]
		                },
		                
		                {
		                    name:'雨量(mm)',
		                    type:'bar',		//柱状图表示
		                    //barMinHeight: 10,	//柱条最小高度,可用于防止某数据项的值过小而影响交互
		                    /* label: {	//显示值
		                        normal: {
		                            show: true,
		                            position: 'top'
		                        }
		                    }, */
		                    data:[]
		                },
		                
		                {
		                    name:'风速(m/s)',
		                    type:'line',
		                    symbol:'emptydiamond',
		                    data:[]
		                }	            
            ]
        };
		 
		myChart.showLoading();	//数据加载完之前先显示一段简单的loading动画
		 
		 var tems=[];		//温度数组(存放服务器返回的所有温度值)
		 var hums=[];		//湿度数组
		 var pas=[];		//压强数组
		 var rains=[];		//雨量数组
		 var win_sps=[];	//风速数组
		 var dates=[];		//时间数组
		 
         $.ajax({	//使用JQuery内置的Ajax方法
         type : "post",		//post请求方式
         async : true,		//异步请求(同步请求将会锁住浏览器,用户其他操作必须等待请求完成才可以执行)
         url : "ShowInfoIndexServlet",	//请求发送到ShowInfoIndexServlet处
         data : {name:"A0001"},		//请求内包含一个key为name,value为A0001的参数;服务器接收到客户端请求时通过request.getParameter方法获取该参数值
         dataType : "json",		//返回数据形式为json
         success : function(result) {
        	 //请求成功时执行该函数内容,result即为服务器返回的json对象
	         if (result != null && result.length > 0) {
	                for(var i=0;i<result.length;i++){       
	                   tems.push(result[i].tem);		//挨个取出温度、湿度、压强等值并填入前面声明的温度、湿度、压强等数组
	                   hums.push(result[i].hum);
	                   pas.push(result[i].pa);
	                   rains.push(result[i].rain);
	                   win_sps.push(result[i].win_sp);
	                   dates.push(result[i].dateStr);
	                }
	                myChart.hideLoading();	//隐藏加载动画
	                
	                myChart.setOption({		//载入数据
	   		         xAxis: {
	   		             data: dates	//填入X轴数据
	   		         },
	   		         series: [	//填入系列(内容)数据
	   		               		{
			   		             // 根据名字对应到相应的系列
			   		             name: '温度',
			   		             data: tems
	   		         		},
	   		               		{
			   		             name: '湿度',
			   		             data: hums
	   		         		},
	   		         			{
			   		             name: '压强',
			   		             data: pas
	   		         		},
	   		         			{
			   		             name: '雨量',
			   		             data: rains
	   		         		},
	   		         			{
		   		             name: '风速',
		   		             data: win_sps
  		         			}
	   		        ]
	   		     });
	                
	         }
	         else {
	        	 //返回的数据为空时显示提示信息
	        	 alert("图表请求数据为空,可能服务器暂未录入近五天的观测数据,您可以稍后再试!");
	          	 myChart.hideLoading();
	         }
         
		},
     	error : function(errorMsg) {
     		//请求失败时执行该函数
         	alert("图表请求数据失败,可能是服务器开小差了");
         	myChart.hideLoading();    	
     	}
    })

    myChart.setOption(option);	//载入图表
		 
    </script>
		
	</body>
</html>

4.创建serverlet类,由jsp调用serverlet访问数据源。

package EchartsExample;

import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.*;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.google.gson.Gson;

/**
 * 响应观测记录展示页的Echarts图表数据请求(使用json格式返回客户端需要的数据)
 * @author zhong
 *
 */
public class ShowInfoIndexServlet extends HttpServlet {
       
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		doPost(req,resp);
	}

	@Override
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

		request.setCharacterEncoding("UTF-8");	//设定客户端提交给servlet的内容按UTF-8编码
		response.setCharacterEncoding("UTF-8");	//设定servlet传回给客户端的内容按UTF-8编码
		response.setContentType("text/html;charset=UTF-8");	//告知浏览器用UTF-8格式解析内容
				
		String name = request.getParameter("name");	//获取台站名参数
		
		//获取当天在内的五天以前的0点格式字符串(用于数据库查询)
		Calendar  cal = Calendar.getInstance();
		cal.add(Calendar.DATE, -4);		//获取当天在内的五天以前的日期时间
		SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd 00:00:00");	//设定日期格式
		String fiveDaysAgoStr = sdf1.format(cal.getTime());	//将五天前的日期时间按指定格式转换成字符串
//System.out.println(fiveDaysAgoStr);				
		//获取当前时间并将其转换成指定格式的字符串(用于数据库查询)
		Date now = new Date();  
        SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  
        String nowStr = sdf2.format(now);  
//System.out.println(nowStr);      
		
        
        
//======================================连接数据库操作============================================================================================        
		/*
		 * 连接数据库并获取五天内该名称的气象站的所有采集数据
		 */
		List<Record> records = new ArrayList<Record>();	//用一个ArrayList来盛装封装了各气象数据的对象
		
		Connection conn = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		
		try {
			conn = DBUtil.getConnection();	//获取与数据库的连接
			String sql = "select * from alldata where data_taizhan_num = ? and data_date >= ? and data_date <= ? order by data_date asc";	//初始化SQL查询语句
			pstmt = conn.prepareStatement(sql);	//创建preparedStatement语句对象	
			pstmt.setString(1, name);	//设定查询参数
			pstmt.setString(2, fiveDaysAgoStr);
			pstmt.setString(3, nowStr);
			rs = pstmt.executeQuery();	//获取查询到的结果集
			while (rs.next()) {
				//封装Record对象
				Record r = new Record();
				r.setTaizhan_num(rs.getString(1));
				r.setDate(rs.getTimestamp(2));
				r.setTem(rs.getString(3));
				r.setHum(rs.getString(4));
				r.setPa(rs.getString(5));
				r.setRain(rs.getString(6));
				r.setWin_dir(rs.getString(7));
				r.setWin_sp(rs.getString(8));
				
				//将时间转换成给定格式便于echarts的X轴日期坐标显示
				SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");			 
			    String str = sdf.format(rs.getTimestamp(2));
			    r.setDateStr(str);
//System.out.println(r.getTem()+" | "+r.getHum()+" | "+r.getPa()+" | "+r.getRain()+" | "+r.getWin_dir()+" | "+r.getWin_sp());											
				records.add(r);		//将封装好的Record对象放入列表容器中
			}
			
			
			
		} catch (SQLException e) {
			System.out.println("查询出错,操作未完成!");
			e.printStackTrace();
		} finally {
			//查询结束后释放资源
			DBUtil.close(rs);
			DBUtil.close(pstmt);
			DBUtil.close(conn);
			System.out.println("查询sucess,操作完成!");
		}    
//======================================连接数据库操作(完)============================================================================================         
        
		
		
      //将list中的对象转换为Json格式的数组
        Gson gson = new Gson();					
		String json = gson.toJson(records);	
		
//System.out.println(json);
		
		//将json数据返回给客户端
		response.setContentType("text/html; charset=utf-8");
		response.getWriter().write(json);
	}

}

5.创建数据库访问,数据库连接池。

package EchartsExample;

import java.sql.*;

import org.apache.tomcat.jdbc.pool.DataSource;
import org.apache.tomcat.jdbc.pool.PoolProperties;

/**
 * 数据库工具类(采用了tomcat jdbc pool)
 * @author zhong
 *
 */
public class DBUtil {
private static DataSource ds;
	
	static {
		//配置tomcat jdbc pool (连接池)
        PoolProperties p = new PoolProperties();
        p.setUrl("jdbc:mysql://localhost:3306/blogexample");	//设置连接的url
        p.setDriverClassName("com.mysql.cj.jdbc.Driver");	//载入数据库驱动
        p.setUsername("root");	//用于远程连接的用户名
        p.setPassword("mysql");	//密码
        p.setJmxEnabled(true);
        p.setTestWhileIdle(false);
        p.setTestOnBorrow(true);
        p.setValidationQuery("SELECT 1");
        p.setTestOnReturn(false);
        p.setValidationInterval(30000);
        p.setTimeBetweenEvictionRunsMillis(30000);
        p.setMaxActive(100);
        p.setInitialSize(10);
        p.setMaxWait(10000);
        p.setRemoveAbandonedTimeout(60);
        p.setMinEvictableIdleTimeMillis(30000);
        p.setMinIdle(10);
        p.setLogAbandoned(true);
        p.setRemoveAbandoned(true);
        p.setJdbcInterceptors(
          "org.apache.tomcat.jdbc.pool.interceptor.ConnectionState;"+
          "org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer");
        ds = new DataSource();
        ds.setPoolProperties(p);
	}
	
	private DBUtil() {}
	
	/**
	 * 获取一个数据库连接(Connection);
	 * @return Database Connection
	 */
	public static Connection getConnection() {
		Connection conn = null;
		
		try {			
			conn = ds.getConnection();
		} catch (SQLException e) {
			e.printStackTrace();
		}
		
		return conn;
	}
	
	/**
	 * 关闭传入的Connection;
	 * @param conn 待关闭的Connection
	 */
	public static void close(Connection conn) {
		try {
			if (conn != null) {
				conn.close();
				conn = null;
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 关闭传入的Statement;
	 * @param stmt	待关闭的Statement
	 */
	public static void close(Statement stmt) {
		try {
			if (stmt != null) {
				stmt.close();
				stmt = null;
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 关闭传入的ResultSet;
	 * @param rs	待关闭的ResultSet
	 */
	public static void close(ResultSet rs) {
		try {
			if (rs != null) {
				rs.close();
				rs = null;
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
}

6.创建曲线数据类

package EchartsExample;

import java.sql.*;

/**
 * 封装气象数据信息
 * @author zhong
 *
 */

public class Record {
	private String taizhan_num;	//台站名
	private String tem;			//温度
	private String hum;			//湿度
	private String pa;			//压强
	private String rain;		//雨量
	private String win_dir;		//风向
	private String win_sp;		//风速
	private String dateStr;		//观测日期(用于Echarts显示格式)
	private Timestamp date;		//观测日期(原始格式)
	
	/**
	 * 获取观测日期(用于echarts图表展示);
	 * @return 观测日期值
	 */
	public String getDateStr() {
		return dateStr;
	}

	/**
	 * 设置观测日期(用于echarts图表展示);
	 * @param dateStr 待设置观测日期值
	 */
	public void setDateStr(String dateStr) {
		this.dateStr = dateStr;
	}
	
	/**
	 * 获取产生该观测记录的台站名称;
	 * @return 台站名称
	 */
	public String getTaizhan_num() {
		return taizhan_num;
	}

	/**
	 * 设置产生该观测记录的台站名称;
	 * @param taizhan_num 待设置台站名称
	 */
	public void setTaizhan_num(String taizhan_num) {
		this.taizhan_num = taizhan_num;
	}

	/**
	 * 获取温度;
	 * @return 温度值
	 */
	public String getTem() {
		return tem;
	}

	/**
	 * 设置温度;
	 * @param tem 待设置温度值
	 */
	public void setTem(String tem) {
		this.tem = tem;
	}

	/**
	 * 获取湿度;
	 * @return 湿度值 
	 */
	public String getHum() {
		return hum;
	}

	/**
	 * 设置湿度;
	 * @param hum 待设置湿度值
	 */
	public void setHum(String hum) {
		this.hum = hum;
	}

	/**
	 * 获取压强;
	 * @return 压强值
	 */
	public String getPa() {
		return pa;
	}

	/**
	 * 设置压强;
	 * @param pa 待设置压强值
	 */
	public void setPa(String pa) {
		this.pa = pa;
	}

	/**
	 * 获取雨量;
	 * @return 雨量值
	 */
	public String getRain() {
		return rain;
	}

	/**
	 * 设置雨量;
	 * @param rain 待设置雨量值
	 */
	public void setRain(String rain) {
		this.rain = rain;
	}

	/**
	 * 获取风向;
	 * @return 风向值
	 */
	public String getWin_dir() {
		return win_dir;
	}

	/**
	 * 设置风向;
	 * @param win_dir 待设置风向值
	 */
	public void setWin_dir(String win_dir) {
		this.win_dir = win_dir;
	}

	/**
	 * 获取风速;
	 * @return 风速值
	 */
	public String getWin_sp() {
		return win_sp;
	}

	/**
	 * 设置风向;
	 * @param win_sp 待设置风向值
	 */
	public void setWin_sp(String win_sp) {
		this.win_sp = win_sp;
	}

	/**
	 * 获取观测日期;
	 * @return 观测日期
	 */
	public Timestamp getDate() {
		return date;
	}

	/**
	 * 设置观测日期; 
	 * @param date 观测日期值
	 */
	public void setDate(Timestamp date) {
		this.date = date;
	}
}

8.修改web访问配置

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1">
  <display-name>LineChart_BOF</display-name>
	<welcome-file-list>
	    <welcome-file>index.html</welcome-file>
	    <welcome-file>index.htm</welcome-file>
	    <welcome-file>index.jsp</welcome-file>
	    <welcome-file>default.html</welcome-file>
	    <welcome-file>default.htm</welcome-file>
    	<welcome-file>default.jsp</welcome-file>
	</welcome-file-list>
  
	<servlet>
	    <servlet-name>ShowInfoIndexServlet</servlet-name>
	    <servlet-class>EchartsExample.ShowInfoIndexServlet</servlet-class>
	</servlet>
	<servlet-mapping>
	    <servlet-name>ShowInfoIndexServlet</servlet-name>
	    <url-pattern>/ShowInfoIndexServlet</url-pattern>
	</servlet-mapping>
</web-app>

启动效果:

启动效果图

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值