场景:

渲染饼图时,lengend中的百分比,自己根据 val/total计算得出的结果和series内label自动渲染的不一样。

示例:

image.png

解决方法:

/**
 * 获取给定精度的数据,确保valueList中的百分比之和为1
 * 采用最大余数法
 * @param {number[]} valueList 所有数据的列表
 * @param {number} idx 数据的索引
 * @param {number} precision 精度
 * @return {number} 百分数
 */
export function getPercentWithPrecision(valueList, idx, precision) {
  if (!valueList[idx]) {
    return 0
  }

  var sum = valueList.reduce(function(acc, val) {
    return acc + (isNaN(val) ? 0 : val)
  }, 0)
  if (sum === 0) {
    return 0
  }

  var digits = Math.pow(10, precision)
  var votesPerQuota = valueList.map(val => {
    return ((isNaN(val) ? 0 : val) / sum) * digits * 100
  })
  var targetSeats = digits * 100

  var seats = votesPerQuota.map(votes => Math.floor(votes))
  var currentSum = seats.reduce(function(acc, val) {
    return acc + val
  }, 0)

  var remainder = votesPerQuota.map((votes, idx) => votes - seats[idx])

  // Has remainding votes.
  while (currentSum < targetSeats) {
    // Find next largest remainder.
    var max = -Infinity //Number.NEGATIVE_INFINITY;
    var maxId = null
    for (var i = 0, len = remainder.length; i < len; ++i) {
      if (remainder[i] > max) {
        max = remainder[i]
        maxId = i
      }
    }

    // Add a vote to max remainder.
    ++seats[maxId]
    remainder[maxId] = 0
    ++currentSum
  }

  return seats[idx] / digits
}

所有代码

<template>
  <div class="pie-chart" ref="pieChart"></div>
</template>
<script>
let myCharts = null
import { getPercentWithPrecision } from '@/utils/util'
export default {
  props: {
    typeLable: {
      type: String,
      default: ''
    }
  },
  data() {
    return {
      myCharts: null,
      option: {},
      title: '分级统计图',
      chartsData: []
    }
  },
  mounted() {
    if (this.chartsData?.length) {
      this.initCharts()
    }
  },
  methods: {
    setData(data, title) {
      this.chartsData = data
      this.title = title + '分级统计图'
      this.initCharts()
    },
    getPercentWithPrecision,
    initCharts() {
      let that = this
      let legendData = []
      let seriesData = []
      let valueData = []

      this.chartsData.forEach(item => {
        legendData.push(item.gradeName)
        valueData.push(item.wellCount)
        seriesData.push({ name: item.gradeName, value: item.wellCount })
      })
      this.option = {
        tooltip: {
          // borderWidth: 4.5,
          trigger: 'item',
          formatter: '{a} <br/>{b} : {c} ({d}%)'
        },
        title: {
          left: 'center',
          bottom: '6%',
          text: this.title
        },
        color: ['#8fc31f', '#f35833', '#cca4e3', '#00ccff', '#ffcc00', '#0c8918', '#ffa400', '#815476', '#177cb0'],
        legend: {
          orient: 'vertical',
          // x: 'right',
          right: '10%',
          y: 'center',
          data: legendData,
          borderColor: '#8C8D8E',
          borderWidth: 1,
          borderRadius: 4,
          padding: [20, 10],
          formatter: name => {
            // let totalNum = 0
            // totalNum = seriesData.reduce(function(sum, cur, index, arr) {
            //   return sum + cur.value
            // }, 0)
            for (var i = 0; i < seriesData.length; i++) {
              let pre = getPercentWithPrecision(valueData, i, 2)
              if (name == seriesData[i].name) {
                return name + '     ' + seriesData[i].value + '     ' + pre + '%'
              }
            }
          }
        },

        series: [
          {
            name: '分级统计图',
            type: 'pie',
            radius: '55%',
            center: ['40%', '50%'],
            data: seriesData,
            // [
            //   { value: 335, name: '准时' },
            //   { value: 310, name: '迟到' },
            //   { value: 234, name: '请假' },
            //   { value: 135, name: '未到' }
            // ],
            itemStyle: {
              emphasis: {
                shadowBlur: 10,
                shadowOffsetX: 0,
                shadowColor: 'rgba(0, 0, 0, 0.5)'
              }
            },
            itemStyle: {
              borderWidth: 1,
              borderColor: '#333',
              normal: {
                label: {
                  borderColor: '#8C8D8E',
                  borderWidth: 1,
                  borderRadius: 4,
                  padding: [4, 10, 2],
                  show: true,
                  //                                position:'inside',
                  formatter: '{b} : {c} ({d}%)'
                }
              },
              labelLine: { show: true }
            }
          }
        ]
      }
      this.myCharts = this.$echarts.init(this.$refs.pieChart)
      this.myCharts.clear()
      this.myCharts.setOption(this.option)
      myCharts = this.myCharts
      window.onresize = function() {
        myCharts.resize()
      }
    }
  }
}
</script>
<style lang="less" scoped>
.pie-chart {
  height: calc(100vh - 281px);
  min-height: 688px;
  // border: 1px solid red;
}
</style>

云胡不喜
73 声望11 粉丝

前端的忠实粉丝