6f30895b8d4aea04150a9f81209566c5.png

作者 | xrkffgg
来源 | https://www.jianshu.com/p/f4f90d44227f

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 效果展示

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

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,其他可根据需要添加。方法一
vue create hello-world
这里参照官方网站,有很详细的介绍。参照:vue create
方法二使用图形化界面
  • vue ui
界面含中文,很好操作。参照:vue ui

2.2.4 安装插件

方法一最直接也是推荐的 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
方法二vue ui图像化界面中包含了若干插件,可点击安装,但不一定是最新版本。同时会在hello中引入。其他和方法一没区别。

2.3 安装Echarts

这里我们为了方便,使用了npm全量引用,后期为了精简项目可单个引用。
npm i echarts -S
然后在main.js中添加2506e311d01a7a7a9f20997754cbb948.png这里建议提前自定义echarts的样式,并引入到项目中。官方自定义地址:theme-builder在页面中我们可以如下引用:
var myChart = this.$echarts.init(document.getElementById("myid"),'temp')
myid是我们要展示的echartsidtemp是我们的自定义的样式,同时官方提供了几个样式例子,可以node_modules\echarts\theme中找到。

2.4 安装element-ui

这里我们为了方便,使用了npm全量引用,后期为了精简项目可单个引用。
  • npm i element-ui -S
然后在main.js中添加e199ec2d7cf41b4516be0e1e7db27e0c.png

2.5 安装百度地图

一般vue使用百度地图有2种方式,
  • 一种是像官网那样去应用。如:BMap
  • 第二种是使用 vue-baidu-map
不管是哪一种都要去申请账号和密钥。申请地址为:百度地图密钥(ak)这里我使用了第二种。vue-baidu-map文档
npm i vue-baidu-map -S
然后在main.js中添加f2a44e9ea08e3002c3f62dfa3d1d108f.pngxxxxxxxx这里填写自己申请的密钥。在页面中,参照文档,可使用标签来调用。

2.6 初始化样式

css样式初始化,简单来说就是为了各个浏览器能统一什么的。这里我使用的是 normalize.css下载下来后,在main.js中添加d397fa45356a2ec66197a9d5464cc51d.png基本上的准备工作都做好了,接下来就是具体的代码了。

3、项目搭建

3.1 router、vuex

我这里新建了一个router.jsstore.js,大致如下:f73828d5f2c0eef43c15790aa48ba8bb.png哦哈,这里路由定义是为了方便看哈,具体还是根据业务来定义。这里的router.beforeEach 路由卫士用于是否登录校验。然后我们在main.js中来引用。ae4853dceaf74e92cd8401eb37aa761b.png更多请参考官方文档:Vue Router Vuex

3.2 、Login页面

登录页面没啥,就是个form提交,由于路由中判断user.id。所以我们储存一下,然后跳转到Index页面就行。这里只是一种方式,也可以使用CookieSession

3.3 Index页面

分析页面分成了2个大部分
  • 第一部分是 头部
  • 第二部门是 主体
7f27fbf89eedbc53f9b1738a04c87951.png我们将头部当做一个组件进行复用。组件的复用可参考官方文档: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,})
预览:d20e8e59a703afe31eb28db5b0b30898.png

3.5.3 柱状图

这里我们直接用双柱状图来演示。因为名字和数字需要提示和点击的功能,所以没有使用echartsy轴。不然formatter又要写一堆,虽然用了自定义的,但最开始是用的formatter。可以实现相同展示,但无法操作,如鼠标提示和鼠标点击。
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>
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>
"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                }            },        },    ]}
预览:9db4ce12599529c6534d823dff091f8e.png

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;}
预览:b628b97d2399ae688bcb4822f21e1127.png

3.5.5 百度地图

vue-baidu-map 文档
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">     //  标点                    :key="it.id"             :position="it.position"         //  标点位置            @click="markclick(it,index)"    //  标点点击事件            @mouseover="markover(it,index)" //  鼠标移动到标点上的事件            :icon="it.if? iocn:newincon"    //  标点的样式            @mouseout="markout(it,index)">  //  鼠标从标点移走的事件                            :show="it.show"             //  标点提示框的显示true/false                :position="it.position">    //  提示框坐标                

"it.mess"

> // 提示框内容 template>map>预览:8a1ae6040d601ef4d14154565738202e.png

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,有没有大佬能给出更好的办法?找到一个全量引用的方法
const rjs = require.context('echarts/map/js/province')rjs.keys().forEach(rjs)
可以替代
require('echarts/map/js/province/beijing.js')require('echarts/map/js/province/shanxi.js')require('echarts/map/js/province/neimenggu.js')
等等等。。。
地图配置:
option = {    //  鼠标提示    tooltip : {        trigger: 'item',        formatter : function(params){            var val = params.data            return '名称:'+val.name+',个数:'+val.value[2]+'
'+'总数:'+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);})
预览:978449e26f8f9cf7d93aea1127ceefb0.png7f9829f5101549bfbd60eee6901b9ecc.png

4 、后记

目前还没有接入后端数据,就是全前台的一个展示。很多都是全量引入,后续待成熟后,可慢慢精简。总结一下:Vue入门 + Echarts入门 ,希望能对你有用!!!😜😜😜感谢支持。若不足之处,欢迎大家指出,共勉。如果觉得不错,记得 点赞,谢谢大家 😂VUE相关图书

1fd73116f2557e1787be35887ecb4404.png

7d7455b8fa34b9b256e1457072ad6262.png

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