ECharts中通过饼图(type为pie)绘制出仪表盘进度条

        在ECharts中,可以通过多个饼图系列(series)来实现仪表盘形式的进度条,如下图,需要通过以下几个饼图组合来完成。

  1. 一个饼图用于进度条背景底色(未完成部分);
  2. 一个饼图用于进度条颜色(已完成部分);
  3. 一个饼图用于进度条末端白色圆点,跟随已完成进度条变更位置;
  4. 一个饼图用于进度条中间扇形透明背景色,跟随已完成进度条变更面积大小;
  5. 最后一个饼图用于中间圆环和文字显示。

        所以,要完成下图进度条,需使用五个饼图来完成图例绘制。那么,接下来我们就按上面顺序,逐一实现。

一、创建界面

        首先在Vue项目中创建一个页面,在路由中配置好地址并在浏览器输入路由跳转到该页面,页面代码 如下:

<template>
  <div class="chart-box" ref="chart"></div>
</template>
<script>
import { chartOptions } from './data/options'
export default {
  data () {
    return {
      chartDom: null
    }
  },
  mounted () {
    this.$nextTick(() => {
      this.initialChart()
    })
  },
  methods: {
    initialChart () {
      // 初始化画板
      this.chartDom = this.$echart.init(this.$refs['chart'])
      this.renderChart()
    },
    renderChart () {
      this.chartDom.setOption(chartOptions({name: '贮藏率', value: 50}))
    }
  }
}
</script>

        将配置项单独放在options.js文件中,通过export导入到页面再使用。

二、未完成进度条绘制

        未完成部分进度条颜色长度是固定的,所以它的开始和末端位置不需要动态调整。打开options.js文件,在配置项中添加未完成进度条。配置代码如下:

/**
 * 配置参数
 * @param {*} chartData 表单数据
 * @returns 返回配置项
 */
export const chartOptions = (chartData) => {
  return {
    series: [
      // 外环底色
      {
        type: 'pie',
        radius: ['50%', '53%'],
        center: ['50%', '50%'],
        startAngle: 225,
        endAngle: 315 - 360,
        label: {   // 文字隐藏
          show: false
        },
        // 未完成进度条两端圆角 + 背景色
        itemStyle: {
          borderRadius: 15,
          color: '#151D21'
        },
        // 鼠标划过的高亮取消
        emphasis: {
          disabled: true
        }
      }
    ]
  }
}

        页面效果如下图:

        对于上面配置项中,可能有些人不明白startAngle和endAngle值是从何而来,下面咱们看一张图,来了解下坐标系。

扫描二维码关注公众号,回复: 17604044 查看本文章

        如上图清晰可见,咱们进度条是从角度225开始,到角度315结束。按顺时针旋转计算,到角度315位置,则是负值 -45度。

三、已完成进度条绘制

        已完成部分进度条,需要根据进度值进行调整结束末端的位置,这部分将会涉及一点计算功能。配置项代码如下:

import * as echarts from 'echarts'
/**
 * 配置参数
 * @param {*} chartData 表单数据
 * @returns 返回配置项
 */
export const chartOptions = (chartData) => {
  return {
    dataset: {
      source: [
        ['贮藏率', 50]
      ]
    },
    series: [
      // 外环底色
      {
        type: 'pie',
        radius: ['50%', '53%'],
        center: ['50%', '50%'],
        startAngle: 225,
        endAngle: 315 - 360,
        label: { // 文字隐藏
          show: false
        },
        // 未完成进度条两端圆角 + 背景色
        itemStyle: {
          borderRadius: 15,
          color: '#151D21'
        },
        // 鼠标划过的高亮取消
        emphasis: {
          disabled: true
        }
      },
      // 外环
      {
        type: 'pie',
        radius: ['50%', '53%'],
        center: ['50%', '50%'],
        startAngle: 225,
        endAngle: 315 - 360,
        label: {
          show: false
        },
        // 已完成部分背景渐变色 + 末端圆角
        itemStyle: {
          borderRadius: 15,
          color: new echarts.graphic.LinearGradient(1, 0, 0, 0, [
            {
              offset: 0,
              color: 'rgb(255, 158, 68)'
            },
            {
              offset: 1,
              color: 'rgba(233, 144, 82, 0)'
            }
          ])
        },
        emphasis: {
          disabled: true
        }
      }
    ]
  }
}

        图表效果如下图:

        注意,除了series中要添加已完成部分配置项代码外,还需要添加dataset数据集,否则已完成部分不会被绘制。目前先默认为100%长度,后续再通过计算来实现末端位置变更。

