最新文章专题视频专题问答1问答10问答100问答1000问答2000关键字专题1关键字专题50关键字专题500关键字专题1500TAG最新视频文章推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37视频文章20视频文章30视频文章40视频文章50视频文章60 视频文章70视频文章80视频文章90视频文章100视频文章120视频文章140 视频2关键字专题关键字专题tag2tag3文章专题文章专题2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章专题3
当前位置: 首页 - 科技 - 知识百科 - 正文

使用Echarts实现动态曲线图表

来源:懂视网 责编:小采 时间:2020-11-27 16:29:17
文档

使用Echarts实现动态曲线图表

使用Echarts实现动态曲线图表:最近做的一个在线气象观测网站要实现一个需求:使用图表展示最近五天温湿度等气象要素的曲线变化具体效果参考:http://www.weatherobserve.com/showInfoIndex.jsp 下面就详述一下实现过程吧(注:相较于原网页我隐去了很多内容,本实现过程就只专注于Echa
推荐度:
导读使用Echarts实现动态曲线图表:最近做的一个在线气象观测网站要实现一个需求:使用图表展示最近五天温湿度等气象要素的曲线变化具体效果参考:http://www.weatherobserve.com/showInfoIndex.jsp 下面就详述一下实现过程吧(注:相较于原网页我隐去了很多内容,本实现过程就只专注于Echa
最近做的一个在线气象观测网站要实现一个需求:使用图表展示最近五天温湿度等气象要素的曲线变化

具体效果参考:

http://www.weatherobserve.com/showInfoIndex.jsp 946400-20160526105217084-1735183663.png

下面就详述一下实现过程吧(注:相较于原网页我隐去了很多内容,本实现过程就只专注于Echarts图表实现)

一:

HTML页面部分,代码如下:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
 <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>

二:

Servlet部分,客户端请求提交到 ShowInfoIndex 处,先在 web.xml 里配置一下Servlet映射:

<?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" id="WebApp_ID" version="3.1">
 <display-name>BlogExample</display-name>

 <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>

关于ShowInfoIndexServlet,简单说一下请求-响应中间的过程:

客户端发送图表请求给Servlet,Servlet接收到请求后先获取客户端请求查看的气象站名称,然后从数据库(SqlServer2005 Express版)中获取最近五天内该气象站所有的采集数据(装在List中),再用Gson工具将该List转换成Json对象返回给客户端,客户端接收到返回的Json对象后对其进行解析并将相应数据填入Echarts中,然后作显示;

其中Record.java是只对外提供get/set方法的用于封装数据的普通实体类,DBUtil.java是JDBC方式下专门提供Connection、Statement、ResultSet等的数据库工具类。

(原本的连接数据库并获取数据过程需经过业务逻辑层与数据访问层,较为复杂,这里隐去这两层,直接在Servlet内连接数据库并拿取数据)

Ps:墙裂建议使用PreparedStatement进行参数化查询,这样可以有效避免SQL注入!

ShowInfoIndexServlet代码如下:

其中用到了Google的Gson工具包(提供java-json对象间的转换,下载后放在 WRB-INF/lib 目录下即可)

下载地址:http://mvnrepository.com/artifact/com.google.code.gson/gson

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.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()); //将五天前的日期时间按指定格式转换成字符串
 
 //获取当前时间并将其转换成指定格式的字符串(用于数据库查询)
 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);
 } 
//======================================连接数据库操作(完)============================================================================================ 
 
 
 
 //将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);
 }

}

alldata表部分数据截图:

946400-20160526105218678-1300548380.png

Record类代码如下:

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;
 }

 
}

DBUitl类(数据库工具类)代码如下:

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:sqlserver://localhost:1433; DatabaseName=weather"); //设置连接的url
 p.setDriverClassName("com.microsoft.sqlserver.jdbc.SQLServerDriver"); //载入数据库驱动
 p.setUsername("sa"); //用于远程连接的用户名
 p.setPassword("2003NianDeDiYiChangXue"); //密码
 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();
 }
 }
 
}

——————————————————————————我是小小分割线

关于远程连接(包括使用Eclipse连接)SqlServer2005我再多嘴两句:

当确认连接的URL,驱动加载,用户名,密码都配置正确时,仍然抛出 java.lang.NullPointerException 的话,请打开开始菜单Microsoft SQL Server 2005软件目录下的SQL Server配置管理器:

①:启用SQL Server 2005网络配置 下的 SQLEXPRESS协议 内的 TCP/IP 协议,并右键TCP/IP协议选择属性,确保IP地址一栏最末的TCP端口为1433,具体见下图

946400-20160526105220491-975664781.png

②:启用 SQL Native Client配置 下的 客户端协议 内的 TCP/IP 协议,并右键查看TCP/IP 属性,确保端口为1433,具体见下图

946400-20160526105222256-566902208.png

③:重新启动 SQL Server 2005服务 下的 SQL Server服务,详情见下图

946400-20160526105223913-782948107.png

至此,应该就解决了java.lang.NullPointerException这个错误了。

————————————————————————我是小小分割线————————————————————————————————————

让我们再回到原来的Echarts图表显示过程上,你可以试着在后台打印看看转换出的Json字符串,关于Json的使用这里我不再多言解释

文档

使用Echarts实现动态曲线图表

使用Echarts实现动态曲线图表:最近做的一个在线气象观测网站要实现一个需求:使用图表展示最近五天温湿度等气象要素的曲线变化具体效果参考:http://www.weatherobserve.com/showInfoIndex.jsp 下面就详述一下实现过程吧(注:相较于原网页我隐去了很多内容,本实现过程就只专注于Echa
推荐度:
标签: 设置 折线图 动态
  • 热门焦点

最新推荐

猜你喜欢

热门推荐

专题
Top