Vue-Element UI集成ECharts实现数据统计分析页
·
文章目录
背景
ECharts是由百度开发捐献给Apache的一款基于 JavaScript 的开源可视化图表库,有丰富的图表库、完善的文档,开箱即用,非常方便好用。
效果预览
以下效果中的数据均为虚拟数据。
其中包含饼状图、折线图。
相关文档
官方示例:https://echarts.apache.org/examples/zh/index.html
官方文档:https://echarts.apache.org/handbook/zh/get-started/
相关依赖
"echarts": "5.1.2"
- 工具类
utils/index.js
/**
* @param {Function} func
* @param {number} wait
* @param {boolean} immediate
* @return {*}
*/
export function debounce(func, wait, immediate) {
let timeout, args, context, timestamp, result
const later = function() {
// 据上一次触发时间间隔
const last = +new Date() - timestamp
// 上次被包装函数被调用时间间隔 last 小于设定时间间隔 wait
if (last < wait && last > 0) {
timeout = setTimeout(later, wait - last)
} else {
timeout = null
// 如果设定为immediate===true,因为开始边界已经调用过了此处无需调用
if (!immediate) {
result = func.apply(context, args)
if (!timeout) context = args = null
}
}
}
return function(...args) {
context = this
timestamp = +new Date()
const callNow = immediate && !timeout
// 如果延时不存在,重新设定延时
if (!timeout) timeout = setTimeout(later, wait)
if (callNow) {
result = func.apply(context, args)
context = args = null
}
return result
}
}
mixins/resize.js
import { debounce } from '@/utils'
export default {
data() {
return {
$_sidebarElm: null
}
},
mounted() {
this.$_initResizeEvent()
this.$_initSidebarResizeEvent()
},
beforeDestroy() {
this.$_destroyResizeEvent()
this.$_destroySidebarResizeEvent()
},
activated() {
this.$_initResizeEvent()
this.$_initSidebarResizeEvent()
},
deactivated() {
this.$_destroyResizeEvent()
this.$_destroySidebarResizeEvent()
},
methods: {
$_resizeHandler() {
return debounce(() => {
if (this.chart) {
this.chart.resize()
}
}, 100)()
},
$_initResizeEvent() {
window.addEventListener('resize', this.$_resizeHandler)
},
$_destroyResizeEvent() {
window.removeEventListener('resize', this.$_resizeHandler)
},
$_sidebarResizeHandler(e) {
if (e.propertyName === 'width') {
this.$_resizeHandler()
}
},
$_initSidebarResizeEvent() {
this.$_sidebarElm = document.getElementsByClassName('sidebar-container')[0]
this.$_sidebarElm && this.$_sidebarElm.addEventListener('transitionend', this.$_sidebarResizeHandler)
},
$_destroySidebarResizeEvent() {
this.$_sidebarElm && this.$_sidebarElm.removeEventListener('transitionend', this.$_sidebarResizeHandler)
}
}
}
具体实现
下面组件的变量每一个在官方文档中都有标注,自行去查阅。
饼状环形圆角图(组件编写)
Vue部分
<template>
<div :class="className" :style="{minHeight:height,width:width}"/>
</template>
Js部分
<script>
import * as echarts from 'echarts'
import resize from './mixins/resize'
// 饼状环形圆角图
export default {
mixins: [resize],
props: {
className: {
type: String,
default: 'chart'
},
width: {
type: String,
default: '100%'
},
height: {
type: String,
default: '250px'
},
seriesData: {
type: Array,
// 默认数据
default: () => {
return [
{
name: '用户统计',
type: 'pie',
radius: ['40%', '70%'],
avoidLabelOverlap: false,
itemStyle: {
borderRadius: 10,
borderColor: '#fff',
borderWidth: 2
},
label: {
show: false,
position: 'center'
},
emphasis: {
label: {
show: true,
fontSize: '15',
fontWeight: 'bold'
}
},
labelLine: {
show: false
},
data: [
{ value: 1048, name: '新增' },
{ value: 735, name: '冻结' },
{ value: 355, name: '活跃' }
]
}
]
}
}
},
data() {
return {
chart: null
}
},
mounted() {
this.$nextTick(() => {
this.initChart()
})
},
beforeDestroy() {
if (!this.chart) {
return
}
this.chart.dispose()
this.chart = null
},
methods: {
initChart() {
this.chart = echarts.init(this.$el, 'roma')
this.drawChart()
},
drawChart() {
this.chart.setOption({
tooltip: {
trigger: 'item',
// formatter: '{a} <br/>{b} : {c} ({d}%)',
formatter: '{b} : {c} ({d}%)',
backgroundColor: 'rgba(255,255,255,0.8)',
color: 'black',
borderWidth: '1',
borderColor: 'gray',
textStyle: {
color: 'black'
}
},
legend: {
left: 'center'
},
series: this.seriesData
})
}
}
}
</script>
饼状平铺图(组件编写)
Vue部分
<template>
<div :class="className" :style="{minHeight:height,width:width}"/>
</template>
Js部分
<script>
import * as echarts from 'echarts'
import resize from './mixins/resize'
// 饼状平铺图
export default {
mixins: [resize],
props: {
className: {
type: String,
default: 'chart'
},
width: {
type: String,
default: '100%'
},
height: {
type: String,
default: '300px'
},
seriesData: {
type: Array,
default: () => {
return [
{
name: '示例数据',
type: 'pie',
radius: '50%',
emphasis: {
itemStyle: {
shadowBlur: 10,
shadowOffsetX: 0,
shadowColor: 'rgba(0, 0, 0, 0.5)'
}
},
itemStyle: {
normal: {
label: {
show: true,
formatter: '{b} : {c} ({d}%)'
},
labelLine: { show: true }
}
},
data: [
{ value: 1048, name: '类目一' },
{ value: 735, name: '类目二' },
{ value: 580, name: '类目三' }
]
}
]
}
}
},
watch: {
seriesData: {
deep: true,
handler(val) {
this.seriesData = val
this.disposeChart()
this.initChart()
}
}
},
data() {
return {
chart: null
}
},
mounted() {
this.$nextTick(() => {
this.initChart()
})
},
beforeDestroy() {
this.disposeChart()
},
methods: {
disposeChart() {
if (!this.chart) {
return
}
this.chart.dispose()
this.chart = null
},
initChart() {
this.chart = echarts.init(this.$el, 'roma')
this.drawChart()
},
drawChart() {
this.chart.setOption({
tooltip: {
trigger: 'item',
formatter: '{b} : {c} ({d}%)'
},
legend: {
left: 'center'
},
series: this.seriesData
})
}
}
}
</script>
折线堆叠图(组件编写)
Vue部分
<template>
<div :class="className" :style="{height:height,width:width}"/>
</template>
Js部分
// 折线堆叠图
export default {
mixins: [resize],
props: {
className: {
type: String,
default: 'chart'
},
width: {
type: String,
default: '100%'
},
height: {
type: String,
default: '500px'
},
xAxisData: {
type: Array,
default: () => {
return ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10']
}
},
seriesData: {
type: Array,
default: () => {
return [{
name: '示例1',
type: 'line',
stack: '总量',
emphasis: {
focus: 'series'
},
areaStyle: {
// 改变区域颜色
//color: '#fadb14'
},
// itemStyle: {
// normal: {
// // 折线点颜色
// color: '#d4b106',
// lineStyle: {
// // 折线颜色
// color: '#876800'
// }
// }
// },
// 光滑线条
// smooth: true,
data: [67, 6213, 66, 67, 78, 632, 1410, 4552, 4512, 555]
}, {
name: '示例2',
type: 'line',
stack: '总量',
areaStyle: {},
emphasis: {
focus: 'series'
},
data: [120, 132, 101, 134, 90, 230, 210, 3466, 67, 36]
}]
}
}
},
watch: {
xAxisData: {
deep: true,
handler(val) {
this.xAxisData = val
}
},
seriesData: {
deep: true,
handler(val) {
this.seriesData = val
this.disposeChart()
this.initChart()
}
}
},
data() {
return {
chart: null
}
},
mounted() {
this.$nextTick(() => {
this.initChart()
})
},
beforeDestroy() {
this.disposeChart()
},
methods: {
disposeChart() {
if (!this.chart) {
return
}
this.chart.dispose()
this.chart = null
},
initChart() {
this.chart = echarts.init(this.$el, 'roma')
this.drawChart()
},
drawChart() {
this.chart.setOption({
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross',
label: {
backgroundColor: '#6a7985'
}
}
},
legend: {
left: 'center'
},
toolbox: {
feature: {
saveAsImage: {}
}
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
xAxis: [
{
type: 'category',
boundaryGap: false,
data: this.xAxisData
}
],
yAxis: [
{
type: 'value'
}
],
series: this.seriesData
})
}
}
}
</script>
组件引用(业务代码)
<el-col :xs="24" :sm="16" :md="16" :lg="16" :xl="16">
<el-card shadow="always">
<div slot="header" class="clearfix">
<span>销售趋势</span>
<span class="card-div-desc">{{ lineCardTitle }}</span>
<el-radio-group style="float: right; padding: 3px 0" v-model="lineDataType"
size="mini" @change="handleLineChange">
<el-radio-button label="order">订单数</el-radio-button>
<el-radio-button label="sale">销售额</el-radio-button>
</el-radio-group>
</div>
<div>
<LineHeapChart
height="600px"
:xAxisData="lineXAxisData"
:seriesData="lineSeriesData"
/>
</div>
</el-card>
</el-col>
import LineHeapChart from '@/views/dashboard/LineHeapChart'
import PieFlatChart from '@/views/dashboard/PieFlatChart'
export default {
name: 'index',
components: {
LineHeapChart,
PieFlatChart
},
}
具体的数据结构,在每一个组件里面的插槽位置都有对应的默认数据示例,自行将后端传来的数据转换为默认数据格式传递给组件就可以了。
下载文章代码
https://download.csdn.net/download/zhengjiacheng2016/85242441
(如果帮助到你,感谢关注点赞)
声明:不包含示例图的全部布局样式代码,需要的自己根据项目风格编写布局,放入Chart即可,像[ 组件引用(业务代码) ],部分一样,简单的用[el-card] 组件包装。
更多推荐
已为社区贡献1条内容
所有评论(0)