原生ajax+ECharts

原生ajax+ECharts

主要架构思想

  • 在项目中,ajax主要实现一部分的数据更新,实现更新的话则需要使用到servlet,如果有多个ajax需要查不同的表,那么会需要多个servlet,实现起来会比较多冗。所以我们需要定义一个接口,来减少servlet与数据库的交互。

项目示例

  • 我们有一个项目,需要使用到ECharts实现简单的各类图表的展示,我们实现起来主要的难点就在于:不同图表所需要的数据格式,比如柱状图和折线图等,需要两组数据,对应横坐标的参数和主要数据;但是饼状图不同它需要的则是类似于Json类数据的格式,所以不同的表类型不同导致所需要的数据也不相同。

  • 接下来我们实现连接数据库的接口:

    public interface SqlTableDao {
        /*
        * 我们这里只实现一个查询的功能,所以只有一个findall方法
        * */
        public <T> String findall(Class<T> tclass);
    }
    

    面对请求的多样化,我们可以创建不同的接口实现类来接受查询不同的数据,但是在之前我们需要创建一个pojo类来进行封装:

    比如我们创建了一个bardata表来封装创建柱状图需要的对象

    public class Bardata {
        private int data;//对应实际数据
        private String x_name;//对应x轴坐标
    
        public Bardata(int data, String x_name) {
            this.data = data;
            this.x_name = x_name;
        }
    
        public Bardata() {
        }
    
        public int getData() {
            return data;
        }
    
        public void setData(int data) {
            this.data = data;
        }
    
        public String getX_name() {
            return x_name;
        }
    
        public void setX_name(String x_name) {
            this.x_name = x_name;
        }
    
        @Override
        public String toString() {
            return "Bardata{" +
                    "data=" + data +
                    ", x_name='" + x_name + '\'' +
                    '}';
        }
    }
    

    那么封装类有了,我们就需要去实现接口。

    import java.lang.reflect.Constructor;
    import java.lang.reflect.InvocationTargetException;
    import java.sql.*;
    import java.util.ArrayList;
    
    /**
     * @author Sleep
     * @Create 2022/11/12 10:40
     */
    public class BarDao implements SqlTableDao{
    
        @Override
        public <T> String findall(Class<T> tclass) {
            //获取数据库连接
            try {
                Connection connection = DriverManager.getConnection("your url","your username","your password");
                //通过反射获取对象的构造方法
                Constructor<T> constructor = tclass.getConstructor(Integer.class, String.class);
                //查询数据库
                String sql = "****";
                //预处理
                PreparedStatement prep = connection.prepareStatement(sql);
                //覆盖占位符的覆盖
                /*只查询有效数据
                *prst.setDouble(1, sal);
                *prst.setInt(2, empno);
                * */
                //执行查询语句
                ResultSet set = prep.executeQuery();
                //创建容器封装
                ArrayList<T> list = new ArrayList<>();
                //遍历set集合
                while (set.next()){
                    //获取其中的参数
                    int data = set.getInt("data");
                    String x_name = set.getString("x_data");
                    //利用之前的反射获取的构造方法,获得对象
                    T t = (T) constructor.newInstance(data,x_name);
                    //添加进入集合
                    list.add(t);
                }
                //利用Gson工具类返回已经封装好的json字符串
                return GsonUtils.getJson(list);
    
            } catch (SQLException e) {
                throw new RuntimeException(e);
            } catch (InstantiationException e) {
                throw new RuntimeException(e);
            } catch (IllegalAccessException e) {
                throw new RuntimeException(e);
            } catch (NoSuchMethodException e) {
                throw new RuntimeException(e);
            } catch (InvocationTargetException e) {
                throw new RuntimeException(e);
            }
    
        }
    }
    

    我们就可以传入pojo类的class对象来实现查询柱状图需要的数据,我们创建一个servlet,来获取请求。

    public class Barservlet extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            doPost(req, resp);
        }
    
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            /*
            * 设置请求和响应的编码格式,以及响应写入数据的格式
            * 这一部分也可以使用Filter过滤器来写
            * */
            req.setCharacterEncoding("UTF-8");
            resp.setCharacterEncoding("UTF-8");
            //由于前后端的交互使用的是json数据格式的传输,所以我们使用起来也需要来规定格式
            resp.setContentType("json/application;charset=utf-8");
            //我们可以根据url来获取到额外的字段,得到想要请求的具体数据,可以是数据库中的表名
            String database = req.getParameter("database");
            //获取传输返回值
            String json = "";
            //对字段名进行判断,对应不同的pojo类的class对象,并调用方法接受
            if (database.equals("bar")){
                //我们调用服务层的ChartSqlFind类中的getchartdata来实现service层与dao层的分离
                json = ChartSqlFind.getchartdata(new BarDao(),Bardata.class);
            }/*else if (database.equals("pie")){
                ....
            }else {
                //else这一部分都是防止意外情况,比如传输的数据出错
                ...
            }*/
    
            //使用响应写回数据
            resp.getWriter().print(json);
    
        }
    }
    

    除此之外我们还需要去web.xml中去注册Servlet

      <servlet>
        <servlet-name>Barservlet</servlet-name>
        <servlet-class>cn.sleep.servlets.Barservlet</servlet-class>
      </servlet>
      <servlet-mapping>
        <servlet-name>Barservlet</servlet-name>
        <url-pattern>/barchart</url-pattern>
      </servlet-mapping>
    

在上述代码中我们为了实现Dao层与Service层的分离,定义了一个服务类,来间接调用Dao层方法:

