数据可视化 三步走(三):thymeleaf + echarts 完成数据可视化

#前言

     春节小长假休的比较舒服,第一天上班,继续年前未完成的内容。
     本章节完成最后一点:利用thymeleaf模板引擎 和echarts完成数据可视化。

为什么使用thymeleaf和echarts?

     1.thymeleaf是基于html的,可以先进行原型设计,即设计静态的html,然后嵌入thymeleaf标签,即使页面渲染不成功,也是标准的html页面,可读性较好,而且独立于java容器,你可以认为它就是一个标准的html页面。
    2.echarts作为百度不可多得的开源框架,这里不做详细介绍,类似于highcharts等图表展示工具,非常强大。因为我没用过,所以要尝试一下。

1.html原型设计

    1.我这里用的是bootstrap,so 去中文网找个原型吧(能自己写原型固然很牛逼,但不建议,写出来也不一定比人家的好看,不要浪费时间)。

https://v4.bootcss.com/docs/4.0/examples/

    我找了个轮播的示例,直接copy html代码到项目中的index.html中,然后自己改了改

这里写图片描述

     此时不要着急实现页面渲染部分的内容,目前只是一个静态的html,然后启动springboot,测试下index.html的样式 css js等是否加载成功,如报错或者跟样例展示效果有出入,请自行修改。

至此,我们的原型设计就完成了。


2.页面动态渲染,实现数据可视化

    1.首先要解决的就是前端组装echarts,还是后端组装,我们用后端组装,更灵活。那么问题来了,需要将echarts的所有属性抽象封装成model,我在网上找了个大神写的echarts-java映射类库:https://gitee.com/free/ECharts,把源码下载下来导入项目。

这里写图片描述
这个类库中用到了lombok减少代码冗余,其实就是不用自己写getter setter方法,只用注解就可以。参考:
http://blog.csdn.net/zhglance/article/details/54931430

    2. 此时我试了一下,还遇到一个问题,对象映射成json时,很多null属性也被映射成json了,这样会导致echarts的某些重要属性遭到null覆盖掉,使得echarts加载报错,所以这里就直接上解决方案:过滤掉json中的null和空字段。写一个配置类如下:
package com.cnepay.config;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializerProvider;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;

import java.io.IOException;

/**
 * Created by wxq on 2018/2/2.
 */
@Configuration
public class JacksonConfig {
    @Bean
    @Primary
    @ConditionalOnMissingBean(ObjectMapper.class)
    public ObjectMapper jacksonObjectMapper(Jackson2ObjectMapperBuilder builder) {
        ObjectMapper objectMapper = builder.createXmlMapper(false).build();

        // 通过该方法对mapper对象进行设置,所有序列化的对象都将按改规则进行系列化
        // Include.Include.ALWAYS 默认
        // Include.NON_DEFAULT 属性为默认值不序列化
        // Include.NON_EMPTY 属性为 空("") 或者为 NULL 都不序列化,则返回的json是没有这个字段的。这样对移动端会更省流量
        // Include.NON_NULL 属性为NULL 不序列化
        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);

        // 字段保留,将null值转为""
        objectMapper.getSerializerProvider().setNullValueSerializer(new JsonSerializer<Object>() {
            @Override
            public void serialize(Object o, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException, JsonProcessingException {
                jsonGenerator.writeString("");
            }
        });
        return objectMapper;
    }
}

    通过以上配置,springboot在将对象转换成json的时候就会过滤掉null和空字段
    3.选择一个维度进行数据可视化,简单点,统计电影评价人数
     后端代码,拼装Option,对echarts不熟悉的先去官网研究:
 /*
    * 获取柱状图 json数据
    * */
    public Option getEchartsOption()
    {
        List<Movie> list = movieMapper.selectMapList();
        //echarts option 对象
        Option option = new Option();
        option.title("电影评价人数统计").tooltip(Trigger.axis).legend("评价人数");
        //x轴为值轴
        option.xAxis(new ValueAxis().boundaryGap(0d, 0.01));

        //y轴为类目轴
        CategoryAxis category = new CategoryAxis();
        //柱状数据
        Bar bar = new Bar("评价人数");
        //循环数据
        for (Movie m : list) {
            //设置类目
            category.data(m.getTitle());
            //类目对应的柱状图
            bar.data(m.getEvalNum());
        }

        Grid grid = new Grid();
        grid.setLeft(200);
        option.setGrid(grid);
        option.yAxis(category);
        option.series(bar);

        return option;
    }
     前端代码:

这里写图片描述

    参考echarts官方文档:http://echarts.baidu.com/option.html#title:
    4.最终效果

这里写图片描述

    5.上映年份维度统计(又做了一个饼状图的统计),附上后台代码:
/*
    * 获取饼状图 json数据
    * */
    public Option getEchartsPieOption()
    {
        List<Movie> list = movieMapper.selectAllMapList();
        Option option = new Option();
        //标题
        Title title = new Title();
        title.setText("豆瓣电影上映年份");
        title.setSubtext("来源豆瓣");
        title.setX("center");
        option.setTitle(title);

        //提示框
        Tooltip tooltip = new Tooltip();
        tooltip.setTrigger(Trigger.item);
        tooltip.formatter("{a} <br/>{b} : {c} ({d}%)");
        option.setTooltip(tooltip);

        //Legend
        Legend legend = new Legend();
        List<String> legendDataList = Arrays.asList("90年代", "00年代", "10年代","其他");
        legend.setOrient(Orient.vertical);
        legend.setLeft("left");
        legend.setData(legendDataList);
        option.setLegend(legend);

        //饼状图
        Pie pie = new Pie();
        //对数据进行简单处理
        int y90 =0;
        int y00 =0;
        int y10 =0;
        int yElse =0;
        for (Movie movie : list) {
            if(movie.getmYear().startsWith("199")){
                y90++;
            }
            else if (movie.getmYear().startsWith("200")){
                y00++;
            }
            else if (movie.getmYear().startsWith("201")){
                y10++;
            }
            else{
                yElse++;
            }
        }
        Map<String,String> dataMap90 = new HashMap<>();
        dataMap90.put("name","90年代");
        dataMap90.put("value",String.valueOf(y90));
        Map<String,String> dataMap00 = new HashMap<>();
        dataMap00.put("name","00年代");
        dataMap00.put("value",String.valueOf(y00));
        Map<String,String> dataMap10 = new HashMap<>();
        dataMap10.put("name","10年代");
        dataMap10.put("value",String.valueOf(y10));
        Map<String,String> dataMapElse = new HashMap<>();
        dataMapElse.put("name","其他");
        dataMapElse.put("value",String.valueOf(yElse));
        //封装pie
        pie.data(dataMap90, dataMap00, dataMap10, dataMapElse);
        pie.setName("上映年代");
        pie.setRadius("55%");
        String [] centerArray = {"50%","60%"};
        pie.setCenter(centerArray);

        option.series(pie);

        return option;
    }
     效果:

这里写图片描述

至此,我们完成了两个维度的数据可视化。
`


总结:

     原始数据来自豆瓣网,使用python的scrapy框架爬取数据、并且进行数据的存储。在此基础上,使用Springboot + thymeleaf + Echarts进行简单的数据可视化。从而完整的展示网络数据采集、存储、处理和使用四个环节所涉及的技术链。
评论 15
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值