Echarts を使用して動的曲線チャートを実装する

PHP中文网
リリース: 2016-06-24 11:16:53
オリジナル
2983 人が閲覧しました

私は最近、要件を満たすためにオンライン気象観測 Web サイトを構築しました。グラフを使用して、過去 5 日間の気温や湿度などの気象要素の曲線変化を表示します

具体的な効果についての参照:

http://www. Weatherobserve.com/showInfoIndex.jsp Echarts を使用して動的曲線チャートを実装する

実装プロセスを詳しく説明しましょう (注: 元の Web ページと比較して、多くのコンテンツを非表示にしています。この実装プロセスは Echarts チャートの実装のみに焦点を当てています)

1:

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(&#39;main&#39;));

        // 指定图表的配置项和数据
        var option = {
            title: {    //图表标题
                text: &#39;过去五天数据图表&#39;
            },
            tooltip: {
                trigger: &#39;axis&#39;, //坐标轴触发提示框,多用于柱状、折线图中
                /*
                 控制提示框内容输出格式
                formatter: &#39;{b0}<br/><font color=#FF3333> ● </font>{a0} : {c0} ℃ &#39; + 
                               &#39;<br/><font color=#53FF53>● </font>{a1} : {c1} % &#39; +          
                               &#39;<br/><font color=#68CFE8> ● </font>{a3} : {c3} mm &#39; +
                               &#39;<br/><font color=#FFDC35> ● </font>{a4} : {c4} m/s &#39; +
                               &#39;<br/><font color=#B15BFF>    ● </font>{a2} : {c2} hPa &#39; 
                */
            },
            dataZoom: [
                 {
                     type: &#39;slider&#39;,    //支持鼠标滚轮缩放
                     start: 0,            //默认数据初始缩放范围为10%到90%
                     end: 100
                 },
                 {
                     type: &#39;inside&#39;,    //支持单独的滑动条缩放
                     start: 0,            //默认数据初始缩放范围为10%到90%
                     end: 100
                 }
            ],
            legend: {    //图表上方的类别显示               
                show:true,
                data:[&#39;温度(℃)&#39;,&#39;湿度(%)&#39;,&#39;雨量(mm)&#39;,&#39;风速(m/s)&#39;,&#39;压强(hPa)&#39;]
            },
            color:[
                   &#39;#FF3333&#39;,    //温度曲线颜色
                   &#39;#53FF53&#39;,    //湿度曲线颜色
                   &#39;#B15BFF&#39;,    //压强图颜色
                   &#39;#68CFE8&#39;,    //雨量图颜色
                   &#39;#FFDC35&#39;    //风速曲线颜色
                   ],
            toolbox: {    //工具栏显示             
                show: true,
                feature: {                
                    saveAsImage: {}        //显示“另存为图片”工具
                }
            },
            xAxis:  {    //X轴           
                type : &#39;category&#39;,
                data : []    //先设置数据值为空,后面用Ajax获取动态数据填入
            },
            yAxis : [    //Y轴(这里我设置了两个Y轴,左右各一个)
                        {
                            //第一个(左边)Y轴,yAxisIndex为0
                             type : &#39;value&#39;,
                             name : &#39;温度&#39;,
                             /* max: 120,
                             min: -40, */
                             axisLabel : {
                                 formatter: &#39;{value} ℃&#39;    //控制输出格式
                             }
                         },
                         {
                            //第二个(右边)Y轴,yAxisIndex为1
                             type : &#39;value&#39;,
                             name : &#39;压强&#39;,
                             scale: true,
                             axisLabel : {
                                 formatter: &#39;{value} hPa&#39;
                             }
                         }
                     
            ],
            series : [    //系列(内容)列表                      
                        {
                            name:&#39;温度(℃)&#39;,
                            type:&#39;line&#39;,    //折线图表示(生成温度曲线)
                            symbol:&#39;emptycircle&#39;,    //设置折线图中表示每个坐标点的符号;emptycircle:空心圆;emptyrect:空心矩形;circle:实心圆;emptydiamond:菱形                        
                            data:[]        //数据值通过Ajax动态获取
                        },
                        
                        {
                            name:&#39;湿度(%)&#39;,
                            type:&#39;line&#39;,
                            symbol:&#39;emptyrect&#39;,
                            data:[]
                        },
                        
                        {
                            name:&#39;压强(hPa)&#39;,
                            type:&#39;line&#39;,
                            symbol:&#39;circle&#39;,    //标识符号为实心圆
                            yAxisIndex: 1,        //与第二y轴有关
                            data:[]
                        },
                        
                        {
                            name:&#39;雨量(mm)&#39;,
                            type:&#39;bar&#39;,        //柱状图表示
                            //barMinHeight: 10,    //柱条最小高度,可用于防止某数据项的值过小而影响交互
                            /* label: {    //显示值
                                normal: {
                                    show: true,
                                    position: &#39;top&#39;
                                }
                            }, */
                            data:[]
                        },
                        
                        {
                            name:&#39;风速(m/s)&#39;,
                            type:&#39;line&#39;,
                            symbol:&#39;emptydiamond&#39;,
                            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: &#39;温度&#39;,
                                    data: tems
                                },
                                      {
                                    name: &#39;湿度&#39;,
                                    data: hums
                                },
                                    {
                                    name: &#39;压强&#39;,
                                    data: pas
                                },
                                    {
                                    name: &#39;雨量&#39;,
                                    data: rains
                                },
                                    {
                                name: &#39;风速&#39;,
                                data: win_sps
                               }
                       ]
                    });
                    
             }
             else {
                 //返回的数据为空时显示提示信息
                 alert("图表请求数据为空,可能服务器暂未录入近五天的观测数据,您可以稍后再试!");
                   myChart.hideLoading();
             }
         
        },
         error : function(errorMsg) {
             //请求失败时执行该函数
             alert("图表请求数据失败,可能是服务器开小差了");
             myChart.hideLoading();        
         }
    })

    myChart.setOption(option);    //载入图表
         
    </script>
        
    </body>