四、进度条末端圆点绘制

        对于进度条末端圆点的绘制,则是通过收缩开始位置和末端位置间距来实现,始终保持开始和结束间距为6度,即可呈现出一个圆点效果。配置项代码如下:

export const chartOptions = (chartData) => {
  return {
    dataset: {
      source: [
        ['贮藏率', 50]
      ]
    },
    series: [
      // 略...

      // 末端圆点绘制
      {
        type: 'pie',
        radius: ['48.5%', '54%'],
        center: ['50%', '50%'],
        // 此处角度值始终保持相差6度即可,根据进度值变更起始和结束位置
        startAngle: -39,
        endAngle: -45,
        label: {
          show: false
        },
        // 圆点的圆角值  + 四周阴影效果
        itemStyle: {
          borderRadius: 15,
          color: 'rgb(255, 255, 255)',
          shadowBlur: 20,
          shadowColor: 'rgba(255, 255, 255, .6)',
          shadowOffsetX: 0,
          shadowOffsetY: 0
        },
        animation: true,
        emphasis: {
          disabled: true
        }
      }
    ]
  }
}

        页面效果如下图:

五、透明扇形绘制

        对于透明扇形图形绘制,则简单多了,主要是调整饼图开始和结束位置,修改背景色即可。配置项代码如下:

export const chartOptions = (chartData) => {
  return {
    dataset: {
      source: [
        ['贮藏率', 50]
      ]
    },
    series: [
      // 略...

      // 内部扇形透明底色
      {
        type: 'pie',
        radius: [0, '53%'],
        center: ['50%', '50%'],
        startAngle: 225,
        endAngle: 315 - 360,
        label: {
          show: false
        },
        // 设置背景色,并将透明度设置为0.15
        itemStyle: {
          color: 'rgba(233, 144, 82, .15)'
        },
        emphasis: {
          disabled: true
        }
      }
    ]
  }
}

        页面效果如下图:

六、中间内容和圆环绘制

        对于中间内圆和文字部分,通过一个饼图完成绘制即可。配置项代码如下:

export const chartOptions = (chartData) => {
  return {
    dataset: {
      source: [
        ['贮藏率', 50]
      ]
    },
    series: [
      // 略...

      // 内部扇形透明底色
      {
        type: 'pie',
        radius: [0, '53%'],
        center: ['50%', '50%'],
        startAngle: 225,
        endAngle: 315 - 360,
        label: {
          show: false
        },
        itemStyle: {
          color: 'rgba(233, 144, 82, .15)'
        },
        emphasis: {
          disabled: true
        }
      },
      // 内圆 + 文字
      {
        name: 'circleText',
        type: 'pie',
        radius: [0, '40%'],
        center: ['50%', '50%'],
        // 将文字 进度值 调整到圆环中间位置 + 并格式化内容添加%号单位符
        label: {
          show: true,
          position: 'center',
          formatter: param => param.value[1] + '%',
          color: 'rgb(233, 144, 82)',
          fontSize: 25,
          fontWeight: 'bold'
        },
        // 设置饼图的背景色 + 线条宽度和颜色 + 四周阴影效果
        itemStyle: {
          color: '#100C2A',
          borderColor: 'rgb(255, 158, 68)',
          borderWidth: 1,
          shadowBlur: 10,
          shadowColor: 'rgba(255, 255, 255, .3)',
          shadowOffsetX: 0,
          shadowOffsetY: 0
        },
        emphasis: {
          disabled: true
        },
        animation: true,
        animationEasing: 'cubicIn'
      }
    ]
  }
}

        效果如下图:

        如果希望透明扇形在内圆+文字上方,将二者顺序调换一下即可。

七、动态更新末端位置

        将图表基本部分绘制完毕后,接下来则需要通过计算对末端位置进行调整。

  1. 首先,定义percent变量,记录当前进度值长度的百分比
  2. 其次,定义startAngle和endAngle变量,用于统一调整所有涉及开始和结束角度设置的饼图,并便于后面计算出当前进度值所在末端位置的角度。
  3. 最后,定义valueAngle用于记录得出的末端位置的角度。

       

        通过上图可见,进度条的开始位置到结束位置为顺时针,并且角度值为递减(225°~-45°)模式,另外225+45=270°,且通过百分比(percent)值则可以计算出当前已完成部分所占270°角度长度份额。所以通过公式:startAngle - ((startAngle - endAngle) * percent)即可获取当前已完成进度条长度。

        现在通过上述方法来定义相应变量,并计算出已完成的进度条长度的末端角度值。配置项代码如下:

import * as echarts from 'echarts'
/**
 * 配置参数
 * @param {*} chartData 表单数据
 * @returns 返回配置项
 */
export const chartOptions = (chartData) => {
  const percent = chartData.value / 100 // 百分比
  const startAngle = 225 // 开始位置角度值
  const endAngle = 315 - 360 // 结束位置角度值
  // 计算并得出当前值位置的角度值
  const valueAngle = startAngle - ((startAngle - endAngle) * percent)
  return {
    dataset: {
      source: [
        [chartData.name, chartData.value]
      ]
    },
    series: [
      // 外环底色
      {
        type: 'pie',
        radius: ['50%', '53%'],
        center: ['50%', '50%'],
        startAngle,
        endAngle,
        label: { // 文字隐藏
          show: false
        },
        // 未完成进度条两端圆角 + 背景色
        itemStyle: {
          borderRadius: 15,
          color: '#151D21'
        },
        // 鼠标划过的高亮取消
        emphasis: {
          disabled: true
        }
      },
      // 外环
      {
        type: 'pie',
        radius: ['50%', '53%'],
        center: ['50%', '50%'],
        startAngle,
        endAngle: valueAngle,
        label: {
          show: false
        },
        // 已完成部分背景渐变色 + 末端圆角
        itemStyle: {
          borderRadius: 15,
          color: new echarts.graphic.LinearGradient(1, 0, 0, 0, [
            {
              offset: 0,
              color: 'rgb(255, 158, 68)'
            },
            {
              offset: 1,
              color: 'rgba(233, 144, 82, 0)'
            }
          ])
        },
        emphasis: {
          disabled: true
        }
      },
      // 末端圆点绘制
      {
        type: 'pie',
        radius: ['48.5%', '54%'],
        center: ['50%', '50%'],
        // 此处角度值始终保持相差6度即可,根据进度值变更起始和结束位置
        startAngle: valueAngle + 3,
        endAngle: valueAngle - 3,
        label: {
          show: false
        },
        // 圆点的圆角值  + 四周阴影效果
        itemStyle: {
          borderRadius: 15,
          color: 'rgb(255, 255, 255)',
          shadowBlur: 20,
          shadowColor: 'rgba(255, 255, 255, .6)',
          shadowOffsetX: 0,
          shadowOffsetY: 0
        },
        animation: true,
        emphasis: {
          disabled: true
        }
      },
      // 内圆 + 文字
      {
        name: 'circleText',
        type: 'pie',
        radius: [0, '40%'],
        center: ['50%', '50%'],
        // 将文字 进度值 调整到圆环中间位置 + 并格式化内容添加%号单位符
        label: {
          show: true,
          position: 'center',
          formatter: param => param.value[1] + '%',
          color: 'rgb(233, 144, 82)',
          fontSize: 25,
          fontWeight: 'bold'
        },
        // 设置饼图的背景色 + 线条宽度和颜色 + 四周阴影效果
        itemStyle: {
          color: '#100C2A',
          borderColor: 'rgb(255, 158, 68)',
          borderWidth: 1,
          shadowBlur: 10,
          shadowColor: 'rgba(255, 255, 255, .3)',
          shadowOffsetX: 0,
          shadowOffsetY: 0
        },
        emphasis: {
          disabled: true
        },
        animation: true,
        animationEasing: 'cubicIn'
      },
      // 内部扇形透明底色
      {
        type: 'pie',
        radius: [0, '53%'],
        center: ['50%', '50%'],
        startAngle,
        endAngle: valueAngle,
        label: {
          show: false
        },
        itemStyle: {
          color: 'rgba(233, 144, 82, .15)'
        },
        emphasis: {
          disabled: true
        }
      }
    ]
  }
}

        页面效果如下图:

        此篇就先讲到这,希望对大家有所帮助。