Echart+jsp+mysq实现多条曲线实时动态展示
背景
接到领导命令,原项目中.net.缺少一个事实展示数据库数据库的曲线图,因为我以前用过java,他让我在java中寻找建立曲线图的快捷方法,可以通过网页浏览曲线图。
源代码:源代码
废话不多说直接开搞:
1.数据源
要显示数据必须要有数据源,由于项目中采用Oracle数据库,但是由于我是实验目的不让我直接连接项目数据库,因此我采用免费的mysql数据库新建了一个数据源。
下载mysql安装mysql不在多说了。
mysql下载
mysql安装参考
安装完新建数据实例
在表中按照数据格式插入一些数据。
2.创建项目
- 采用MyEclipse创建一个webserver项目。
- 项目中添加依赖文件和包:新建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> ● </font>{a0} : {c0} ℃ ' +
'<br/><font color=#53FF53>● </font>{a1} : {c1} % ' +
'<br/><font color=#68CFE8> ● </font>{a3} : {c3} mm ' +
'<br/><font color=#FFDC35> ● </font>{a4} : {c4} m/s ' +
'<br/><font color=#B15BFF> ● </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>