public class ChartSqlFind {
   /* 我们定义一个静态方法,调用SqlTableDao的实现方法
   * 这样可以将Dao层的功能分离出来
   * */
    public static <T> String getchartdata(SqlTableDao sql, Class<T> tClass){
        return sql.findall(tClass);
    }
}

那么接下来要做的事情就是需要为jsp写入数据和处理数据:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
    <!--一般写jsp页面时我们需要创建一个文件夹来存放静态文件,比如css、js、img等-->
    <script src="static/js/echarts.js"></script>
</head>
<body>
    <button onclick="ons()">显示图形</button>
    <!--创建一个容纳图片的容器-->
    <div id="main" style="width: 1000px;height:800px;"></div>
<script type="text/javascript">

    function ons(){
        //1、我们首先要创建 XMLHttpRequest
        var xmlhttprequest = new XMLHttpRequest();
        //2、调用 open 方法设置请求参数
        xmlhttprequest.open("POST","/WebMod_war/barchart",true);
        /*
        * 关于open的参数,
        * 第一个参数为请求的方式:GET、POST
        * 第二个参数为:跳转的路径,一般来说是 项目配置路径+注册的servlet的url
        * open方法一共有5个参数
        * 其余参数为可选的
        * */
        //3、在 send 方法前绑定 onreadystatechange 事件,处理请求完成后的操作。
        xmlhttprequest.onreadystatechange = function() {
            //4、判断请求状态码来判断是否执行
            if (xmlhttprequest.readyState == 4 && xmlhttprequest.status == 200){
                //5、获取后端response返回的Json数据,并使用内置的JSON模块格式化
                var Json = JSON.parse(xmlhttprequest.responseText);
                //6、创建数组遍历接受数据
                /*
                * 不同的图表的对应的数据处理也不同,
                * 比如bar柱状图需要两组数据,分别对应横坐标和具体的数据,
                * 或者pie饼状图则需要一组json数据来直接使用
                * */
                var data = [];
                var x_name = [];
                //7、遍历Json数组
                for(var o in Json){
                    //push函数尾部添加
                    data.push(Json[o].data);
                    x_name.push(Json[o].x_name);
                }
            }
       
            }
             xmlhttprequest.send();
            //8、遍历完数组,调用图表显示函数
            //需要设置一个请求完的执行函数
            xmlhttprequest.onloadend = function (){
           		showChart(data,x_name);
        }
    }
    //获取函数参数
    function showChart(data,x_name){
        //1、获取图表容器,封装为对象
        var myChart = echarts.init(document.getElementById('main'));
        //2、指定图表的配置项和数据
        //在使用ECharts渲染date时,需要3-4s,我们需要提升用户感知
        myChart.showLoading({text:'正在加载数据'})
            var option = {
                xAxis: {
                    type: 'category',
                    //传入特定的参数,通过参数传入
                    data: data
                },
                yAxis: {
                    type: 'value'
                },
                series: [
                    {
                        //传入特定的参数,通过参数传入
                        data: x_name,
                        type: 'bar',
                        showBackground: true,
                        backgroundStyle: {
                            color: 'rgba(180, 180, 180, 0.2)'
                        }
                    }
                ]
            };
        //
        myChart.hideLoading();//将提示关闭
        // 使用刚指定的配置项和数据显示图表。
        myChart.setOption(option);

    }

</script>
</body>
</html>

上述代码是bar柱状图,pie的饼状图需要使用的数据格式也不一样:

在ECharts官方文档里,饼状图数据需要的是json类型的格式的,所以我们可以直接传入

 function ons(){
		//由于Json的数据处理函数需要在函数体内部,所以我们需要定义变量来接收
		var datamod=[];  
        // 1 、我们首先要创建 XMLHttpRequest
        var xmlhttprequest = new XMLHttpRequest();
        // 2 、调用 open 方法设置请求参数
        xmlhttprequest.open("POST","/WebMod_war/ajex",true);
        // 3 、在 send 方法前绑定 onreadystatechange 事件,处理请求完成后的操作。
        xmlhttprequest.onreadystatechange = function() {
            if (xmlhttprequest.readyState == 4 && xmlhttprequest.status == 200) {
				 var jsonObj = JSON.parse(xmlhttprequest.responseText);
                datamod=jsonObj;
                
            }
        }
        xmlhttprequest.send();
        //需要设置一个请求完的执行函数
        xmlhttprequest.onloadend = function (){
           		ens(datamod)
            }
    }
  // 基于准备好的dom,初始化echarts实例
  function ens(datamod){
      var myChart = echarts.init(document.getElementById('main'));
      myChart.showLoading();
      //alert(typeof(datas));
      // 指定图表的配置项和数据
      var option = {
          legend: {
              top: 'bottom'
          },
          toolbox: {
              show: true,
              feature: {
                  mark: { show: true },
                  dataView: { show: true, readOnly: false },
                  restore: { show: true },
                  saveAsImage: { show: true }
              }
          },
          series: [
              {
                  name: 'Nightingale Chart',
                  type: 'pie',
                  radius: [50, 250],
                  center: ['50%', '50%'],
                  roseType: 'area',
                  itemStyle: {
                      borderRadius: 20
                  },
                  data:datamod
              }
          ]
      };
      myChart.hideLoading();
      // 使用刚指定的配置项和数据显示图表。
      myChart.setOption(option);
  }

更多的图表数据可以查看官方的文档Examples - Apache ECharts

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值