0
点赞
收藏
分享

微信扫一扫

Echarts-legend自定义

上古神龙 2022-03-22 阅读 101
前端

实现效果图如下

在这里插入图片描述

  • html代码
  <!-- echarts-pie -->
      <div class="fd-pie-chart" id="fd-pie-chart"></div>
      <!-- echarts-legend -->
      <div class="fd-pie-legend">
        <div
          class="fd-legend-item"
          v-for="(item, index) in pieData"
          :key="index"
        >
          <div class="fd-legend-name">
            <div
              class="fd-legend"
              :style="{
                background: `linear-gradient(0deg, ${pieColors[index].start} 0%, ${pieColors[index].end} 100%)`,
              }"
            ></div>
            <div class="fd-name">{{ item.name }}</div>
          </div>
          <div class="fd-legend-data">
            <div class="fd-num">{{ million(item.value) }}件</div>
            <div class="fd-prc">
              {{ getPercentValue(valueList, index, 2) }}%
            </div>
          </div>
        </div>
      </div>
  • js代码
 // 饼图数据
            pieData: [{
                value: 0,
                name: 'namee'
            },
            {
                value: 0,
                name: 'name'
            },
            {
                value: 0,
                name: 'name'
            },
            {
                value: 0,
                name: 'name'
            },
            {
                value: 0,
                name: 'name'
            },
            {
                value: 0,
                name: 'name'
            },
            {
                value: 0,
                name: 'name'
            },
            {
                value: 0,
                name: 'name'
            },
            {
                value: 0,
                name: '其他'
            }
            ],
// 饼图颜色
            pieColors: [{
                start: '#005BCE',
                end: '#009FFF'
            }, {
                start: '#03AA93',
                end: '#20CFBA'
            }, {
                start: '#10BFF0',
                end: '#00A3D1'
            }, {
                start: '#FFBA00',
                end: '#FE7700'
            }, {
                start: '#667A9E',
                end: '#8AA3C9'
            }, {
                start: '#073c2a',
                end: '#30e9a4'
            }, {
                start: '#AFA4F2',
                end: '#8C79F0'
            }, {
                start: '#FF7C48',
                end: '#FF8758'
            }, {
                start: '#FA4D40',
                end: '#FF897B'
            }],
