0

0

使用Echarts实现动态曲线图表

php中文网

php中文网

发布时间:2016-05-26 15:25:31

|

3912人浏览过

|

来源于php中文网

原创

最近做的一个在线气象观测网站要实现一个需求:使用图表展示最近五天温湿度等气象要素的曲线变化

具体效果参考:http://www.weatherobserve.com/showInfoIndex.jsp

图示如下(2016-5-25日的数据):

无标题

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

 

一:

HTML页面部分,代码如下:

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

        
        <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}
{a0} : {c0} ℃ ' + '
{a1} : {c1} % ' + '
{a3} : {c3} mm ' + '
{a4} : {c4} m/s ' + '
{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>BlogExampledisplay-name>

    <servlet>
        <servlet-name>ShowInfoIndexServletservlet-name>
        <servlet-class>EchartsExample.ShowInfoIndexServletservlet-class>
    servlet>
    <servlet-mapping>
        <servlet-name>ShowInfoIndexServletservlet-name>
        <url-pattern>/ShowInfoIndexServleturl-pattern>
    servlet-mapping>
  
web-app>

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

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

通用产品企业网站(.NET2.0)1.0
通用产品企业网站(.NET2.0)1.0

1、系统采用.net2.0开发,数据库access2、三层架构,数据层、逻辑层和表示层分离3、系统完全使用div+css布局,可以灵活处理界面4、技术特点: 使用模板页,大大减少代码量 动态生成竖向导航菜单 ul li实现表格 各种自定义用户空间 Reapter等数据控件的灵活运用

下载

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

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

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

 

ShowInfoIndexServlet代码如下:

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 records = new ArrayList();    //用一个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表部分数据截图:

数据库截图

 

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

    

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
Python 序列化
Python 序列化

本专题整合了python序列化、反序列化相关内容,阅读专题下面的文章了解更多详细内容。

0

2026.02.02

AO3官网入口与中文阅读设置 AO3网页版使用与访问
AO3官网入口与中文阅读设置 AO3网页版使用与访问

本专题围绕 Archive of Our Own(AO3)官网入口展开,系统整理 AO3 最新可用官网地址、网页版访问方式、正确打开链接的方法,并详细讲解 AO3 中文界面设置、阅读语言切换及基础使用流程,帮助用户稳定访问 AO3 官网,高效完成中文阅读与作品浏览。

91

2026.02.02

主流快递单号查询入口 实时物流进度一站式追踪专题
主流快递单号查询入口 实时物流进度一站式追踪专题

本专题聚合极兔快递、京东快递、中通快递、圆通快递、韵达快递等主流物流平台的单号查询与运单追踪内容,重点解决单号查询、手机号查物流、官网入口直达、包裹进度实时追踪等高频问题,帮助用户快速获取最新物流状态,提升查件效率与使用体验。

27

2026.02.02

Golang WebAssembly(WASM)开发入门
Golang WebAssembly(WASM)开发入门

本专题系统讲解 Golang 在 WebAssembly(WASM)开发中的实践方法,涵盖 WASM 基础原理、Go 编译到 WASM 的流程、与 JavaScript 的交互方式、性能与体积优化,以及典型应用场景(如前端计算、跨平台模块)。帮助开发者掌握 Go 在新一代 Web 技术栈中的应用能力。

11

2026.02.02

PHP Swoole 高性能服务开发
PHP Swoole 高性能服务开发

本专题聚焦 PHP Swoole 扩展在高性能服务端开发中的应用,系统讲解协程模型、异步IO、TCP/HTTP/WebSocket服务器、进程与任务管理、常驻内存架构设计。通过实战案例,帮助开发者掌握 使用 PHP 构建高并发、低延迟服务端应用的工程化能力。

5

2026.02.02

Java JNI 与本地代码交互实战
Java JNI 与本地代码交互实战

本专题系统讲解 Java 通过 JNI 调用 C/C++ 本地代码的核心机制,涵盖 JNI 基本原理、数据类型映射、内存管理、异常处理、性能优化策略以及典型应用场景(如高性能计算、底层库封装)。通过实战示例,帮助开发者掌握 Java 与本地代码混合开发的完整流程。

5

2026.02.02

go语言 注释编码
go语言 注释编码

本专题整合了go语言注释、注释规范等等内容,阅读专题下面的文章了解更多详细内容。

62

2026.01.31

go语言 math包
go语言 math包

本专题整合了go语言math包相关内容,阅读专题下面的文章了解更多详细内容。

55

2026.01.31

go语言输入函数
go语言输入函数

本专题整合了go语言输入相关教程内容,阅读专题下面的文章了解更多详细内容。

27

2026.01.31

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
UNI-APP开发(仿饿了么)
UNI-APP开发(仿饿了么)

共32课时 | 8.8万人学习

JavaScript OOP调试技巧视频教程
JavaScript OOP调试技巧视频教程

共5课时 | 1.0万人学习

Uniapp微信小程序1:1仿饿了么首页
Uniapp微信小程序1:1仿饿了么首页

共5课时 | 2.1万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号