效果圖:
我在服務器上設置了10點和18點的定時任務,及時爬取疫情數據,數據爬取的相關內容在上一篇博客。
這里提供國家、省份和城市的篩選,現存確診、累計確診、累計治愈和死亡人數的排序。
1、前端界面用了bootstrap4框架,通過ajax實現數據實時交互。
<%@page import="java.util.ArrayList"%> <%@page import="java.sql.Date"%> <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>主界面</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/4.3.1/css/bootstrap.min.css"> <script src="https://cdn.staticfile.org/jquery/3.2.1/jquery.min.js"></script> <script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script> <script src="https://cdn.staticfile.org/popper.js/1.15.0/umd/popper.min.js"></script> <script src="https://cdn.staticfile.org/twitter-bootstrap/4.3.1/js/bootstrap.min.js"></script> <script src="https://cdn.staticfile.org/echarts/4.3.0/echarts.min.js"></script> </head> <script type="text/javascript"> function Query(id){ var valu,date,type; switch(id){ case "btnquerycontury":{ valu=$('#querycontury').val(); if($('#querydate').val()==null||$('#querydate').val()==""){ date="1"; }else{ date=$('#querydate').val(); } type="contury"; break; } case "btnquerycity":{ valu=$('#querycity').val(); if($('#querydate').val()==null||$('#querydate').val()==""){ date="1"; }else{ date=$('#querydate').val(); } type="city"; break; } case "btnqueryprovince":{ valu=$('#queryprovince').val(); if($('#querydate').val()==null||$('#querydate').val()==""){ date="1"; }else{ date=$('#querydate').val(); } type="province"; break; } case "btnquerydate":{ valu=$('#dropdown').val(); type="date"; date=$('#querydate').val(); break; } }; valu=encodeURI(valu); $.ajax({ type : "POST", async : true, url : "Query?valu=" + valu +"&date=" + date+"&type="+type, success : function(data) { var obj = eval(data); var tbody = $('<tbody></tbody>'); $(obj).each( function(index) { var val = obj[index]; var tr = $('<tr></tr>'); tr.append('<td>' + val.state + '</td>' + '<td>' + val.name + '</td>' + '<td>' + val.confirm + '</td>' + '<td>' + val.current + '</td>' + '<td>' + val.suspect + '</td>' + '<td>' + val.cured + '</td>' + '<td>' + val.dead + '</td>' + '<td>' + val.date + '</td>'); tbody.append(tr); }); $('#mytable tbody').replaceWith(tbody); }, error: function(){ alert("查詢失敗!"); } }); } function refreshTable(valu, order, updown) { $.ajax({ type : "POST", async : true, url : "GetData?valu=" + valu + "&order=" + order + "&updown=" + updown, success : function(data) { { var obj = eval(data); var tbody = $('<tbody></tbody>'); $(obj).each( function(index) { var val = obj[index]; var tr = $('<tr></tr>'); tr.append('<td>' + val.state + '</td>' + '<td>' + val.name + '</td>' + '<td>' + val.confirm + '</td>' + '<td>' + val.current + '</td>' + '<td>' + val.suspect + '</td>' + '<td>' + val.cured + '</td>' + '<td>' + val.dead + '</td>' + '<td>' + val.date + '</td>'); tbody.append(tr); }); $('#mytable tbody').replaceWith(tbody); if (valu == "city") { $('#wuhannow').replaceWith( $('<p>注:武漢現存:' + obj[0].current + '</p>')); $('#dropdown').val("city"); $('#dropdown').text("城市"); $('#stat').text("省份"); $('#cont').text("城市"); } else if (valu == "province") { $('#hubeinow').replaceWith( $('<p>注:湖北現存:' + obj[0].current + '</p>')); $('#dropdown').val("province"); $('#dropdown').text("省份"); $('#stat').text("大洲"); $('#cont').text("省份"); } else { $('#dropdown').val("out"); $('#dropdown').text("國家"); $('#stat').text("大洲"); $('#cont').text("國家"); } } } }); } function refreshChart(valu, order, updown) { //判斷是否為排序篩選傳來的消息 if (valu == "aaa") { valu = $('#dropdown').val(); $('#dropdown_order').val(order); updown=$('#dropdown_updown').val(); switch (order) { case "currentt": { $('#dropdown_order').text("現存數排序"); break; } case "cured": { $('#dropdown_order').text("治愈數排序"); break; } case "confirmm": { $('#dropdown_order').text("總確診排序"); break; } case "dead": { $('#dropdown_order').text("死亡數排序"); break; } } }else if(valu=="bbb"){ valu = $('#dropdown').val(); order = $('#dropdown_order').val(); $('#dropdown_updown').val(updown); if(updown=="ASC"){ $('#dropdown_updown').text("升序"); }else{ $('#dropdown_updown').text("降序"); } }else{ order = $('#dropdown_order').val(); updown = $('#dropdown_updown').val(); } refreshTable(valu, order, updown); $.ajax({ type : "POST", async : true, //異步執行 url : "ShowData?q=" + valu+"&order="+order+"&updown="+updown, dataType : "json", //返回數據形式為json success : function(json) { if (json) { myChart.hideLoading(); myChart.setOption({ xAxis : { data : json.xAxisData }, series : json.seriesList }); } }, error : function(errorMsg) { alert("請求數據失敗" + errorMsg); } }) myChart.setOption(option); } </script> <body onload="refreshChart('out','currentt','DESC')"> <div class="container-fluid" align="center"> <div id="echart" style="width: 2000px; height: 300px;"></div> <script type="text/javascript"> // 基於准備好的dom,初始化echarts實例 var myChart = echarts.init(document.getElementById('echart')); // 指定圖表的配置項和數據 // 初始 option option = { title : { text : '小高的疫情統計——數據從3.20日開始爬取,每天10點、18點更新(app排序bug已修復,稍后提供下載鏈接)' }, tooltip : {}, legend : { data : [ ] }, xAxis : { type : "category", data : [] }, yAxis : [ { type : "value", } ], series : [ { name : "人數", type : "bar", data : [] } ] }; myChart.showLoading(); </script> <div class="container" align="center" style="margin-bottom: 20px; margin-left: 200px;" align="center"> <!-- //異步查詢區域--> <div class="container"> <div style="width: 100px; float: left; margin-right: 10px;" class="container"> <div class="dropdown"> <button class="btn btn-primary dropdown-toggle" role="button" id="dropdown" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" value="out">區域</button> <div class="dropdown-menu" aria-labelledby="dropdownMenuLink"> <button class="dropdown-item" value="out" onClick="refreshChart(this.value,'currentt','DESC')">國外</button> <button class="dropdown-item" value="province" onClick="refreshChart(this.value,'currentt','DESC')">省份(除湖北)</button> <button class="dropdown-item" value="city" onClick="refreshChart(this.value,'currentt','DESC')">城市(除武漢)</button> </div> </div> <br> <div class="dropdown"> <button class="btn btn-primary dropdown-toggle" role="button" id="dropdown_order" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" value="currentt">排序依據</button> <div class="dropdown-menu" aria-labelledby="dropdownMenuLink"> <button class="dropdown-item" value=currentt id="current" onClick="refreshChart('aaa','currentt','DESC')">現存確診</button> <button class="dropdown-item" value="confirmm" id="confirm" onClick="refreshChart('aaa','confirmm','DESC')">確診總數</button> <button class="dropdown-item" value="dead" id="dead" onClick="refreshChart('aaa','dead','DESC')">死亡數</button> <button class="dropdown-item" value="cured" id="cured" onClick="refreshChart('aaa','cured','DESC')">治愈數</button> </div> </div> <br> <div class="dropdown"> <button class="btn btn-primary dropdown-toggle" role="button" id="dropdown_updown" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" value="DESC">排序方向</button> <div class="dropdown-menu" aria-labelledby="dropdownMenuLink"> <button class="dropdown-item" value=currentt id="current" onClick="refreshChart('bbb','currentt','DESC')">降序</button> <button class="dropdown-item" value="confirmm" id="confirm" onClick="refreshChart('bbb','confirmm','ASC')">升序</button> </div> </div> </div> <!-- 文字描述 --> <div style="float: left; margin-left: 30px;" align="left"> <p id="wuhannow">注:武漢現存:</p> <p id="hubeinow"> 湖北現存:</p> <p>國家選項圖表中只顯示確診數前50的國家,</p> <p>其他國家請在右側的查詢框查詢或自己查下面的表哦~</p> </div> </div> <div class="container" style="margin-bottom: 20px; margin-left: 200px;" align="center"> <!-- 查詢表格 --> <input type="text" name="city" placeholder="國家查詢" id="querycontury" style="width: 250px; margin: 10px;"> <input type="button" value="查詢" class="btn btn-outline-primary" id="btnquerycontury" style="width: 250px;" onClick="Query(this.id)"><br> <input type="text" id="queryprovince" name="province" placeholder="(國內)省份查詢:格式:xx省或xx市" style="width: 250px; margin: 10px;"> <input id="btnqueryprovince" type="button" value="查詢" class="btn btn-outline-primary" style="width: 250px;" onClick="Query(this.id)"><br> <input type="text" id="querycity" name="city" placeholder="(國內)城市查詢:格式:xx區或xx市" style="width: 250px; margin: 10px;"> <input id="btnquerycity" type="button" value="查詢" class="btn btn-outline-primary" style="width: 250px;" onClick="Query(this.id)"><br> <input type="text" id="querydate" name="city" placeholder="日期查詢:格式:yyyy-mm-dd" style="width: 250px; margin: 10px;"> <input id="btnquerydate" type="button" value="查詢" class="btn btn-outline-primary" style="width: 250px;" onClick="Query(this.id)"> </div> </div> <!-- 展示表格 --> <table class="table table-hover" id="mytable"> <thead> <tr> <td id="stat">大洲</td> <td id="cont">國家</td> <td>累計確診</td> <td>現存確診</td> <td>疑似病例</td> <td>累計治愈</td> <td>死亡人數</td> <td>時間</td> </tr> </thead> <tbody></tbody> </table> </div> </body> </html>
2、后端主要是查詢數據庫然后發送給前端。
兩個類,一個用了更新圖表,一個用了更新表格
GetData.java
package com.data.java; import java.io.IOException; import java.lang.Thread.State; import java.sql.Connection; import java.sql.Date; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.ArrayList; import java.util.List; 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.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; @WebServlet("/GetData") public class GetData extends HttpServlet { private static final long serialVersionUID = 1L; public GetData() { super(); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //更新圖表 response.setHeader("Cache-Control", "no-cache"); request.setCharacterEncoding("utf-8"); response.setContentType("utf-8"); response.setCharacterEncoding("utf-8"); String type=request.getParameter("valu"); String ordertype=request.getParameter("order"); String updown=request.getParameter("updown"); try { Connection con =BaseConnection.getConnection("VData"); Statement stmt = con.createStatement(); Date date = new Date((System.currentTimeMillis())); JSONArray json=new JSONArray(); List<ProvinceBean> arr=new ArrayList<>(); switch(type) { case "province":{ String sql="select * from province where date=(select max(date) from province) order by convert("+ordertype+",SIGNED) "+updown; ResultSet rsst=stmt.executeQuery(sql); while(rsst.next()) { ProvinceBean pr=new ProvinceBean(); pr.setConfirm(rsst.getString("confirmm")); pr.setCured(rsst.getString("cured")); pr.setCurrent(rsst.getString("currentt")); pr.setDate(rsst.getDate("date").toString()); pr.setDead(rsst.getString("dead")); pr.setName(rsst.getString("name")); pr.setState("亞洲"); pr.setSuspect(rsst.getString("suspect")); arr.add(pr); } break; } case "city":{ String sql="select * from city where date=(select max(date) from city) order by convert("+ordertype+",SIGNED) "+updown; ResultSet rsst=stmt.executeQuery(sql); while(rsst.next()) { ProvinceBean pr=new ProvinceBean(); pr.setConfirm(rsst.getString("confirmm")); pr.setCured(rsst.getString("cured")); pr.setCurrent(rsst.getString("currentt")); pr.setDate(rsst.getDate("date").toString()); pr.setDead(rsst.getString("dead")); pr.setName(rsst.getString("name")); pr.setState(rsst.getString("province")); pr.setSuspect(rsst.getString("suspect")); arr.add(pr); } break; } case "out":{ String sql="select * from contury where date=(select max(date) from contury) order by convert("+ordertype+",SIGNED) "+updown; System.out.println(sql); ResultSet rsst=stmt.executeQuery(sql); while(rsst.next()) { ProvinceBean pr=new ProvinceBean(); pr.setConfirm(rsst.getString("confirmm")); pr.setCured(rsst.getString("cured")); pr.setCurrent(rsst.getString("currentt")); pr.setDate(rsst.getDate("date").toString()); pr.setDead(rsst.getString("dead")); pr.setName(rsst.getString("provincename")); pr.setState(rsst.getString("continents")); pr.setSuspect(rsst.getString("suspect")); arr.add(pr); } break; } } BaseConnection.close(stmt, con); //通過print將json發送到前端 json=JSONArray.parseArray(JSON.toJSONString(arr)); System.out.println(json); response.getWriter().print(json); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
ShowData.java
package com.data.java; import java.io.IOException; import java.io.PrintWriter; import java.sql.Connection; import java.sql.Date; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; 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.alibaba.fastjson.JSONObject; @WebServlet("/ShowData") public class ShowData extends HttpServlet { private static final long serialVersionUID = 1L; public ShowData() { super(); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { try { response.setHeader("Cache-Control", "no-cache"); String valu = request.getParameter("q"); String order=request.getParameter("order"); String updown=request.getParameter("updown"); System.out.println(valu); if (valu != null) { } request.setCharacterEncoding("utf-8"); response.setContentType("utf-8"); response.setCharacterEncoding("utf-8"); PrintWriter printWriter = response.getWriter(); List<String> xdata = new ArrayList<>(); List<String> data = new ArrayList<>(); List<com.alibaba.fastjson.JSONObject> seriesList = new ArrayList<com.alibaba.fastjson.JSONObject>(); Connection con=BaseConnection.getConnection("VData"); Statement stmt=con.createStatement(); Date date = new Date((System.currentTimeMillis())); System.out.println(date); System.out.println(111); //省 if (valu.equals("province")) { System.out.println("select * from province where date=(select max(date) from province) order by convert("+order+",SIGNED) "+updown); ResultSet rsst = stmt.executeQuery( "select * from province where date=(select max(date) from province) order by convert("+order+",SIGNED) "+updown); rsst.next(); rsst.next(); while (rsst.next()) { boolean flag = true; for (int i = 0; i < data.size(); i++) { if (xdata.get(i).equals(rsst.getString("name"))) { flag = false; } } if (flag) { xdata.add(rsst.getString("name")); data.add(rsst.getString(order)); } } Series series = new Series("現存確診數", "TYPE_BAR", data); com.alibaba.fastjson.JSONObject jsonObject = new com.alibaba.fastjson.JSONObject(); jsonObject.put("name", series.toName()); jsonObject.put("type", "bar"); jsonObject.put("data", series.data); seriesList.add(jsonObject); JSONObject jsonObject1 = new JSONObject(); jsonObject1.put("xAxisData", xdata); jsonObject1.put("seriesList", seriesList); // 發送給前台 printWriter.write(jsonObject1.toString()); printWriter.flush(); printWriter.close(); rsst.close(); stmt.close(); con.close(); } // 國外數據 else if (valu.equals("out")) { request.setCharacterEncoding("utf-8"); response.setContentType("utf-8"); response.setCharacterEncoding("utf-8"); System.out.println("select * from contury where date=(select max(date) from contury) order by convert("+order+",SIGNED) "+updown); ResultSet rsst = stmt.executeQuery( "select * from contury where date=(select max(date) from contury) order by convert("+order+",SIGNED) "+updown); while (rsst.next()) { boolean flag = true; for (int i = 0; i < data.size(); i++) { if (xdata.get(i).equals(rsst.getString("provincename"))) { flag = false; } } if (flag) { xdata.add(rsst.getString("provincename")); data.add(rsst.getString(order)); } } Series series = new Series("現存確診數", "TYPE_BAR", data); com.alibaba.fastjson.JSONObject jsonObject = new com.alibaba.fastjson.JSONObject(); jsonObject.put("name", series.toName()); jsonObject.put("type", "bar"); jsonObject.put("data", series.data); seriesList.add(jsonObject); JSONObject jsonObject1 = new JSONObject(); jsonObject1.put("xAxisData", xdata); jsonObject1.put("seriesList", seriesList); // 發送給前台 printWriter.write(jsonObject1.toString()); printWriter.flush(); printWriter.close(); rsst.close(); stmt.close(); con.close(); } //市 else if(valu.equals("city")){ System.out.println("select * from city where date=(select max(date) from city) order by convert("+order+",SIGNED) "+updown); ResultSet rsst = stmt.executeQuery( "select * from city where date=(select max(date) from city) order by convert("+order+",SIGNED) "+updown); rsst.next(); while (rsst.next()) { boolean flag = true; for (int i = 0; i < data.size(); i++) { if (xdata.get(i).equals(rsst.getString("name"))) { flag = false; } } if (flag) { xdata.add(rsst.getString("name")); data.add(rsst.getString(order)); } } Series series = new Series("現存確診數", "TYPE_BAR", data); com.alibaba.fastjson.JSONObject jsonObject = new com.alibaba.fastjson.JSONObject(); jsonObject.put("name", series.toName()); jsonObject.put("type", "bar"); jsonObject.put("data", series.data); seriesList.add(jsonObject); JSONObject jsonObject1 = new JSONObject(); jsonObject1.put("xAxisData", xdata); System.out.println(seriesList); jsonObject1.put("seriesList", seriesList); System.out.println((jsonObject1.get("seriesList"))); // 發送給前台 printWriter.write(jsonObject1.toString()); printWriter.flush(); printWriter.close(); rsst.close(); stmt.close(); con.close(); } } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } // request.setAttribute("data", data); // request.getRequestDispatcher("echart222.jsp").forward(request, response); } }
這個用來實現查詢
package com.data.java; import java.io.IOException; import java.sql.Connection; import java.sql.Date; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.ArrayList; import java.util.List; 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.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; @WebServlet("/Query") public class Query extends HttpServlet { private static final long serialVersionUID = 1L; public Query() { super(); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setHeader("Cache-Control", "no-cache"); request.setCharacterEncoding("utf-8"); response.setContentType("utf-8"); response.setCharacterEncoding("utf-8"); String valu = request.getParameter("valu"); String date = request.getParameter("date"); String type = request.getParameter("type"); System.out.println(valu); try { Connection con=BaseConnection.getConnection("VData"); Statement stmt=con.createStatement(); JSONArray json = new JSONArray(); List<ProvinceBean> arr = new ArrayList<>(); switch (type) { case "province": { String sql; if (!date.equals("1")) { sql = "select * from province where date='" + date + "' and name='" + valu + "'"; } else { sql = "select * from province where name='" + valu + "'"; } ResultSet rsst = stmt.executeQuery(sql); while (rsst.next()) { ProvinceBean pr = new ProvinceBean(); pr.setConfirm(rsst.getString("confirmm")); pr.setCured(rsst.getString("cured")); pr.setCurrent(rsst.getString("currentt")); pr.setDate(rsst.getDate("date").toString()); pr.setDead(rsst.getString("dead")); pr.setName(rsst.getString("name")); pr.setState("亞洲"); pr.setSuspect(rsst.getString("suspect")); arr.add(pr); } break; } case "city": { String sql; if (!date.equals("1")) { sql = "select * from city where date='" + date + "' and name='" + valu + "'"; } else { sql = "select * from city where name='" + valu + "'"; } ResultSet rsst = stmt.executeQuery(sql); while (rsst.next()) { ProvinceBean pr = new ProvinceBean(); pr.setConfirm(rsst.getString("confirmm")); pr.setCured(rsst.getString("cured")); pr.setCurrent(rsst.getString("currentt")); pr.setDate(rsst.getDate("date").toString()); pr.setDead(rsst.getString("dead")); pr.setName(rsst.getString("name")); pr.setState(rsst.getString("province")); pr.setSuspect(rsst.getString("suspect")); arr.add(pr); } rsst.close(); break; } case "contury": { String sql; if (!date.equals("1")) { sql = "select * from contury where date='" + date + "' and provincename='" + valu + "'"; } else { sql = "select * from contury where provincename='" + valu + "'"; } ResultSet rsst = stmt.executeQuery(sql); while (rsst.next()) { ProvinceBean pr = new ProvinceBean(); pr.setConfirm(rsst.getString("confirmm")); pr.setCured(rsst.getString("cured")); pr.setCurrent(rsst.getString("currentt")); pr.setDate(rsst.getDate("date").toString()); pr.setDead(rsst.getString("dead")); pr.setName(rsst.getString("provincename")); pr.setState(rsst.getString("continents")); pr.setSuspect(rsst.getString("suspect")); arr.add(pr); } rsst.close(); break; } case "date": { if (valu.equals("out")) { valu = "contury"; } String sql = "select * from " + valu + " where date='" + date + "'"; ResultSet rsst = stmt.executeQuery(sql); while (rsst.next()) { ProvinceBean pr = new ProvinceBean(); pr.setConfirm(rsst.getString("confirmm")); pr.setCured(rsst.getString("cured")); pr.setCurrent(rsst.getString("currentt")); pr.setDate(rsst.getDate("date").toString()); pr.setDead(rsst.getString("dead")); pr.setName(rsst.getString("provincename")); pr.setState(rsst.getString("continents")); pr.setSuspect(rsst.getString("suspect")); arr.add(pr); } rsst.close(); break; } } stmt.close(); con.close(); // 通過print將json發送到前端 json = JSONArray.parseArray(JSON.toJSONString(arr)); System.out.println(json); response.getWriter().print(json); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
,