美文网首页前端技术vueVue
vue全家桶+Echarts+百度地图,搭建数据可视化系统

vue全家桶+Echarts+百度地图,搭建数据可视化系统

作者: xrkffgg | 来源:发表于2019-04-25 19:54 被阅读0次

    本文章篇幅略长,内容有点多
    大佬可根据目录选择性查阅
    新人可一步步来阅读

    1 前言

    1.1 业务场景

    突然接到产品说要做一个数据监控的系统。有线图、柱状图、地图,类似于数据可视化的方式。

    本人之前从未接触过Echarts,然后需要2周拿出成果,有点慌😂😂

    1.2 业务分析

    拿到需求看了一下

    支持用户名、密码登录,默认显示一个维度数据,然后点击可钻取进入第二维度数据,再点击进入第三维度数据展示。

    大致估摸着。。。

    1. 系统搭建vue-cli
    2. vuex记录登录信息
    3. vue-router路由跳转
    4. 3个维度的页面,提取出共用的组件
    5. 各个组件开发
    6. 调节样式,增加UI
    7. 加入后台接口数据
    8. 优化显示
    9. 测试
    10. 上线

    当然这不是要2周内,全做完。应该是完成步骤6。

    相对于公司就我一个前端,没接触过Echarts,有问题都没人讨论的情况下。。。

    心里还是忍不住想吐槽一下😒😒😒

    1.3 效果展示

    这里列出了第一维度页面的样式。文字请无视,哈哈。

    image

    2 系统安装

    吐槽归吐槽,活还是要干的。😎

    因为本人最熟悉的还是vue,所以还是选择了用vue全家桶来做。这部分可参考 vue build

    2.1 安装node环境

    • 下载安装node环境,直接去官网下载即可 node.js

    安装完后可在命令行运行node -v npm -v 查看是否安装成功以及版本

    2.2 安装Vue项目

    2.2.1 安装vue

    官方文档:vuejs

    这里我们使用npm的方式

    • npm i vue

    2.2.2 安装Vue CLI

    官方文档:vue CLI

    • npm i -g @vue/cli

    安装之后,你就可以在命令行中访问 vue 命令。你可以用这个命令来查看其版本。vue -V

    2.2.3 创建项目

    这里安装的时候,注意将我们要使用的安装上。vuexvue-router,其他可根据需要添加。

    1. 方法一
    • vue create hello-world

    这里参照官方网站,有很详细的介绍。参照:vue create

    1. 方法二

    使用图形化界面

    • vue ui

    界面含中文,很好操作。参照:vue ui

    2.2.4 安装插件

    1. 方法一

    最直接也是推荐的 npm i xxx

    这里介绍一下 -S -D -g 的区别

    • npm i -S xxx 文件写入dependencies,用于工程中开发时使用到的插件,会发布到生产环境如UI,JS等。
    • npm i -D xxx 文件写入devDependencies,用于工程支持类插件,不会发布到生产环境,如gulp等压缩打包工具。
    • npm i -g xxx 全局安装,如vue、ncu等。安装目录为:C:\Users\用户\AppData\Roaming\npm
    1. 方法二

    vue ui图像化界面中包含了若干插件,可点击安装,但不一定是最新版本。

    同时会在hello中引入。其他和方法一没区别。

    2.3 安装Echarts

    这里我们为了方便,使用了npm全量引用,后期为了精简项目可单个引用。

    • npm i echarts -S

    然后在main.js中添加

    image

    这里建议提前自定义echarts的样式,并引入到项目中。官方自定义地址:theme-builder

    在页面中我们可以如下引用:
    var myChart = this.$echarts.init(document.getElementById("myid"),'temp')

    myid是我们要展示的echartsid

    temp是我们的自定义的样式,同时官方提供了几个样式例子,可以node_modules\echarts\theme中找到。

    2.4 安装element-ui

    这里我们为了方便,使用了npm全量引用,后期为了精简项目可单个引用。

    • npm i element-ui -S

    然后在main.js中添加

    image

    2.5 安装百度地图

    一般vue使用百度地图有2种方式,

    • 一种是像官网那样去应用。如:BMap

    • 第二种是使用 vue-baidu-map

    不管是哪一种都要去申请账号和密钥。申请地址为:百度地图密钥(ak)

    这里我使用了第二种。vue-baidu-map文档

    • npm i vue-baidu-map -S

    然后在main.js中添加

    image

    xxxxxxxx这里填写自己申请的密钥。

    在页面中,参照文档,可使用标签<baidu-map/>来调用。

    2.6 初始化样式

    css样式初始化,简单来说就是为了各个浏览器能统一什么的。

    这里我使用的是 normalize.css

    下载下来后,在main.js中添加

    image

    基本上的准备工作都做好了,接下来就是具体的代码了。

    3 项目搭建

    3.1 router、vuex

    我这里新建了一个router.jsstore.js,大致如下:

    image

    哦哈,这里路由定义是为了方便看哈,具体还是根据业务来定义。

    这里的router.beforeEach 路由卫士用于是否登录校验。

    然后我们在main.js中来引用。

    image

    更多请参考官方文档:Vue Router Vuex

    3.2 Login页面

    登录页面没啥,就是个form提交,由于路由中判断user.id。所以我们储存一下,然后跳转到Index页面就行。

    这里只是一种方式,也可以使用CookieSession

    3.3 Index页面

    分析页面分成了2个大部分

    • 第一部分是 头部
    • 第二部门是 主体
    image

    我们将头部当做一个组件进行复用。

    组件的复用可参考官方文档:https://cn.vuejs.org/v2/guide/components.html

    3.4 header页面

    头部比较简单,除了一些显示外,还有一个显示当前时间。

    这里我们使用了setInterval,每隔1秒去获取一下当前时间赋值给你定义的v-model就行。

    同时在离开页面时,我们清理掉定时器。

    这里需要我们对Vue生命周期有一定的了解。

    获取当前时间的方法可参考:data-module.js

    3.5 主体页面

    这里分析一下页面,主要分成了3块。

    1. 左边,包含了2个折线图。
    2. 中间,包含了数字和地图。
    3. 右边,包含了柱状图和表格。

    接下来主要介绍一下,自己这2周摸索出来的一些Echarts配置,适合新手,大佬轻喷。

    这里需要经常翻阅 Echarts配置项API

    3.5.1 Echarts基本

    这里列出基本的渲染写法,具体的图形和数据只要修改option就可以了。

    <template>
        <div id="myecharts" class="myecharts">
    </template>
    
    <script>
        export default {
            mounted(){
                this.drawECharts()
            },
            
            methods:{
                drawECharts(){
                    // temp 是我们的自定义样式,上面安装Echarts时有介绍
                    var myChart = this.$echarts.init(document.getElementById("myecharts"),'temp')
                    var option = {}
                    option = {
                        // 吧啦吧啦 一堆配置
                    }
                    // 执行渲染图形和数据的操作
                    if (option && typeof option === "object") {
                        myChart.setOption(option, true)
                    }
                }
            }
        }
    </script>
    
    <style>
        //  一定要设置大小,不然不出来,这玩意和canvas一样
        .myecharts{
            width : 500px;
            height : 300px;
        }
    </style>
    

    3.5.2 线形图

    多多实践,就会发现每个配置和其参数的作用了。

    option = {
        // 提示框(就是鼠标放上去后出现的框)
        tooltip : {
            trigger: 'axis',
            axisPointer: {
                type: 'cross',
                label: {
                    backgroundColor: '#6a7985'
                }
            }
        },
        
        //  右上角的组件,用于说明,也可进行点击筛选
        legend: {
            align : 'right',
            x : 'right',
            top : 25,
            selectedMode : 'single',    //  我这里设置的单选模式
            data:['好','坏']            //  显示的第一项和第二项,这里的颜色是根据自定义主题的颜色顺序来定的
        },
        
        //  x、y轴显示一些设置,比如刻度颜色显示什么的,可在自定义主题设置一部分
        xAxis: {
            type: 'category',
            boundaryGap: false,
            data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
        },
        yAxis: {
            type: 'value'
        },
        // 具体配置项,根据具体项目查看官网配置项说明
        series: [
            {
                name : '好',
                data: [150, 132, 201, 534, 290, 530, 820],
                type: 'line',
                smooth: true,   //  是否平滑曲线
                areaStyle: {},
            },
            { 
                name : '坏',
                data: [82, 93, 90, 93, 129, 333, 432],
                type: 'line',
                smooth: true,
                areaStyle: {},
            }
        ]
    }
    
    // 查看Echarts的API,我们需要显示默认的一些数据,配置如下
    // 默认显示坏的数据
    myChart.dispatchAction({
        type: 'legendSelect',
        name: '坏',
    })
    //  默认显示第7个数据
    myChart.dispatchAction({
        type: 'showTip',
        seriesIndex: 1,
        dataIndex: 6,
    })
    

    预览:

    image

    3.5.3 柱状图

    这里我们直接用双柱状图来演示。

    因为名字和数字需要提示和点击的功能,所以没有使用echartsy轴。

    不然formatter又要写一堆,虽然用了自定义的,但最开始是用的formatter

    可以实现相同展示,但无法操作,如鼠标提示和鼠标点击。

    <div class="left">
        <div v-for="it in its1" :key="it.id">
            <el-tooltip class="item"  effect="light" placement="bottom-start">
                <div slot="content">名称:{{it.name}}<br/>个数:{{it.num}}</div>
                <div class="name" @click="go"> {{ it.name.substring(0,4)+'...' }}</div>
            </el-tooltip>
            <div class="num">{{ it.num }}</div>
        </div>
    </div>
    
    <div class="right">
        <div v-for="it in its2" :key="it.id">
            <el-tooltip class="item"  effect="light" placement="bottom-start">
                <div slot="content">名称:{{it.name}}<br/>个数:{{it.num}}</div>
                <div class="name" @click="go"> {{ it.name.substring(0,4)+'...' }}</div>
            </el-tooltip>
            <div class="num">{{ it.num }}</div>
        </div>
    </div>
    
    <div id="myecharts" class="myecharts">
    

    css这里就不贴了,效果就是这2行文字刚好贴在2行柱状图前面。

    接下来是echarts配置。

    option = {
        // 鼠标提示框
        tooltip: {
            trigger: 'axis',
            axisPointer: {
                type: 'shadow'
            }
        },
        
        // 右边显示
        legend: {
            selectedMode:false,
            data: ['好', '坏'],
            top:5,
            right:8,
        },
        
        // 两个图坐标的位置
        grid: [
            {left: '16%', top:'10%', width: '22%', height: '86%'},
            {left: '65%', top:'10%', width: '22%', height: '86%'}
        ],
        
        // 两个图x轴的设置,这里的gridIndex就是个序号,用于区分
        xAxis: [
            {gridIndex : 0, show : false},
            {gridIndex : 1, show : false},
        ],
        
        // 两个图y轴的设置,注释的部分是用echarts本身的y轴来显示名称和数量的
        yAxis: [
            {
                gridIndex: 0,
                type: 'category',
                show : false,
                data : ['广东/12','杭州/13','北京北京/14','天津/16'],
                // axisLabel: {
                //   formatter : function(value){
                //     let arr = value.split('/')
                //     return '{a|'+arr[0]+'}\n{b|'+ arr[1]+'}';
                //   },
                //   rich: {
                //     a: {
                //       color : '#ffffff',
                //       lineHeight : 19,
                //       fontSize : 14,
                //       align: 'right',
                //     },
                //     b:{
                //       fontSize : 18,
                //       lineHeight : 19,
                //       fontWeight : 'bold',
                //       align: 'right',
                //       fontFamily : 'Digital',
                //     }
                //   }
                // }
            },
            {
                gridIndex: 1,
                show : false,
                type: 'category',
                data : ['海南/12','三亚/13','哈尔滨/14','西双版纳/16'],
                // axisLabel: {
                //   formatter : function(value){
                //     let arr = value.split('/')
                //     return '{a|'+arr[0]+'}\n{b|'+ arr[1]+'}';
                //   },
                //   rich: {
                //     a: {
                //       color : '#ffffff',
                //       lineHeight : 19,
                //       fontSize : 14,
                //       align: 'right',
                //     },
                //     b:{
                //       fontSize : 18,
                //       lineHeight : 19,
                //       fontWeight : 'bold',
                //       align: 'right',
                //       fontFamily : 'Digital',
                //     }
                //   }
                // }
            },
        ],
        
        //  渲染图形和数据,bar是柱状图
        //  barWidth 柱状的宽度
        //  两类两套,所以有4组数据,使用xAxisIndex、yAxisIndex来区分。
        series: [
            {
                name: '好',
                type: 'bar',
                barWidth  : 5,
                barMinHeight : 5,
                barGap : '100%',
                xAxisIndex: 0,
                yAxisIndex: 0,
                data: [0, 3489, 9022234, 922228],
                label: {
                    normal: {
                        position: 'right',
                        show: true
                    }
                },
            },
            
            {
                name: '坏',
                type: 'bar',
                barWidth  : 5,
                barMinHeight : 5,
                xAxisIndex: 0,
                yAxisIndex: 0,
                data: [0, 2438, 3300, 1594],
                label: {
                    normal: {
                        position: 'right',
                        show: true
                    }
                 },
            },
            {
                name: '好',
                type: 'bar',
                barWidth  : 5,
                barMinHeight : 10,
                barGap : '100%',
                xAxisIndex: 1,
                yAxisIndex: 1,
                data: [8203, 3489, 9034, 222],
                label: {
                    normal: {
                        position: 'right',
                        show: true
                    }
                },
            },
            {
                name: '坏',
                type: 'bar',
                barWidth  : 5,
                barMinHeight : 5,
                xAxisIndex: 1,
                yAxisIndex: 1,
                data: [445, 2438, 3300, 555],
                label: {
                    normal: {
                        position: 'right',
                        show: true
                    }
                },
            },
        ]
    }
    

    预览:

    image

    3.5.4 表格

    table我这里使用了element-ui加上修改 UI 默认css 和 滚动条的 css

    这里列出一项,其他写法相似。

    <el-table
        :data="tableData"
        height="252"
        style="min-width: 100%;">
        <el-table-column
            prop="date"
            min-width="12"
            header-align="center"
            label="时间">
            <template slot-scope="scope">
                <template v-if="scope.row.if == '1'">
                    <img src="../../assets/img/new.png"/>
                    <div style="color:#E63136;margin-top:-27px;margin-left:35px;">
                        {{scope.row.date}}
                    </div>
                </template>
                <template v-else>
                    <div style="margin-left:35px;">
                        {{ scope.row.date }}
                    </div>
                </template>
            </template>
        </el-table-column>
    </el-table>
    
    • UI 样式

    UI css的修改,这里我使用了自定义字体哦,完全copy是不起作用的。

    其他的设置项不做说明,F12打开,随便玩。

    .el-table thead {
        color: #FFFFFF;
    }
    
    .el-table {
        color: #00A5F6;
        font-family: 'Regular';
        background-color: rgba(0, 0, 0, 0.03);
        th {
            padding: 2px 0;
            background-color: #003260; 
        }
        th.is-leaf {
            border-bottom: 0px solid #EBEEF5;
        }
        tr {
            background-color: rgba(0, 0, 0, 0.03);
        }
        td {
            border-bottom: 1px solid #2c3547;
            padding: 2px 0;
        }
        
        .el-table::before {
            height: 0px;
            z-index: 0;
            background-color: #2c3547;
        }
    }
    
    • 滚动条的样式

    随意改变看看效果就懂了,谷歌浏览器 😅

    /* scrollbar */
    
    ::-webkit-scrollbar {
      width: 8px;
      height: 1px;
      background-color:transparent;
    }
    ::-webkit-scrollbar-thumb {
      border-radius: 10px;
      background: #adabab;
    }
    ::-webkit-scrollbar-track {
      border-radius: 10px;
      background:#394d63;
    }
    

    预览:

    image

    3.5.5 百度地图

    vue-baidu-map 文档

    <baidu-map 
        :center="map.center"        //  地图中心经纬 {lng: 114.023598, lat: 33.589299}
        :scroll-wheel-zoom="true"   //  地图是否滚轮缩放
        :zoom="map.zoom"            //  默认地图尺寸
        :mapStyle="mapStyle"        //  地图样式
        class="baidumap">           //  地图宽高
        <template v-for="(it,index) in ms">     //  标点
            <bm-marker 
                :key="it.id" 
                :position="it.position"         //  标点位置
                @click="markclick(it,index)"    //  标点点击事件
                @mouseover="markover(it,index)" //  鼠标移动到标点上的事件
                :icon="it.if? iocn:newincon"    //  标点的样式
                @mouseout="markout(it,index)">  //  鼠标从标点移走的事件
                <bm-info-window
                    :show="it.show"             //  标点提示框的显示true/false
                    :position="it.position">    //  提示框坐标
                    <p v-text="it.mess"></p>    //  提示框内容
                </bm-info-window>
            </bm-marker>
        </template>
    </baidu-map>
    

    预览:


    image

    3.5.6 矢量地图

    Echarts矢量地图的类型有

    • type:'scatter' 散点气泡图,可在地图中显示不用颜色程度的点
    • type:'effectScatter' 有涟漪特效动画的散点图
    • type:'map' 地理区域的数据可视化
    • type:'lines' 地图航线、路线的可视化

    引入地图

    require('echarts/map/js/china.js')
    require('echarts/map/js/province/beijing.js')
    

    这里我有问题,我要引入全国的省份,就要多写30多个require,有没有大佬能给出更好的办法?

    地图配置:

    option = {
        //  鼠标提示
        tooltip : {
            trigger: 'item',
            formatter : function(params){
                var val = params.data
                return '名称:'+val.name+',个数:'+val.value[2]+'<br/>'+'总数:'+val.tol+',个数:'+val.un
            },
        },
        
        //  不同颜色的点
        visualMap: [
            {
                min: 0,
                max: 1,
                show : false,
                inRange: {
                    color: ['#01cae2', '#e63136',]
                },
                dimension : 3,
            },
        ],
    
        // 地图样式
        geo: {
            map: 'china',   // 地图样式,当为‘北京’时,会显示北京地图   
            roam : true,    
            label: {
                emphasis: {
                    show: true
                }
            },
            zoom : 1.2,     //  初始大小
            scaleLimit : {
                min : 1.2,  //  最小缩放
                max : 6     //  最大缩放
            },
            regions : regions(data)     // 省份样式方法
        },
    
        series : [
            {
                name: '分布',
                type: 'scatter',
                coordinateSystem: 'geo',    //  地图配置
                data: convertData(data.sort(function (a, b) {   //  数据方法
                    return b.value - a.value;
                })),
                encode: {
                    value : 2
                },
                hoverAnimation: true,
                itemStyle: {
                    normal: {
                        // color: '#FF3030',
                        shadowBlur: 1,
                    }
                },
            }
        ]
    };
    

    当点击省份地图时,我们可以进入省份地图的矢量图

    myChart.on('click',function(params){
        option.geo.map =  '北京'
        myChart.setOption(option, true);
    })
    

    预览:

    image
    image

    4 后记

    目前还没有接入后端数据,就是全前台的一个展示。很多都是全量引入,后续待成熟后,可慢慢精简。

    总结一下:Vue入门 + Echarts入门 ,希望能对你有用!!!😜😜😜

    感谢支持。若不足之处,欢迎大家指出,共勉。

    如果觉得不错,记得 点赞,谢谢大家 😂

    欢迎关注 我的: 【Github】【掘金】【简书】【CSDN】【OSCHINA】【SF】

    本文章采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。

    出处为:https://github.com/xrkffgg/Tools

    相关文章

      网友评论

        本文标题:vue全家桶+Echarts+百度地图,搭建数据可视化系统

        本文链接:https://www.haomeiwen.com/subject/cqrtnqtx.html