1. 90前端首页
  2. 前端开发
  3. JavaScript

Echart饼图实现(圆环图)+状态颜色控制

最近做项目遇到了圆环图以及对于图例颜色值的处理,这里做一个记录,分享给大家。
UI图长这样:
Echart饼图实现(圆环图)+状态颜色控制

HTML

<div class=\"flex-row\">
              <div class=\"contain flex-row\" v-loading=\"taskLoading\">
                <resize-chart :chart=\"taskChart\">
                  <div id=\"taskChart\" style=\"width:7.8rem;height:5rem;\" />
                </resize-chart>
              </div>
            </div>

其中,resize-chart是封装的自适应组件

JS

initTaskChart() {
      getTaskStatus({ type: this.taskTimeType }).then(res => {
        console.log(\'任务状态\', res)
        if (res) {
          const color = [
            \'#999999\',
            \'#00cce2\',
            \'#9962ff\',
            \'#27dca1\',
            \'#e9e536\',
            \'\',
            \'#1cbe6b\',
            \'#f8a639\',
            \'#f868b9\',
            \'#4a8dfd\',
            \'#f45151\'
          ]
          let taskStateList = JSON.parse(JSON.stringify(res))
          let taskStateData = []
          let taskStatelegendData = []
          let taskTotal = 0
          for (const item of taskStateList) {
            taskTotal += item.count
            taskStateData.push({
              name: this.taskStateArr[item.state],
              value: item.count,
              itemStyle: {
                normal: { color: this.statusColorHandle(item.state, color) }
              }
            })
            taskStatelegendData.push({
              name: this.taskStateArr[item.state],
              value: item.count,
              textStyle: {
                normal: { color: this.statusColorHandle(item.state, color) }
              }
            })
          }
          this.taskChart = echarts.init(document.getElementById(\'taskChart\'))
          this.taskChart.setOption(
            {
              title: {
                text: taskTotal === 0 ? \'\' : taskTotal,//主要是为了处理没有数据时
                subtext: taskTotal !== 0 ? \'任务总量\' : \'\',
                x: \'center\',
                y: \'center\',
                textAlign: \'center\',
                itemGap: 5, //主副标题之间的间距
                top: \'38%\',
                left: \'28%\',
                // 标题
                textStyle: {
                  fontFamily: \'PingFangSC-Medium\',
                  fontWeight: \'normal\',
                  fontSize: 20,
                  color: \'#333333\'
                },
                // 副标题
                subtextStyle: {
                  fontWeight: \'normal\',
                  fontSize: 14,
                  color: \'#333333\'
                }
              },
              legend: {
                type: \'scroll\',
                icon: \'circle\',
                orient: \'vertical\',
                y: \'center\',
                right: \'5%\',
                itemWidth: 5,
                itemHeight: 5,
                data: taskStatelegendData,
                // 使用回调函数
                formatter: function(name) {
                  let count, percent
                  for (const item of taskStatelegendData) {
                    if (item.name === name) {
                      count = item.value
                      percent = ((item.value / taskTotal) * 100).toFixed(2)
                    }
                  }
                  let arr = [
                    \'{a|\' + name + \'}\',
                    \'{b|\' + count + \'}\',
                    \'{c|\' + percent + \'}%\'
                  ]
                  return arr.join(\'\')
                },
                textStyle: {
                  rich: {
                    a: {
                      fontSize: 12,
                      width: 50,
                      color: \'rgba(51, 51, 51, 0.6)\'
                    },
                    b: {
                      fontSize: 12,
                      width: 40,
                      color: \'#333\'
                    },
                    c: {
                      fontSize: 12,
                      width: 38,
                      color: \'#333\'
                    }
                  }
                }
              },
              tooltip: {
                trigger: \'item\',
                formatter: \'{a} <br/>{b} : {c} ({d}%)\'
              },
              series: [
                {
                  name: \'任务状态\',
                  type: \'pie\',
                  radius: [\'40%\', \'55%\'], // 第一项是内半径,第二项是外半径,内半径为0就是真的饼,不是环形
                  center: [\'30%\', \'50%\'], // 位置
                  label: {
                    normal: {
                      show: false, // 是否显示标签[ default: false ]
                      position: \'outside\', // 标签的位置。\'outside\'饼图扇区外侧,通过视觉引导线连到相应的扇区。\'inside\',\'inner\' 同 \'inside\',饼图扇区内部。\'center\'在饼图中心位置。
                      formatter: function(params) {
                        return (
                          \'{c|\' +
                          params.value +
                          \'}  {d|\' +
                          params.percent +
                          \'%}\\n{b|\' +
                          params.name +
                          \'}\'
                        )
                      },
                      fontFamily: \'PingFangSC-Regular\',
                      lineHeight: 20,
                      padding: [0, -55],
                      rich: {
                        c: {
                          color: \'#333333\',
                          fontSize: 14,
                          align: \'left\',
                          padding: [0, 0, 0, 10]
                        },
                        d: {
                          color: \'#333333\',
                          align: \'left\',
                          fontSize: 14
                        },
                        b: {
                          color: \'rgba(51, 51, 51, 0.6)\',
                          fontSize: 14,
                          align: \'left\',
                          padding: [0, 0, 0, 10]
                        }
                      }
                    }
                  },
                  labelLine: {
                    // 标签的视觉引导线样式,在 label 位置 设置为\'outside\'的时候会显示视觉引导线。
                    normal: {
                      show: false, // 是否显示视觉引导线。
                      length: 20, // 在 label 位置 设置为\'outside\'的时候会显示视觉引导线。
                      length2: 40, // 视觉引导项第二段的长度。
                      lineStyle: {
                        // 视觉引导线的样式
                        //color: \'#000\',
                        //width: 1
                      }
                    }
                  },
                  data: taskStateData,
                  itemStyle: {
                    emphasis: {
                      shadowBlur: 10,
                      shadowOffsetX: 0,
                      shadowColor: \'rgba(0, 0, 0, 0.5)\'
                    }
                  }
                }
              ]
            },
            true //这个参数有它的作用
          )
        }
        this.taskLoading = false
      })
    }

其中,用到了一个函数statusColorHandle,这个是根据具体的状态分配颜色值的,这里做了封装:

statusColorHandle(state, colorArr) {
  state = ~~state
  return colorArr[state % colorArr.length]
},

这是其中一个,另外一个基本类似,下面是实现的效果图:
Echart饼图实现(圆环图)+状态颜色控制
代码里添加了很多注释,方便自己查阅,分享给大家,希望大家在用到的时候遇到问题了可以作为参考。

本文来自网络整理,转载请注明原出处:https://segmentfault.com/a/1190000021592713

展开阅读全文

发表评论

登录后才能评论