// 初始化饼图
        initPieChart() {
        	//饼图颜色渐变
            const colorXsjc = new this.$echarts.graphic.LinearGradient(0, 1, 0, 0, [{
                offset: 0,
                color: '#005BCE'
            }, {
                offset: 1,
                color: '#009FFF'
            }], false);
            const colorGyss = new this.$echarts.graphic.LinearGradient(0, 1, 0, 0, [{
                offset: 0,
                color: '#03AA93'
            }, {
                offset: 1,
                color: '#20CFBA'
            }], false);
            const colorMsjc = new this.$echarts.graphic.LinearGradient(0, 1, 0, 0, [{
                offset: 0,
                color: '#10BFF0'
            }, {
                offset: 1,
                color: '#00A3D1'
            }], false);
            const colorWj = new this.$echarts.graphic.LinearGradient(0, 1, 0, 0, [{
                offset: 0,
                color: '#FFBA00'
            }, {
                offset: 1,
                color: '#FE7700'
            }], false);
            const colorXzjc = new this.$echarts.graphic.LinearGradient(0, 1, 0, 0, [{
                offset: 0,
                color: '#667A9E'
            }, {
                offset: 1,
                color: '#8AA3C9'
            }], false);
            const colorZj = new this.$echarts.graphic.LinearGradient(0, 1, 0, 0, [{
                offset: 0,
                color: '#073c2a'
            }, {
                offset: 1,
                color: '#30e9a4'
            }], false);
            const colorKs = new this.$echarts.graphic.LinearGradient(0, 1, 0, 0, [{
                offset: 0,
                color: '#AFA4F2'
            }, {
                offset: 1,
                color: '#8C79F0'
            }], false);
            const colorJcjs = new this.$echarts.graphic.LinearGradient(0, 1, 0, 0, [{
                offset: 0,
                color: '#FF7C48'
            }, {
                offset: 1,
                color: '#FF8758'
            }], false);
            const colorQt = new this.$echarts.graphic.LinearGradient(0, 1, 0, 0, [{
                offset: 0,
                color: '#FA4D40'
            }, {
                offset: 1,
                color: '#FF897B'
            }], false);
            this.myChart = this.$echarts.init(document.getElementById('fd-pie-chart'));
            this.myChart.clear();
            const option = {
                tooltip: {
                    trigger: 'item',
                    formatter: function (params) {
                        const str = `<div class="fd-pie-name">${params.name}</div>
                               <div  class="fd-pie-data">
                                <div>${params.value}件</div>
                                <div>${params.percent}%</div>
                               </div> `;
                        return str;
                    }
                },
                color: [colorXsjc, colorGyss, colorMsjc, colorWj, colorXzjc, colorZj, colorKs, colorJcjs, colorQt],
                series: [{
                    type: 'pie',
                    radius: ['50%', '80%'],
                    center: ['50%', '50%'],
                    avoidLabelOverlap: false,
                    label: {
                        show: false,
                        position: 'center'
                    },
                    emphasis: {label: {show: false}},
                    labelLine: {show: false},
                    data: this.pieData
                }, {
                    name: '背景线',
                    silent: true,
                    type: 'pie',
                    radius: ['80%', '85%'],
                    center: ['50%', '50%'],
                    label: {show: false},
                    emphasis: {
                        scale: false,
                        label: {show: false}
                    },
                    itemStyle: {
                        label: {show: false},
                        labelLine: {show: false},
                        borderWidth: 5
                    },
                    data: [{
                        value: 100,
                        itemStyle: {
                            color: 'rgba(242, 244, 247,1)',
                            borderWidth: 0
                        },
                        hoverAnimation: false
                    }]
                }]
            };
            this.myChart.setOption(option);
        },
 // 最大余额法(自定义图例比例,使用此方法,保证与echarts饼图计算比例一致性)
        getPercentValue(valueList, idx, precision) {
            // 判断是否为空
            if (!valueList[idx]) {
                return 0;
            }
            // 求和
            const sum = valueList.reduce(function (acc, val) {
                return acc + (isNaN(val) ? 0 : val);
            }, 0);
            if (sum === 0) {
                return 0;
            }
            // 10的2次幂是100,用于计算精度。
            const digits = Math.pow(10, precision);
            // 扩大比例100,
            const votesPerQuota = valueList.map(function (val) {
                return (isNaN(val) ? 0 : val) / sum * digits * 100;
            });
            // 总数,扩大比例意味的总数要扩大
            const targetSeats = digits * 100;
            // 再向下取值,组成数组
            const seats = votesPerQuota.map(function (votes) {
                return Math.floor(votes);
            });
            // 再新计算合计,用于判断与总数量是否相同,相同则占比会100%
            let currentSum = seats.reduce(function (acc, val) {
                return acc + val;
            }, 0);
            // 余数部分的数组:原先数组减去向下取值的数组,得到余数部分的数组
            const remainder = votesPerQuota.map(function (votes, idx) {
                return votes - seats[idx];
            });
            // 给最大最大的余额加1,凑个占比100%;
            while (currentSum < targetSeats) {
                //  找到下一个最大的余额,给其加1
                let max = Number.NEGATIVE_INFINITY;
                let maxId = null;
                for (let i = 0, len = remainder.length; i < len; ++i) {
                    if (remainder[i] > max) {
                        max = remainder[i];
                        maxId = i;
                    }
                }
                // 对最大项余额加1
                ++seats[maxId];
                // 已经增加最大余数加1,则下次判断就可以不需要再判断这个余额数。
                remainder[maxId] = 0;
                // 总的也要加1,为了判断是否总数是否相同,跳出循环。
                ++currentSum;
            }
            // 这时候的seats就会总数占比会100%
            return seats[idx] / digits;
        },
         // 过万处理(防止数据过大情况,图例展示不开)
million(value) {
            let num;
            if (value > 99999) { // 大于9999显示x.xx万
                num = `${(Math.floor(value / 100) / 100).toFixed(1)}万`;
            } else if (value <= 99999) {
                num = value;
            }
            return num;
        }
举报

相关推荐

0 条评论