vue 数据可视化大屏开发中,因为大屏都是一个一个的模块组成,除了实现效果外,我们还需要考虑组件的可移植性和复用性,避免因为数据导致组件使用混乱。尽可能做到组件拿来即用。
请求接口
首先组件封装,当前组件我们只做一件事请求接口,把接口的数据传给echarts子组件。
<template>
<div class="itemBodys">
<echarts1 :list="list"></echarts1>
</div>
</template>
<script>
import dayjs from 'dayjs'
import echarts1 from "./echarts1.vue";
import {getBaseData} from "@/api/api/user.js";
export default {
name: "title",
data() {
return {
list: [{
title: '专科生',
value: 0,
id: 'studentTypeJuniorCollege'
}, {
title: '留学生',
value: 0,
id: 'studentTypeOverseasStudent'
}, {
title: '函授生',
value: 0,
id: 'studentTypeCorrespondenceStudent'
}, {
title: '全日制在校生',
value: 0,
id: 'learningTypeFullTime'
}, {
title: '折合在校生',
value: 0,
id: 'learningTypeAll'
},],
}
},
components: {echarts1},
watch: {},
mounted() {
var that = this;
this.getData()
},
methods: {
getData() {
var that = this;
getBaseData({year: dayjs().format("YYYY")}).then(res => {
if (res.data) {
that.list.forEach((type) => {
type.value = res.data[type.id]
});
}
}).catch(err => {
})
},
},
}
</script>
<style lang="scss" scoped>
.itemBodys {
position: relative;
width: calc(100% - 40px);
margin: 0 auto;
height: calc(100% - 10px);
display: flex;
justify-content: space-around;
align-items: flex-start;
flex-wrap: nowrap;
flex-direction: column;
align-content: flex-start;
}
</style>
echarts组件封装
组件获取到父组件的传值后,通过计算属性来获取横坐标纵坐标的值的数组,通过watch监听数组的变化来渲染echarts图表。这里我们只需要关心x轴的数据获取 y轴的数据获取就可以了。
<template>
<div class="echarts1" ref="echarts">
</div>
</template>
<script>
import * as echarts from "echarts";
export default {
name: 'echarts1',
components: {},
data() {
return {}
},
watch: {
xData() {
this.drawEcharts()
},
yData() {
this.drawEcharts()
},
},
props: {
list: {
type: Array,
default() {
return [];
}
}
},
mounted() {
this.drawEcharts()
},
computed: {
xData: function () {
var list = []
this.list.forEach((type) => {
list.push(type.title)
});
return list
},
yData: function () {
var list = []
this.list.forEach((type) => {
list.push(type.value)
});
return list
},
},
methods: {
drawEcharts() {
var that = this
window.addEventListener('resize', this.drawEcharts)
let myChart = echarts.init(this.$refs.echarts)
var option = {
color: ['#00D7E9', 'rgba(0, 215, 233, 0.9)'],
grid: {
containLabel: true,
left: 0,
right: 0,
bottom: 0,
top: 40,
},
xAxis: {
axisLabel: { //底部label样式
color: 'rgba(215, 231, 255, 1)',
fontSize: 13,
interval: 0,
},
axisTick: { //刻度线
show: false,
},
splitLine: { //不显示分割线
show: false
},
axisLine: {
lineStyle: {
color: '#335971',
},
show: true,
},
data: this.xData,
},
yAxis: {
name: '人', //左上角单位设置
nameTextStyle: {
color: 'rgba(11, 255, 168, 1)',
padding: [0, 25, 0, 0],
fontSize: 12,
},
axisLabel: { //纵坐标颜色
color: 'rgba(181, 217, 255, 1)',
fontSize: 14,
interval: 0,
fontFamily: 'DIN-bold'
},
axisTick: { //不显示刻度
show: false,
},
splitLine: { //分割线样式
show: true,
lineStyle: {
color: '#335971',
"type": "dashed"
},
},
axisLine: { //不显示左侧坐标轴线
show: false,
}
},
series: [
{
data: this.yData,
type: 'bar', //类型 柱状图为bar
barWidth: 27, //柱状图宽度
itemStyle: { //柱状图颜色,通过linear实现渐变色
color: {
x: 0,
y: 1,
x2: 0,
y2: 0,
type: 'linear',
colorStops: [
{
offset: 0,
color: 'rgba(18, 99, 255, 1)',
},
{
offset: 1,
color: 'rgba(4, 206, 247, 1)',
},
],
},
},
label: { //柱状图文字配置
show: true,
position: 'top',
distance: 10,
fontSize: 14,
color: 'rgba(0, 234, 254, 1)',
fontFamily: 'DIN-bold'
},
},
],
tooltip: {
show: true,
formatter: '{b}:{c0}',
},
};
myChart.clear()
myChart.resize()
myChart.setOption(option)
},
}
}
</script>
<style lang="scss" scoped>
.echarts1 {
position: relative;
width: 100%;
height: 100%;
}
</style>