</html>
ログイン後にコピー


2 つ:

サーブレット パーツ、クライアント リクエストが ShowInfoIndex に送信され、最初に web.xml でサーブレット マッピングを構成します:

<?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 について簡単に説明しますリクエストとレスポンスのプロセスについて説明します:

クライアントはサーブレットにチャートリクエストを送信します。リクエストを受信した後、サーブレットはまずクライアントがリクエストした気象観測所の名前を取得し、次に気象観測所の収集されたデータをすべて取得します。過去 5 日間のデータをデータベース (SqlServer2005 Express バージョン) ( List にインストールされている) から取得し、Gson ツールを使用して List を Json オブジェクトに変換し、クライアントに返します。返された Json オブジェクトを受信した後、クライアントは解析します。

その中で、Record.java はデータをカプセル化するために使用される通常のエンティティ クラスであり、外部に get/set メソッドを提供するだけです。 JDBC モードで特に Connection、Statement、ResultSet などを提供するクラス。

(データベースに接続してデータを取得する元のプロセスでは、ビジネス ロジック層とデータ アクセス層を経由する必要がありますが、これは比較的複雑です。これら 2 つの層はここでは隠されており、データベースはサーブレットとデータに直接接続されています。が取得されます)

追記: SQL インジェクションを効果的に回避できる、PreparedStatement がパラメーター化されたクエリを実行することをお勧めします。

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 テーブルの部分データのスクリーンショット:

Echarts を使用して動的曲線チャートを実装する

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 がまだスローされる場合は、SQL Server 構成を開いてください。スタート メニューの Microsoft SQL Server 2005 ソフトウェア ディレクトリでの管理 デバイス:

①: SQL Server 2005 ネットワーク構成の SQLEXPRESS プロトコルで TCP/IP プロトコルを有効にし、TCP/IP プロトコルを右クリックしてプロパティを選択します。 IP アドレス列の末尾の TCP ポートが 1433 であることを確認してください。詳細については、以下の図を参照してください

Echarts を使用して動的曲線チャートを実装する

②: SQL Native Client 構成でクライアント プロトコルで TCP/IP プロトコルを有効にします。クリックして TCP/IP プロパティを表示し、ポートが 1433 であることを確認します。詳細については、以下の図を参照してください

Echarts を使用して動的曲線チャートを実装する


③: SQL Server 2005 サービスで SQL Server サービスを再起動します。詳細については、以下の図を参照してください。

Echarts を使用して動的曲線チャートを実装する

この時点で、java.lang.NullPointerException エラーは解決されるはずです。

——————————————————————————————私は小さな境界線です———————————— ———— ————————————————————

元の Echarts チャート表示プロセスに戻り、バックグラウンドで印刷して、変換されたチャートを確認してみてください。 Json文字列、Jsonの使い方についてはこれ以上説明しません



ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート