
.vue
import multiBarLineChart from '@/utils/echarts.js'
drawChart (xData, datas) {
this.myEchart = echarts.init(this.$refs.myChart)
const countLimit = 8 // 可视范围展示个数
this.myEchart.clear()
this.myEchart.setOption(multiBarLineChart(xData, datas, countLimit))
window.onresize = _.debounce(this.myEchart.resize, 500)
}
echarts.js
xData的数据格式为[‘2021Q1’,‘2021Q2’,…]
datas的数据格式如下图
import * as echarts from 'echarts'
const axisLineTxTColor = '#666' // 轴和文字颜色
const splitLineColor = '#d9d9d9' // 分割线颜色
const gradientList = [ // 渐变色字典(最多是4个)
{ light: '#a4cbfd', dark: '#5c97ca' },
{ light: '#b4ecd0', dark: '#73deb3' },
{ light: '#ffe3a4', dark: '#fac858' },
{ light: '#ffa1a1', dark: '#ee6666' }
]
/** 动态柱状折线图
* @xData 横坐标数据 ['','',...]
* @datas 传过来的原始数据(用于处理legend,yAxis,series等)
* @showCount 可视区域内展示的个数,超过则滑动(默认8)
*/
const multiBarLineChart = (xData, datas, showCount = 8) => {
const obj = handleDatas(datas) // 处理数据获取legend等信息
const { legend, yAxis, series } = obj
// 赋值option
const option = {
title: {
text: xData.length > showCount ? '(滑动查看更多)' : '',
left: 48,
textStyle: {
fontSize: '12',
color: '#999',
fontWeight: 500
}
},
grid: {
top: xData.length > showCount ? 60 : 40,
bottom: 80,
left: 80,
right: 60,
y2: 2 // 控制柱状间隔
},
dataZoom: [{
type: 'inside',
rangeMode: ['value', 'percent'],
startValue: xData.length >= showCount ? xData.length - showCount : 0,
endValue: xData.length - 1,
preventDefaultMouseMove: false, // 阻止mousemove事件的默认行为
zoomOnMouseWheel: false // 禁用鼠标滑轮的缩放
}],
tooltip: {
trigger: 'axis',
confine: true, // 避免悬浮窗溢出
axisPointer: {
type: 'cross',
crossStyle: {
type: 'dashed'
},
lineStyle: {
type: 'dashed'
}
},
formatter: (params) => {
let str = `${params[0].name}<br/>`
params.forEach((item, index) => {
const color = item.color?.colorStops[0]?.color // 提取渐变色中其中一头的颜色
if (color) item.marker = item.marker.replace('[object Object]', color) // 解决渐变色无法提取marker问题
const valContent = item.value ? item.value + item.data.unit : '-'
str += `${item.marker}${item.seriesName} : ${valContent}${index !== params.length - 1 ? '<br/>' : ''}`
})
return str
}
},
xAxis: [
{
type: 'category',
data: xData,
axisLine: {
lineStyle: { color: '#999' }
},
axisLabel: { color: axisLineTxTColor },
axisTick: { show: false }
}
],
yAxis,
legend,
series
}
return option
}
// 统一处理数据
const handleDatas = (datas) => {
const _datas = _.cloneDeep(datas)
const hasBar = datas.find(item => item.type === 'bar')
const hasLine = datas.find(item => item.type === 'line')
const has2type = hasBar && hasLine // 是否bar,line均有
let i = 0
const barCount = _datas.reduce((prev, cur) => { // 柱状图个数
if (cur.type === 'bar') i++
return i
}, 0)
// 1.图例
const legend = {
bottom: 0,
itemWidth: 15,
itemHeight: 8,
data: _datas.map(item => item.name)
}
// 2.y轴设置
const defaultYAxis = [] // 默认双y轴
const arr2 = new Array(2).fill('')
const barItem = _datas.filter(item => item.type === 'bar')?.[0]?.data
arr2.forEach((item, index) => { // 双类型时-> index: 0-bar使用, 1-line使用
defaultYAxis.push({
type: 'value',
name: index === 0 ? barItem?.[0].unit : '',
// min: 0,
// max: 25,
// interval: index === 0 ? 50 :5,
axisLabel: {
color: axisLineTxTColor,
formatter: index === 0 ? '{value}' : '{value}%'
},
axisLine: {
show: false,
lineStyle: { color: '#999' } // 联动tooltip-cross指示器的背景色
},
axisTick: { show: false },
splitLine: { // 分割线
show: has2type ? index === 0 : true,
lineStyle: {
type: 'solid',
color: splitLineColor
}
}
})
})
const yAxis = has2type ? defaultYAxis : (hasBar ? [defaultYAxis[0]] : [defaultYAxis[1]]) // 若单类型则判断具体哪条轴
// 3.series赋值
const series = _datas.map((item, index) => {
const isBar = item.type === 'bar'
return {
name: item.name,
type: item.type,
yAxisIndex: has2type ? (isBar ? 0 : 1) : 0, // 双类型时: 0-左侧bar, 1-右侧line; 单类型只有0-左侧轴
barWidth: isBar ? (barCount > 2 ? 15 : 20) : void 0, // 柱图宽度
itemStyle: { // 图例会自动提取这里的颜色
normal: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: gradientList[index].light },
{ offset: 1, color: gradientList[index].dark }
])
}
},
data: item.data.map(it => {
return {
value: it.value,
unit: it.unit, // 单位
label: { // 文字说明
show: false,
fontSize: 12,
color: '#999',
position: +it.value >= 0 ? 'top' : 'bottom',
formatter: isBar ? '{c}' : `{c}${it.unit}`
},
itemStyle: {
normal: {
barBorderRadius: +it.value >= 0 ? [15, 15, 0, 0] : [0, 0, 15, 15] // 动态设置柱状图圆角
}
}
}
})
}
})
const obj = { legend, yAxis, series }
return obj
}
export default multiBarLineChart
这篇博客详细介绍了如何使用Echarts在Vue.js环境中创建动态的折线柱状图,包括实现渐变色的marker效果,控制可视区域内展示的数据点个数,以及动态设置柱状图的圆角等高级特性。内容涉及到的数据格式为xData: ['2021Q1', '2021Q2', ...]和datas的相关配置。"
110701319,9620680,PAT甲级考试2020.12.5总结:边界bug与DFS挑战,"['算法', 'Java', '数据结构', 'DFS', '编程竞赛']


1129

被折叠的 条评论
为什么被折叠?



