vue全家桶+Echarts+百度地圖,搭建數據可視化系統

本文章篇幅略長,內容有點多
大佬可根據目錄選擇性查閱
新人可一步步來閱讀

1 前言

1.1 業務場景

忽然接到產品說要作一個數據監控的系統。有線圖、柱狀圖、地圖,相似於數據可視化的方式。php

本人以前從未接觸過Echarts,而後須要2周拿出成果,有點慌😂😂css

1.2 業務分析

拿到需求看了一下html

支持用戶名、密碼登陸,默認顯示一個維度數據,而後點擊可鑽取進入第二維度數據,再點擊進入第三維度數據展現。前端

大體估摸着。。。vue

  1. 系統搭建vue-cli
  2. vuex記錄登陸信息
  3. vue-router路由跳轉
  4. 3個維度的頁面,提取出共用的組件
  5. 各個組件開發
  6. 調節樣式,增長UI
  7. 加入後臺接口數據
  8. 優化顯示
  9. 測試
  10. 上線

固然這不是要2周內,全作完。應該是完成步驟6。node

相對於公司就我一個前端,沒接觸過Echarts,有問題都沒人討論的狀況下。。。git

內心仍是忍不住想吐槽一下😒😒😒github

1.3 效果展現

這裏列出了第一維度頁面的樣式。文字請無視,哈哈。web

image

2 系統安裝

吐槽歸吐槽,活仍是要乾的。😎

由於本人最熟悉的仍是vue,因此仍是選擇了用vue全家桶來作。這部分可參考 vue buildvue-router

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中添加

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...

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,有沒有大佬能給出更好的辦法?

找到一個全量引用的方法

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]+'<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

相關文章
相關標籤/搜索