Vue2+Echarts封裝組件之專注邏輯,圖表生成自動化方式
Vue2+Echarts封裝組件之專注邏輯,圖表生成自動化
通過Vue2封裝了一個Echarts圖表組件,不需要關(guān)注圖表的生成和渲染了,只需要關(guān)注邏輯開發(fā)即可,包含了柱狀圖、折線圖、餅圖、柱狀疊加圖、柱狀圖折線圖組合、柱狀疊加圖與柱狀圖的組合等,包含了圖表下鉆、右鍵跳轉(zhuǎn)明細功能,無需關(guān)注Echarts的實現(xiàn),提高開發(fā)效率。
開發(fā)者能夠?qū)⒆⒁饬性跇I(yè)務邏輯的開發(fā)上,而無需擔心底層圖表的創(chuàng)建和渲染過程。這樣的表述既體現(xiàn)了組件的便捷性,也突出了它對提高開發(fā)效率的幫助。同時,對于那些尋找簡化ECharts集成解決方案的開發(fā)者來說,這也是一個很好的案例。

組件使用
(1調(diào)用)<SzqCommonChart :chart-data="charDataArray" :height="aotuMainHeight.height" />
(2data)data() {
return {
aotuMainHeight: {
height: ''
},
charDataArray: [],
}
},
(3接口回調(diào)后)
// legend 處理:
const all = ['示例1','實例2','示例3']
// 下鉆的數(shù)據(jù)
const idData = [{ name: '', id: '',userId: ''}]
// 橫坐標的數(shù)據(jù)
const xData = ['X1','X2','X3']
// 圖表的數(shù)據(jù)
const mbData = [1,2,3] // 柱狀圖
const sjData = [4,5,6] // 柱狀圖
const lvData = [7,8,9] // 折線圖
// 圖表的顏色
const color = ['#73deb4', '#f6e0b4', '#5b8ff9']
// Y軸單位
const unit = ['個', '']
// 參數(shù)傳遞 ,
// 2: 2代表左側(cè)Y軸兩個柱狀圖 1代表右側(cè)Y軸的折線圖 'barAndLine', 圖的類型(此處為柱狀圖和折線圖的組合,其他的見 SzqCommonChart)
// true 是否下鉆 標志1表示不同頁面的不同圖表的區(qū)分 all 圖表實例 color圖表顏色 unitY軸單位 true是否顯示單位
this.charDataArray.push([2, 1, 'barAndLine', true, '標志1', all, color, unit, true])
// 參數(shù)2:下鉆參數(shù).
this.charDataArray.push(idData)
// 參數(shù)3:橫坐標
this.charDataArray.push(xData)
// 參數(shù)4 數(shù)據(jù)信息
this.charDataArray.push([mbData, sjData, lvData])/**
* 最大值最小值
*/
export function szqMaxAndMin(data) {
// series 中 所有數(shù)據(jù)的最大值和最小值
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 左邊數(shù)值軸, Min1 右側(cè)百分比軸
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>
<!-- 圖表區(qū)域 -->
<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() {
// 初始化圖表數(shù)據(jù)
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) => {})
// 鼠標移入后自定義的數(shù)據(jù)顯示彈窗
this.eChart.on('mouseover', (params) => {})
// 鼠標移除處理
this.eChart.on('mouseout', (params) => {})
// 單機事件,針對于沒有下鉆有明細的
this.eChart.on('click', (params) => {
if (this.options.onlyClickBUYAOLE) {
// 不需要傳遞參數(shù)的例子
if (this.options.sType === '標志1') {
this.$bus.emit('ld-mx-no-params', 'MX')
} else if (this.options.sType === '標志2') {
// 需要傳遞參數(shù)的例子獲取點擊的圖表數(shù)據(jù)
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
// 在 橫坐標放了隱藏數(shù)據(jù),記錄了一些數(shù)據(jù)
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)
// 根據(jù)每個圖表的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: {
// 圖表數(shù)據(jù)
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 自動對齊到最近的數(shù)據(jù)點
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中的數(shù)據(jù)
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
// 如果返回的是整數(shù),不保留小數(shù)
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', // 類目軸,適用于離散的類目數(shù)據(jù)
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軸的顏色
}
}, // 軸線相關(guān)配置
axisLabel: {
// 坐標軸刻度標簽相關(guān)配置
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軸內(nèi)容文字顏色
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軸內(nèi)容文字顏色
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: '', // :{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) {
// 創(chuàng)建一個service, 保存圖表個數(shù)
this.service = []
// 1: 參數(shù)說明
// num1 左側(cè)Y軸顯示圖表個數(shù) num2 右側(cè)個數(shù),一般圖表都是左右分布的,左側(cè)柱狀圖,右側(cè)折線圖
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] : ''
// 基礎數(shù)據(jù)賦值
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軸出現(xiàn)負值,造成 X為0時,兩個Y軸的0刻度不在一個水平
if (this.option.yAxis[0].show && this.option.yAxis[1].show) {
// 最大值和最小值
const minMax = szqMaxAndMin(this.option.series)
// 某個Y軸有負數(shù)的時候處理
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
}
}
// 功能類型,一般使用中文標注,用于區(qū)分下鉆和明細
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]
// 下鉆參數(shù),保存到第二個橫坐標
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)
},
// 設置數(shù)據(jù)
setData(newData, yAxisIndex, next, num1, i, type) {
// 設置Y軸為左右
newData.yAxisIndex = yAxisIndex
// 設置示例顏色
newData.itemStyle.color = next[0].length > 0 ? next[0][6][num1 + i] : ''
// 放置數(shù)據(jù)
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>總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
vue2.0和mintui-infiniteScroll結(jié)合如何實現(xiàn)無線滾動加載
這篇文章主要介紹了vue2.0和mintui-infiniteScroll結(jié)合如何實現(xiàn)無線滾動加載,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-10-10
vue實現(xiàn)歌手列表字母排序下拉滾動條側(cè)欄排序?qū)崟r更新
這篇文章主要介紹了vue實現(xiàn)歌手列表字母排序,下拉滾動條側(cè)欄排序?qū)崟r更新,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下2019-05-05
基于Vue3和Element Plus實現(xiàn)自動導入功能
在 Vue 3 項目中,結(jié)合 Element Plus 實現(xiàn)自動導入可以顯著減少代碼量,提升開發(fā)效率,Element Plus 提供了官方的自動導入插件 unplugin-vue-components 和 unplugin-auto-import,以下是如何配置和使用的詳細步驟,需要的朋友可以參考下2025-03-03
關(guān)于vue跳轉(zhuǎn)后頁面置頂?shù)膯栴}
這篇文章主要介紹了關(guān)于vue跳轉(zhuǎn)后頁面置頂?shù)膯栴},具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-05-05
如何在vue3中使用滑塊檢驗vue-puzzle-verification
這篇文章主要介紹了在vue3中使用滑塊檢驗vue-puzzle-verification的相關(guān)資料,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友參考下吧2023-11-11

