前段时间因为公司须要,产品临时安排任务,但愿尽快出一个实时数据统计的图表,因此综合考虑就没有用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