echarts动态的折线柱状图(渐变色的marker处理;控制可视区域展示个数;动态设置柱状图圆角等)

这篇博客详细介绍了如何使用Echarts在Vue.js环境中创建动态的折线柱状图,包括实现渐变色的marker效果,控制可视区域内展示的数据点个数,以及动态设置柱状图的圆角等高级特性。内容涉及到的数据格式为xData: ['2021Q1', '2021Q2', ...]和datas的相关配置。" 110701319,9620680,PAT甲级考试2020.12.5总结:边界bug与DFS挑战,"['算法', 'Java', '数据结构', 'DFS', '编程竞赛']

在这里插入图片描述
.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

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值