基于echarts实例封装的组件,用于需要echarts比较多的时候,将他进行封装,哪个页面需要直接引用就好
1、安装
npm i v-charts echarts -S
2、完整引入
// main.js
import Vue from ‘vue’
import VCharts from ‘v-charts’
import App from ‘./App.vue’
Vue.use(VCharts)
3、echarts封装的组件
封装了各种类型的图表。只需要给个type类型判断,就可以区分使用组件的哪种类型的图表,以下是代码封装的完整版,如需更多类型,只需要继续添加即可。
<template>
<div :style="{width: '100%', height: '100%'}" :id='id'>
</div>
</template>
<script>
export default {
props: {
datas: Object, //图标对象 x值y值
id: String, //图表id
unit: String,
position: String, //方形
type: String //图表类型
},
mounted() {
this.init();
},
methods: {
init() {
let myChart = this.$echarts.init(document.getElementById(this.id))
let option = {};
if (this.type == "1") { //折线
option = {
tooltip: {
trigger: 'axis'
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
top: '5%',
containLabel: true
},
xAxis: [{
type: 'category',
data: this.datas.label,
axisLine: {
lineStyle: {
color: "#999"
}
}
}],
yAxis: [{
type: 'value',
splitNumber: 4,
splitLine: {
lineStyle: {
type: 'dashed',
color: '#DDD'
}
},
axisLine: {
show: false,
lineStyle: {
color: "#333"
},
},
nameTextStyle: {
color: "#999"
},
splitArea: {
show: false
}
}],
series: [{
name: '',
type: 'line',
data: this.datas.list,
lineStyle: {
normal: {
width: 2,
color: {
type: 'linear',
colorStops: [{
offset: 0,
color: '#A9F387' // 0% 处的颜色
}, {
offset: 1,
color: '#48D8BF' // 100% 处的颜色
}],
globalCoord: false // 缺省为 false
},
shadowColor: 'rgba(72,216,191, 0.3)',
shadowBlur: 10,
shadowOffsetY: 20
}
},
itemStyle: {
normal: {
color: '#fff',
borderWidth: 10,
/*shadowColor: 'rgba(72,216,191, 0.3)',
shadowBlur: 100,*/
borderColor: "#A9F387"
}
},
smooth: true
}]
};
} else if (this.type == "2") { //柱状图
option = {
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'line'
}
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
top: '5%',
containLabel: true
},
xAxis: [{
type: 'category',
data: this.datas.label,
axisTick: {
alignWithLabel: true
}
}],
yAxis: [{
type: 'value',
axisLabel: {
show: true,
// interval: 'auto',
// formatter:'{value}' + (this.unit || "%")
formatter: '{value}' + (this.unit || "㎡")
},
axisLine: {
show: true,
},
min: 0,
}],
series: [{
type: 'bar',
barWidth: '35%', // 柱子宽度
label: {
show: true,
color: '#fff',
fontSize: 14,
fontWeight: 'bold', // 加粗
distance: 5, // 距离
// formatter: '{c}' + (this.unit || "%")
formatter: '{c}' + (this.unit || "")
}, // 柱子上方的数值
itemStyle: {
color: function (params) {
var colorList = ['#3AA0FF', '#4ECB73', '#F55277', '#F8A52C', '#FF883A'];
return colorList[params.dataIndex];
},
},
data: this.datas.list
}]
};
} else if (this.type == "3") { //横向
let sumValue = this.datas.list.reduce((sum, number) => {
return sum + number;
}, 1)
console.log(sumValue)
option = {
backgroundColor: '#fff',
color: ['#1E93FF'],
grid: {
containLabel: true,
top: 15,
bottom: 5,
left: 2,
right: 20
},
tooltip: {
trigger: 'axis'
},
xAxis: {
type: 'value',
axisTick: {
show: false
},
axisLine: {
show: false
},
splitLine: {
lineStyle: {
color: '#CCCCCC',
type: 'dashed'
}
}
},
yAxis: {
type: 'category',
data: this.datas.label,
axisTick: {
show: false
},
axisLine: {
show: false
},
axisLabel: {
interval: 0
},
splitLine: {
show: true,
lineStyle: {
color: '#CCCCCC',
type: 'dashed'
}
}
},
series: [{
name: '',
type: 'bar',
barWidth: '18px',
label: {
show: true,
position: 'right',
color: '#333333',
fontSize: 14,
offset: [2, 0]
},
data: this.datas.list.map(ele => {
return (ele / sumValue).toFixed(1) * 100
})
}]
};
} else if (this.type == "4") { //饼图百分比
let bgcolor = ["#3aa0fe", "#5ddecf", "#4dcb73", "#8976cb"]
let index = this.id.replace(/[^0-9]/ig, "")
option = {
title: [{
text: this.datas.label,
x: 'center',
top: 'center',
}],
polar: {
radius: ['94%', '80%'],
center: ['50%', '50%'],
},
angleAxis: {
max: 100,
show: false,
},
radiusAxis: {
type: 'category',
show: true,
axisLabel: {
show: false,
},
axisLine: {
show: false,
},
axisTick: {
show: false
},
},
series: [{
name: '',
type: 'bar',
roundCap: true,
barWidth: 20,
showBackground: true,
backgroundStyle: {
color: "#ccc",
},
data: this.datas.list,
coordinateSystem: 'polar',
itemStyle: {
normal: {
color: bgcolor[index]
}
}
}]
}
} else if (this.type == "5" || this.type == "6") { //饼图切分 5:分裂 6:实心
let datas = this.datas.list
const sum = (...arr) => [].concat(...arr).reduce((acc, val) => Number(acc) + Number(val), 0);
let putArr = datas.map(ele => {
return ele.value;
})
function getValue(val) {
return datas.filter(ele => {
return ele.name == val
})[0].value
}
const colorList = ['#47A2FF ', '#53C8D1', '#59CB74', '#FBD444', "#f00"]
option = {
title: {
text: ((datas[0].value / sum(putArr)) * 100).toFixed(0) + "%",
subtext: datas[0].name,
textStyle: {
fontSize: 16,
color: '#333',
lineHeight: 20
},
subtextStyle: {
fontSize: 18,
color: '#999'
},
textAlign: 'center',
left: '20%',
top: '36%',
show: this.type == "5" ? true : false
},
tooltip: {
trigger: 'item',
},
legend: {
type: 'scroll',
orient: 'vertical',
right: this.type == "5" ? '10%' : '50%',
top: 'center',
itemGap: 20,
selectedMode: true,
icon: 'pin',
data: this.datas.label,
textStyle: {
color: '#77899c',
rich: {
uname: {
width: 100
},
unum: {
color: '#000',
width: 40,
fontSize: 14,
align: 'left'
}
}
},
formatter(name, s) {
return `{uname|${name}}{unum|${((getValue(name) / sum(putArr)) * 100).toFixed(2)}}{unit| %}`
}
},
color: colorList,
series: [{
type: 'pie',
radius: this.type == "5" ? [60, 80] : "80%",
center: this.type == "5" ? ['20%', '50%'] : ['70%', '50%'],
label: {
show: false
},
labelLine: {
show: false
},
data: this.datas.list
}]
};
} else if (this.type == "7") { //多类柱状图
option = {
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow'
}
},
legend: {
data: this.datas.titles
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
xAxis: [{
type: 'category',
data: this.datas.tit
}],
yAxis: {
type: 'value',
},
series: this.datas.list
}
}
myChart.setOption(option)
}
}
}
</script>
4、父页面使用时,引用子组件
type的数字即判断图表的类型,datas即图表的数据
<script>
import Chart from "@/components/charts/index"
export default {
components: { Chart },
},
</script>
好了,只需要这样就可以轻松在页面写多个echarts了。哪个页面需要直接按上面直接引,拿来即用。