Vue2+Echarts封装组件之专注逻辑,图表生成自动化方式
作者:努力奋斗小白
文章介绍了使用Vue2封装的Echarts图表组件,简化了图表的生成和渲染过程,提供了多种图表类型和交互功能,提高了开发效率,帮助开发者专注于业务逻辑的开发
Vue2+Echarts封装组件之专注逻辑,图表生成自动化
通过Vue2封装了一个Echarts图表组件,不需要关注图表的生成和渲染了,只需要关注逻辑开发即可,包含了柱状图、折线图、饼图、柱状叠加图、柱状图折线图组合、柱状叠加图与柱状图的组合等,包含了图表下钻、右键跳转明细功能,无需关注Echarts的实现,提高开发效率。
开发者能够将注意力集中在业务逻辑的开发上,而无需担心底层图表的创建和渲染过程。这样的表述既体现了组件的便捷性,也突出了它对提高开发效率的帮助。同时,对于那些寻找简化ECharts集成解决方案的开发者来说,这也是一个很好的案例。
组件使用
(1调用)<SzqCommonChart :chart-data="charDataArray" :height="aotuMainHeight.height" /> (2data)data() { return { aotuMainHeight: { height: '' }, charDataArray: [], } }, (3接口回调后) // legend 处理: const all = ['示例1','实例2','示例3'] // 下钻的数据 const idData = [{ name: '', id: '',userId: ''}] // 横坐标的数据 const xData = ['X1','X2','X3'] // 图表的数据 const mbData = [1,2,3] // 柱状图 const sjData = [4,5,6] // 柱状图 const lvData = [7,8,9] // 折线图 // 图表的颜色 const color = ['#73deb4', '#f6e0b4', '#5b8ff9'] // Y轴单位 const unit = ['个', ''] // 参数传递 , // 2: 2代表左侧Y轴两个柱状图 1代表右侧Y轴的折线图 'barAndLine', 图的类型(此处为柱状图和折线图的组合,其他的见 SzqCommonChart) // true 是否下钻 标志1表示不同页面的不同图表的区分 all 图表实例 color图表颜色 unitY轴单位 true是否显示单位 this.charDataArray.push([2, 1, 'barAndLine', true, '标志1', all, color, unit, true]) // 参数2:下钻参数. this.charDataArray.push(idData) // 参数3:横坐标 this.charDataArray.push(xData) // 参数4 数据信息 this.charDataArray.push([mbData, sjData, lvData])
/** * 最大值最小值 */ export function szqMaxAndMin(data) { // series 中 所有数据的最大值和最小值 let isLing = false const arrLing = [] data.forEach(it => { if (it.yAxisIndex === 1) { arrLing.push(...it.data) } }) isLing = arrLing.every(number => Number(number) === 0) const mm = maxAndMin(data) // Min 左边数值轴, Min1 右侧百分比轴 const Max = Math.ceil(mm[0].max) const Max1 = Math.ceil(mm[1].max) let Min = mm[0].min let Min1 = mm[1].min const rat1 = Min / Max const rat2 = Min1 / Max1 rat1 > rat2 ? Min = rat2 * Max : Min1 = rat1 * Max1 return { max: Max, min: Math.ceil(Min), max1: Max1, min1: Math.ceil(Min1), isLing } } function maxAndMin(allData) { const result = {} allData.forEach(item => { const yAxisIndex = item.yAxisIndex const values = item.data.map(value => value && parseInt(value)) if (!result[yAxisIndex]) { result[yAxisIndex] = { max: Math.max(...values), min: Math.min(...values) } } else { result[yAxisIndex].max = Math.max(result[yAxisIndex].max, ...values) result[yAxisIndex].min = Math.min(result[yAxisIndex].min, ...values) } }) return result } export function autoBottom(h, isTitle) { let height = '' let left = [] let right = [] if (h <= 400) { isTitle ? height = '42.5%' : height = '40%' } else if (h <= 450) { isTitle ? height = '42.5%' : height = '40%' } else if (h <= 500) { isTitle ? height = '37.5%' : height = '35%' } else if (h <= 550) { isTitle ? height = '34.5%' : height = '32%' } else if (h <= 600) { isTitle ? height = '33.5%' : height = '31%' } else if (h <= 650) { isTitle ? height = '30.5%' : height = '28%' left = [0, 10, -10, -20] right = [0, -30, -10, 0] } else if (h <= 700) { isTitle ? height = '27.5%' : height = '25%' left = [0, 10, -5, -20] right = [0, -30, -5, 0] } else if (h <= 750) { isTitle ? height = '26.5%' : height = '24%' } else if (h <= 800) { isTitle ? height = '23.5%' : height = '21%' } else { isTitle ? height = '22.5%' : height = '20%' } return { height, left, right } }
<template> <!-- 图表区域 --> <div> <div ref="myEchart" :style="{ height: height, width: width }" /> </div> </template> <script> import * as echarts from 'echarts' export default { name: 'BasicChart', props: { options: { type: Object, default: () => {} }, height: { type: String, default: '100%' }, width: { type: String, default: '100%' } }, data() { return { myEchart: null, eChart: null, showPopover: false, popData: [], aotuPHeight: { left: '', top: '' }, popName: '', topS: 0, popup: '', state: { sType: '', x: '', xl: '', value: '', id: '', userId: '' } } }, watch: { options: { handler(next) { this.$nextTick(() => { // 如果只改变了颜色或者坐标轴等信息,不刷新图表 this.eChart ? this.eChart.setOption(next, true) : '' }) }, deep: true, immediate: false } }, mounted() { // 初始化图表数据 this.initEChart() window.addEventListener('resize', this.resizeChart) document.addEventListener('click', this.handleScreenClick) document.addEventListener('mousemove', this.handleMouseMove) window.addEventListener('scroll', this.handleScroll, true) }, beforeDestroy() { this.eChart ? this.eChart.clear() : '' window.removeEventListener('resize', this.resizeChart) }, methods: { handleScroll(event) { this.topS = event.srcElement.scrollTop }, handleMouseMove(event) { if (this.showPopover) { this.aotuPHeight.left = (event.clientX + 20) + 'px' this.aotuPHeight.top = (this.topS + (event.clientY - 60)) + 'px' } }, initEChart() { // 图表初始化 this.$nextTick(() => { this.eChart = echarts.init(this.$refs.myEchart) this.eChart.setOption(this.options, false) this.eChart.on('legendselectchanged', (params) => {}) // 鼠标移入后自定义的数据显示弹窗 this.eChart.on('mouseover', (params) => {}) // 鼠标移除处理 this.eChart.on('mouseout', (params) => {}) // 单机事件,针对于没有下钻有明细的 this.eChart.on('click', (params) => { if (this.options.onlyClickBUYAOLE) { // 不需要传递参数的例子 if (this.options.sType === '标志1') { this.$bus.emit('ld-mx-no-params', 'MX') } else if (this.options.sType === '标志2') { // 需要传递参数的例子获取点击的图表数据 const name = params.name this.$bus.emit('ld-mx-bing', name, 'MX') } } }) // 右键事件 this.eChart.on('contextmenu', (params) => { if (this.options.xzFlag) { // 决定处理那个图表 this.state.sType = this.options.sType // 点击的横坐标 this.state.x = params.name // 点击的系列 this.state.xl = params.seriesName // 点击的值 this.state.value = params.value // 在 横坐标放了隐藏数据,记录了一些数据 if (this.options && this.options.xAxis.length === 2) { const id = this.options.xAxis[1].data.filter(item => item.name === params.name) id.length > 0 ? this.state.id = id[0].id : this.state.id = [] id.length > 0 ? id[0].userId ? this.state.userId = id[0].userId : this.state.userId = '' : this.state.userId = '' } if (this.popup && this.popup.innerHTML !== '') { this.popup.innerHTML = '' } console.log('111111111111111111111', this.options, params, this.state) // 根据每个图表的sType判断不同的模块及模块对应的图表 // 显示右键菜单 this.showContextMenu(params.dataIndex, this.state, '') } // 右键明细的案例 if (this.options.onlyClick) { if (this.popup && this.popup.innerHTML !== '') { this.popup.innerHTML = '' } let hehe = '' console.log('333333333333333', params) if (this.options.sType === '标志1') { this.state.value = params.data.unit hehe = 'HEHE' } else if (this.options.sType === '标志2') { this.state.value = params.name hehe = 'HEHE' } this.showContextMenu(params.dataIndex, this.state, hehe) } }) }) }, // 显示右键菜单 showContextMenu(dataIndex, state, type) { this.popup = document.createElement('div') this.popup.style.position = 'absolute' this.popup.id = 'ID' + dataIndex this.popup.className = 'custom-context-menu' this.popup.style.left = event.pageX + 'px' this.popup.style.top = event.pageY + 'px' this.popup.style.zIndex = 100 if ((state.userId && state.userId !== '' && state.userId !== undefined) || type === 'HEHE') { this.popup.innerHTML = `<div style="width: 120px; height: 40px;background-color: rgba(0, 0, 0, .4);border-radius: 5px; text-align: center; color: #ffffff; font-size: 15px;cursor:pointer"> <div id="myButton2" style="height: 40px; text-align: center; line-height: 40px;">明细</div> </div>` document.body.appendChild(this.popup) document.getElementById('myButton2').addEventListener('click', () => { this.clickMx() }) } else { this.popup.innerHTML = `<div style="width: 120px; height: 80px;background-color: rgba(0, 0, 0, .4);border-radius: 5px; text-align: center; color: #ffffff; font-size: 15px;cursor:pointer"> <div id="myButton1" style="height: 40px; text-align: center; line-height: 40px; border-bottom: 1px solid #d7d7d7">下钻</div> <div id="myButton2" style="height: 40px; text-align: center; line-height: 40px;">明细</div> </div>` document.body.appendChild(this.popup) document.getElementById('myButton1').addEventListener('click', () => { this.clickXz() }) document.getElementById('myButton2').addEventListener('click', () => { this.clickMx() }) } }, // 处理下钻 clickXz() { if (this.state.sType === '标志1') { this.$bus.emit('customer-coverage', this.state, 'XZ') } }, // 明细处理 clickMx() { if (this.state.sType === '标志1') { this.$bus.emit('customer-coverage', this.state, 'MX') } }, handleScreenClick() { if (this.popup && this.popup.innerHTML !== '') { this.popup.innerHTML = '' } }, resizeChart() { this.eChart && this.eChart.resize() } } } </script> <style scoped lang="scss"> .popoverClass { background-color: rgba(0,0,0,0.5); border: 1px solid rgba(0,0,0,0.4); z-index: 10; position: absolute; color:white; border-radius: 5px; } </style>
<template> <BasicChart id="echart" :height="height" :width="width" :options="option" /> </template> <script> import BasicChart from './BasicChart/index' import { szqMaxAndMin, autoBottom } from './cockpit.js' export default { name: 'SzqCommonChart', components: { BasicChart }, props: { // 图表数据 chartData: { type: Array, default: () => null }, // 图表高度 height: { type: String, default: '400px' }, // 图标宽度 width: { type: String, default: '100%' }, // 是否显示弹窗 showTooltoip: { type: Boolean, default: true }, // 是否有标题 isTitle: { type: Boolean, default: false }, // 设置图表边距 setGrid: { type: Object, default() { return { left: '1.5%', right: '1%', top: '12%', bottom: '19%' } } }, // 是否显示示例1 showLegend: { type: Boolean, default: true }, // 示例排布,纵向 vertical 横向 horizontal orientLengent: { type: String, default: 'horizontal' }, // 示例位置,以right为准,设置auto则居中 rightLengent: { type: String, default: '10' }, leftLengent: { type: String, default: 'auto' }, topLengent: { type: String, default: 'auto' }, funcType: { type: String, default: '' } }, data() { return { windowHeight: window.innerHeight, isRate: true, option: { // 提示框1 tooltip: { show: this.showTooltoip, trigger: 'axis', axisPointer: { type: 'shadow', animation: false, snap: true, // 让 axisPointer 自动对齐到最近的数据点 crossStyle: { color: '#999' } }, borderColor: 'rgba(0,0,0,0.4)', showContent: true, // 是否显示悬浮提示框 alwaysShowContent: false, // 是否一直显示悬浮窗 backgroundColor: 'rgba(0,0,0,0.5)', formatter: (params) => { if (this.funcType === 'KHSL') { return '' } // 自定义弹窗显示样式1 // 获取xAxis data中的数据 let dataStr = `<div><p style="font-weight:bold;margin:0 8px 15px;color:white">${params[0].name}</p></div>` params.forEach((item) => { let data = '' let name = '' if (this.funcType === 'PASS') { data = Number(item.data) const ind = item.componentIndex if (ind <= 3) { name = item.seriesName + '(同期)' } else { name = item.seriesName + '(当期)' } } else { name = item.seriesName // 如果返回的是整数,不保留小数 if (item.seriesType === 'line') { if (this.isRate) { data = Number.isInteger(Number(item.data)) ? Number(item.data) + '%' : Number(item.data).toFixed(2) + '%' } else { data = Number.isInteger(Number(item.data)) ? Number(item.data) : Number(item.data).toFixed(2) } } else { data = Number.isInteger(Number(item.data)) ? Number(item.data) : Number(item.data).toFixed(2) } } dataStr += `<div> <div style="margin: 0 8px;"> <span style="display:inline-block;margin-right:5px;width:10px;height:10px;background-color:${item.color};"></span> <span style="color:#FFFFFF">${name}:</span> <span style="float:right;color:#FFFFFF;margin-left:20px;">${data}</span> </div> </div>` }) return dataStr } }, // 图表边距 grid: { left: this.setGrid.left, right: this.setGrid.right, top: this.setGrid.top, bottom: this.setGrid.bottom, containLabel: true }, // 系列 legend: { show: this.showLegend, orient: this.orientLengent, // 示例排布,横纵向 right: this.rightLengent, // 不设置则居中显示 left: this.leftLengent, // 不设置则居中显示 top: this.topLengent, itemGap: 25, // type: 'scroll', height: '300', !!饼图示例出界可以用 animation: false, data: [], textStyle: { fontSize: 12, color: '#303313' } }, xAxis: [ { show: false, type: 'category', // 类目轴,适用于离散的类目数据 inverse: false, name: '', data: [], nameLocation: 'end', // 坐标轴名称显示的位置 nameTextStyle: { // 名称的样式 fontStyle: 'normal', fontWeight: 'bold', // 粗体 fontSize: 14, align: 'left', padding: [30, 0, 0, 0], color: '#303313' // X轴 文本字体的颜色 }, axisLine: { lineStyle: { width: 1, // 线的宽度 color: '#7d7d7d' // X轴的颜色 } }, // 轴线相关配置 axisLabel: { // 坐标轴刻度标签相关配置 show: true, color: '#858689', padding: [5, 0, 0, 5], interval: '0', // 自动计算间隔 formatter: (value) => { return value && value.split('(').length > 0 ? value.split('(')[0] : value }, // rotate: 12, // fontSize: 11, rich: { year: {}, month: { padding: [0, 0, 3, 0], fontWeight: 'bold' } } }, axisTick: { alignWithLabel: true // 刻度线与标签对齐 } }, { show: false, data: [] } ], yAxis: [ { show: false, type: 'value', name: '', // 单位 position: 'left', // Y 轴的位置 inverse: false, nameTextStyle: { fontStyle: 'normal', fontSize: 13, align: 'left', padding: [0, 0, 0, -20] }, nameGap: 18, axisLabel: { color: '#858689', interval: 'auto', // Y轴内容文字颜色 formatter: (value) => { return Number.isInteger(Number(value)) ? Number(value) : Number(value).toFixed(2) } }, axisLine: { // y轴线的配置 show: false, // 是否展示 lineStyle: { color: '#7d7d7d', // y轴线的颜色(若只设置了y轴线的颜色,未设置y轴文字的颜色,则y轴文字会默认跟设置的y轴线颜色一致) width: 1, // y轴线的宽度 type: 'solid' // y轴线为实线 } }, splitLine: { lineStyle: { type: 'dashed', color: '#e5e6eb', // 虚线颜色 width: 1 } }, axisTick: { lineStyle: { color: '#7d7d7d' // 轴小横线的颜色 } } }, { show: false, type: 'value', name: '', position: 'right', // Y 轴的位置 inverse: false, axisLabel: { color: '#858689', // Y轴内容文字颜色 formatter: (value) => { if (this.isRate) { return Number.isInteger(Number(value)) ? Number(value) + '%' : Number(value).toFixed(2) + '%' } else { return Number.isInteger(Number(value)) ? Number(value) : Number(value).toFixed(2) } } }, axisLine: { // y轴线的配置 show: false, // 是否展示 lineStyle: { color: '#7d7d7d', // y轴线的颜色(若只设置了y轴线的颜色,未设置y轴文字的颜色,则y轴文字会默认跟设置的y轴线颜色一致) width: 1, // y轴线的宽度 type: 'solid' // y轴线为实线 } }, splitLine: { show: false, lineStyle: { type: 'dashed', color: '#e5e6eb', // 虚线颜色 width: 1 } } } ], color: [], series: [], onlyClick: false, // 是否点击下钻 xzFlag: false, // 是否右键下钻 sType: '' // 功能类型 }, serviceType: { 'bar': { name: '', // 合同额目标 type: 'bar', stack: '', // 叠加使用 itemStyle: { color: '' }, data: [], // emphasis: { // focus: 'series' // }, label: { show: false, position: 'top', formatter: (params) => { if (parseFloat(params.value) === 0) { return '' } return params.value === null ? '' : parseFloat(params.value).toFixed(2) } }, markLine: { symbol: 'none', // 折线为点 symbolSize: 2, // 点大小 precision: 1, lineStyle: { color: '#73deb4', width: 0 }, data: [ { name: '', yAxis: 5, label: { show: true, // 是否显示标签 formatter: '{b}', // :{c} fontSize: 11, color: '#303313', padding: [0, 0, 20, 0], position: 'end' // 标签位置 } } ] }, yAxisIndex: 0 }, 'line': { name: '', type: 'line', itemStyle: { color: '' }, yAxisIndex: 0, data: [], label: { show: true, position: 'top', formatter: '{c}' + '%' } }, 'pie': { name: '', type: 'pie', radius: '0%', left: -100, top: -50, label: { show: true, formatter: '' }, data: [] } }, service: [] } }, watch: { chartData: { handler(next) { if (next && next.length > 0) { this.chartHandler(next) } else { this.option.sType = '' this.option.legend.data = [] this.option.yAxis[0].name = '' this.option.series = [] this.service = [] this.option.xAxis[0].show = false this.option.xAxis[0].data = [] this.option.xAxis[1].data = [] } }, deep: true, immediate: true } }, mounted() { this.handleResize() window.addEventListener('resize', this.handleResize) }, beforeDestroy() { window.removeEventListener('resize', this.handleResize) }, methods: { // 渲染图表 chartHandler(next) { // 创建一个service, 保存图表个数 this.service = [] // 1: 参数说明 // num1 左侧Y轴显示图表个数 num2 右侧个数,一般图表都是左右分布的,左侧柱状图,右侧折线图 const num1 = next[0].length > 0 ? next[0][0] : 0 const num2 = next[0].length > 0 ? next[0][1] : 0 // 图表的类型 目前6种 bar line barAndLine addBar addBarAndLine,doubleAddBar // 只有柱状图、只有折线图、柱状图加折线图、柱状叠加图、柱状叠加图加折线图、双排柱状叠加图 const type = next[0].length > 0 ? next[0][2] : '' // 基础数据赋值 this.commonMes(next) // 不同类型不同处理 if (type === 'bar' || type === 'line') { this.option.yAxis[0].show = true this.option.yAxis[1].show = false const chartType = type // 只有柱状图或者折线图(单个图标) this.barHandler(type, num1, next, chartType) } else if (type === 'addBar') { this.option.yAxis[0].show = true this.option.yAxis[1].show = false // 柱状叠加图 this.barHandler('bar', num1, next, 'addBar') } else if (type === 'pie') { this.option.yAxis[0].show = false this.option.yAxis[1].show = false this.option.xAxis[0].show = false // 饼图 this.preHandler(next, type) } else if (type === 'barAndLine') { this.option.yAxis[0].show = true this.option.yAxis[1].show = true // 柱状图和折线图混合 this.barAndLineHandler('bar', 'line', num1, num2, next, 'bar', 'line') } else if (type === 'addBarAndLine') { this.option.yAxis[0].show = true this.option.yAxis[1].show = true // 叠加柱状图和折线图混合 this.barAndLineHandler('bar', 'line', num1, num2, next, 'addBar', 'line') } else if (type === 'doubleAddBar') { this.option.yAxis[0].show = true this.option.yAxis[1].show = false // 双叠加柱状图 this.barAndLineHandler('bar', 'bar', num1, num2, next, 'tqAddBar', 'dqAddBar') } this.option.series = this.service // 处理Y轴0刻度保持水平,防止某个Y轴出现负值,造成 X为0时,两个Y轴的0刻度不在一个水平 if (this.option.yAxis[0].show && this.option.yAxis[1].show) { // 最大值和最小值 const minMax = szqMaxAndMin(this.option.series) // 某个Y轴有负数的时候处理 if (Number(minMax.min) < 0 || Number(minMax.min1) < 0) { minMax.min ? this.option.yAxis[0].min = Number(minMax.min) : this.option.yAxis[0].min = 0 minMax.min1 ? this.option.yAxis[1].min = Number(minMax.min1) : this.option.yAxis[1].min = 0 } else { this.option.yAxis[0].min = 0 this.option.yAxis[1].min = 0 } } }, commonMes(next) { // 是否下钻,xzFlag:即下钻又明细 onlyClick:仅明细 if (next[0].length > 0) { if (next[0][3]) { this.option.xzFlag = true this.option.onlyClick = false } else { this.option.xzFlag = false this.option.onlyClick = true } } // 功能类型,一般使用中文标注,用于区分下钻和明细 this.option.sType = next[0].length > 0 ? next[0][4] : '' // 示例 this.option.legend.data = next[0].length > 0 ? next[0][5] : '' // 单位,两个Y轴的 this.option.yAxis[0].name = next[0].length > 0 ? next[0][7][0] : '' this.option.yAxis[1].name = next[0].length > 0 ? next[0][7][1] : '' // 显示赋值横坐标 this.option.xAxis[0].show = true this.option.xAxis[0].data = next[2] // 下钻参数,保存到第二个横坐标 this.option.xAxis[1].data = next[1] // 是否加% this.isRate = next[0].length > 0 ? next[0][8] : true }, // 处理柱状图或者折线图 barHandler(type, num, next, chartTyep) { for (let i = 0; i < num; i++) { const newData = JSON.parse(JSON.stringify(this.serviceType[type])) this.setData(newData, 0, next, 0, i, chartTyep) this.service.push(newData) } }, // 处理柱状图和折线图的混合(混合图表) barAndLineHandler(type1, type2, num1, num2, next, chartType1, chartType2) { // 先柱后折 for (let i = 0; i < num1; i++) { const newData = JSON.parse(JSON.stringify(this.serviceType[type1])) this.setData(newData, 0, next, 0, i, chartType1) this.service.push(newData) } // 只有双叠加柱状图才会是0 let leftOrRight = 1 chartType1 === 'tqAddBar' ? leftOrRight = 0 : leftOrRight = 1 for (let i = 0; i < num2; i++) { const newData = JSON.parse(JSON.stringify(this.serviceType[type2])) this.setData(newData, leftOrRight, next, num1, i, chartType2) this.service.push(newData) } }, // 饼图处理 preHandler(next, type) { const newData = JSON.parse(JSON.stringify(this.serviceType[type])) newData.radius = '50%' newData.color = next[0].length > 0 ? next[0][6] : [] newData.data = next[3][0] newData.label.formatter = (value) => { return value.name + '' + value.data.num } this.service.push(newData) }, // 设置数据 setData(newData, yAxisIndex, next, num1, i, type) { // 设置Y轴为左右 newData.yAxisIndex = yAxisIndex // 设置示例颜色 newData.itemStyle.color = next[0].length > 0 ? next[0][6][num1 + i] : '' // 放置数据 newData.data = next[3].length > 0 ? next[3][num1 + i] : [] // 名称 newData.name = next[0].length > 0 ? next[0][5][num1 + i] : '' // 单个叠加柱状图的处理DQ当期 TQ同期 if (type === 'addBar') { newData.stack = 'DQ' } else if (type === 'tqAddBar') { newData.stack = 'TQ' } else if (type === 'dqAddBar') { newData.stack = 'DQ' } // 折线图一般是率,需要加百分号 if (this.isRate && type === 'line') { newData.label.formatter = '{c}' + '%' } else { newData.label.formatter = '{c}' } }, handleResize() { // 更新windowWidth的值,更好看一点 this.$nextTick(() => { this.windowHeight = window.innerHeight const ob = autoBottom(window.innerHeight, this.isTitle) this.option.grid.bottom = ob.height if (ob.left.length > 0) { this.option.yAxis[0].nameTextStyle.padding = ob.left } if (ob.right.length > 0) { this.option.yAxis[1].nameTextStyle.padding = ob.right } }) } } } </script> <style scoped lang="scss"> </style>
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。