前段時間因爲公司須要,產品臨時安排任務,但願儘快出一個實時數據統計的圖表,因此綜合考慮就沒有用echarts自己,而是使用了經過vue封裝過的v-charts,但願能快速上手echarts,而後就有了這篇文章的實現過程。html
接下來按照上圖紅框從左到右從上到下一一講解:vue
├── src 源碼目錄
│ ├── main.js 入口js文件
│ ├── app.json 全局配置
│ ├── components 組件目錄
│ │ └── common 公共組件
└── classfiyRing.vue 框5
└── hHistogram.vue 框4
└── hLine.vue 框2
└── hMap.vue 框3
└── hRing.vue 框1複製代碼
<!-- 環狀 -->
<template>
<div class="h-ring">
<div class="ring-relative">
<ve-ring
class="ring-box"
:data="chartData"
:settings="chartSettings"
height="112px"
width="112px"
:tooltip="tooltip"
:extend="chartExtend"
></ve-ring>
<span class="desc">{{percentage}}</span>
</div>
<p class="title">{{text}}</p>
</div>
</template>
<script>
export default {
data () {
this.chartSettings = {
dimension: 'name',
metrics: 'value',
label: {
normal: {
show: false
}
},
radius: [
'25', '40'
],
offsetY: 56
}
return {
tooltip: {
trigger: 'none'
},
chartExtend: {
legend: {
show: false
},
color: ['#44F0FF', '#19355A']
}
}
},
props: {
text: {
type: String,
required: true
},
chartData: {
type: Object,
required: true
},
percentage: {
type: String,
required: true
}
}
}
</script>複製代碼
echarts options 屬性,與echarts配置項對應的屬性也被加到了組件上,用於直接覆蓋options原有的對應屬性;json
grid: [object, array],
colors: array,
visualMap: [object, array],
dataZoom: [object, array],
toolbox: [object, array],
title: object,
legend: [object, array],
xAxis: [object, array],
yAxis: [object, array],
radar: object,
tooltip: object,
axisPointer: object,
brush: [object, array],
geo: object,
timeline: [object, array],
graphic: [object, array],
series: [object, array],
backgroundColor: [object, string],
textStyle: object,
animation: object複製代碼
折線圖組件內容:bash
<!-- 折線圖 -->
<template>
<div class="h-line">
<ve-line
:data="chartData"
:settings="chartSettings"
height="250px"
width="348px"
:extend="chartExtend"
></ve-line>
</div>
</template>
<script>
export default {
data () {
this.chartSettings = {
metrics: ['新增門店'],
dimension: ['日期'],
scale: [true, true]
}
return {
chartExtend: {
series: {
label: {
normal: {
show: true,
color: '#90E23C',
fontSize: 18
}
},
symbolSize: 10,
color: ['#44F0FF']
},
legend: {
show: false
},
grid: {
y: 10,
y2: 50,
left: 10,
containLabel: true
},
xAxis: {
axisLabel: {
textStyle: {
color: '#fff',
fontSize: 14
}
},
axisLine: {
show: true,
lineStyle: {
color: '#fff'
}
}
},
yAxis: {
axisLabel: {
textStyle: {
color: '#fff',
fontSize: 14
}
},
splitLine: {
show: false
},
position: 'left',
axisLine: {
show: true,
lineStyle: {
color: '#fff'
}
}
}
}
}
},
props: {
chartData: {
type: Object,
required: true
}
}
}
</script>複製代碼
<!-- 地圖 -->
<template>
<div class="h-map">
<ve-map
class="echarts-map"
:data="chartData"
:settings="chartSettings"
height="600px"
width="600px"
:extend="chartExtend"
></ve-map>
</div>
</template>
<script>
export default {
data () {
return {
chartSettings: {
position: 'china',
metrics: ['門店數'],
itemStyle: {
normal: {
borderColor: '#72F2FF',
areaColor: '#7F8FA3',
borderWidth: 2,
shadowBlur: 1
},
emphasis: {
borderColor: '#72F2FF',
areaColor: '#19355A',
borderWidth: 1,
shadowBlur: 1
}
},
label: {
normal: {
show: true,
formatter: function (params) {
if (params.value) {
return params.name + ' ' + params.value // 地圖上展現文字 + 數值
} else {
return ''
}
},
color: '#fff',
backgroundColor: 'rgba(0, 15, 42, 0.3)',
fontSize: 12,
align: 'right',
verticalAlign: 'top',
lineHeight: 12,
padding: 4,
borderRadius: 4
},
emphasis: {
show: true,
formatter: function (params) {
if (params.value) {
return params.name + ' ' + params.value // 地圖上展現文字 + 數值
} else {
return ''
}
},
color: '#44F0FF'
}
},
zoom: 1,
selectData: true,
scaleLimit: {
min: 1,
max: 2
},
roam: true
},
chartExtend: {
legend: {
show: false
},
visualMap: [
{
type: 'continuous',
left: 'left',
top: 'bottom',
calculable: true,
text: ['高', '低'],
inRange: {
color: ['#4C627F', '#334C6D', '#19355A']
},
textStyle: {
color: '#fff'
}
}
]
}
}
},
props: {
chartData: {
type: Object,
required: true
}
}
}
</script>複製代碼
爲ve-map組件添加geo、series屬性可設置漣漪特效動畫,以下圖:app
實現漣漪特效動畫的關鍵代碼以下: (感興趣的能夠本身實現,原本項目也須要作這個動畫,可是當和區域地圖結合的時候二者不能同時顯示,目前尚未找到最佳方法,因此項目中捨棄了動畫)echarts
<div id="app">
<ve-map :tooltip="chartTooltip" :settings="chartSettings" :geo="chartGeo" :series="chartSeries" :data="chartData"></ve-map>
</div>
<script>
new Vue({
el: '#app',
created: function() {
this.chartTooltip = {
formatter: function(v) {
var tpl = []
tpl.push(v.seriesName + '<br>')
tpl.push(v.name + ':' + v.value[2])
return tpl.join('')
}
}
this.chartData = {
columns: [],
rows: []
}
this.chartSettings = {
position: 'china'
}
this.chartSeries = [{
name: 'pm2.5',
type: 'effectScatter', // 'scatter'
coordinateSystem: 'geo',
symbolSize: 10,
rippleEffect: {
brushType: 'stroke'
},
hoverAnimation: true,
data: [{
name: '吉林',
value: [126.57, 43.87, 10]
}],
label: {
normal: {
formatter: '{b}',
position: 'right',
show: true
},
emphasis: {
show: true
}
},
itemStyle: {
normal: {
color: '#ddb926'
}
}
}]
this.chartGeo = {
map: 'china',
label: {
emphasis: {
show: false
}
},
roam: true,
itemStyle: {
normal: {
areaColor: '#323c48',
borderColor: '#111'
},
emphasis: {
areaColor: '#2a333d'
}
}
}
}
})
</script>複製代碼
<!-- 柱狀圖 -->
<template>
<div class="h-histogram">
<h-title :text="'活躍門店走勢圖'"></h-title>
<ve-histogram
:data="chartData"
:extend="chartExtend"
width="328px"
height="220px"
></ve-histogram>
<div class="item">
<h-title :text="'活躍門店排名'"></h-title>
<ul class="city-list">
<transition-group name="list" mode="out-in">
<li class="city" v-for="item in realList" :key="item.id">
{{item.name}}
</li>
<li class="city" v-if="realList.length >= 1 && realList.length < 2" :key="'one'"></li>
<li class="city" v-if="realList.length >= 1 && realList.length < 3" :key="'two'"></li>
<li class="city" v-if="realList.length >= 1 && realList.length < 4" :key="'three'"></li>
<li class="city" v-if="realList.length >= 1 && realList.length < 5" :key="'four'"></li>
</transition-group>
</ul>
</div>
</div>
</template>
<script>
import HTitle from '@/components/common/hTitle'
export default {
data () {
return {
chartExtend: {
legend: {
show: false
},
grid: {
left: '5%',
containLabel: true,
top: '5%',
bottom: '5%'
},
xAxis: {
axisLabel: {
textStyle: {
color: '#fff',
fontSize: 14
}
},
axisLine: {
show: true,
lineStyle: {
color: '#fff'
}
}
},
yAxis: {
axisLabel: {
textStyle: {
color: '#fff',
fontSize: 14
}
},
splitLine: {
show: false
},
position: 'left',
axisLine: {
show: true,
lineStyle: {
color: '#fff'
}
}
},
series: {
type: 'bar',
itemStyle: {
normal: {
color: 'rgba(68,240,255,1)'
}
}
}
},
storeFlag: true,
realList: [],
timer3: null
}
},
props: {
chartData: {
type: Object,
required: true
},
storeList: {
type: Array,
required: true
}
},
components: {
HTitle
},
watch: {
storeList (newVal, oldVal) {
const that = this
if (newVal.length > 0) {
if (that.storeList.length > 5) {
that.realList = that.storeList.slice(0, 5)
that.timer3 = setInterval(() => {
if (that.storeFlag) {
that.realList = that.storeList.slice(5)
that.storeFlag = false
} else {
that.realList = that.storeList.slice(0, 5)
that.storeFlag = true
}
}, 5000)
} else {
that.realList = that.storeList
}
}
}
}
}
</script>複製代碼
<!-- 產品分類統計 -->
<template>
<div class="classify-ring">
<h-title :text="'產品分類統計'"></h-title>
<ve-ring
class="ring"
:data="chartData"
width="360px"
height="160px"
:settings="chartSettings"
:extend="chartExtend"
></ve-ring>
</div>
</template>
<script>
import HTitle from '@/components/common/hTitle'
export default {
data () {
this.chartSettings = {
dimension: 'name',
metrics: 'value',
radius: [
'35', '50'
],
offsetY: 80,
labelLine: {
normal: {
lineStyle: {
color: '#fff'
}
}
},
label: {
normal: {
formatter: '{b}: {d}%',
padding: [0, -10]
}
}
}
return {
chartExtend: {
legend: {
show: false
}
}
}
},
components: {
HTitle
},
props: {
chartData: {
type: Object,
required: true
}
}
}
</script>複製代碼
其實在作項目以前,本人是沒有用過echarts的,就項目自己而言是有些畏懼的,怕作很差。但經過本身的摸索,儘量達到產品須要的效果,這也是我但願作到的。最後的效果除了地圖有點差強人意,其餘基本都正常實現了,後面有時間再好好研究下地圖漣漪動畫的實現。之因此寫這個文章,一是爲了幫助那些沒用過又須要上手echarts的朋友;二是爲了記錄本身的學習過程。讀到這裏,若是以爲本文對你有所啓發或幫助,請動動大家的手指,點個贊吧!ide