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

栏目: 编程语言 · 发布时间: 5年前

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

本文章篇幅略长,内容有点多

大佬可根据目录选择性查阅

新人可一步步来阅读

1 前言

1.1 业务场景

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

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

1.2 业务分析

拿到需求看了一下

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

大致估摸着。。。

vue-cli
vuex
vue-router

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

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

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

1.3 效果展示

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

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

2 系统安装

吐槽归吐槽,活还是要干的。:sunglasses:

因为本人最熟悉的还是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用户AppDataRoamingnpm
  1. 方法二

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

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

2.3 安装Echarts

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

  • npm i echarts -S

然后在 main.js 中添加

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

这里建议提前自定义 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 中添加

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

2.5 安装百度地图

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

  • 一种是像官网那样去应用。如: BMap
  • 第二种是使用 vue-baidu-map

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

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

  • npm i vue-baidu-map -S

然后在 main.js 中添加

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

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

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

2.6 初始化样式

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

这里我使用的是 normalize.css

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

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

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

3 项目搭建

3.1 router、vuex

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

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

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

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

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

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

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

3.2 Login页面

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

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

3.3 Index页面

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

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

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

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

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

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,
})

预览:

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

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
                }
            },
        },
    ]
}

预览:

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

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;
    }
}
  • 滚动条的样式

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

/* 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;
}

预览:

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

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>

预览:

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

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);
})

预览:

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

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

4 后记

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

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

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

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

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

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

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


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Algorithm Design

Algorithm Design

Jon Kleinberg、Éva Tardos / Addison-Wesley / 2005-3-26 / USD 144.20

Algorithm Design introduces algorithms by looking at the real-world problems that motivate them. The book teaches students a range of design and analysis techniques for problems that arise in compu......一起来看看 《Algorithm Design》 这本书的介绍吧!

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具