饼图数据过多时,图例分成左右两列对称展示,可滚动翻页

使用echarts实现饼图

  • 1.饼图数据过多时,图例分成左右两列对称展示,垂直居中,可滚动翻页;
  • 2.图例文字大于8个字显示省略号;
  • 3.给定颜色数组,手动按索引循环取色渲染饼图;
  • 4.自定义提示框;鼠标悬浮时显示;

效果图:

完整代码:

css 复制代码
let colors = [  '#D25486',  '#DE7070',  '#EEBE3F',  '#23B5FF',  '#0043CB',  '#00CFB5',  '#0EEDFE',  '#0E96FE',  '#345EBF',  '#038CB6',  '#00FFBD',  '#FFC000',  '#A823FF',  '#0868FB',  '#FFD700',  '#EE82EE',  '#FF6347',  '#008000',  '#BA55D3',  '#FFFF00',  '#9370DB',  '#3CB371',  '#FF4500',  '#FFA500',  '#6B8E23'];

let data = [  { name: '百年孤独', value: '76' },  { name: '时间简史', value: '34' },  { name: '国富论', value: '89' },  { name: '人类简史', value: '12' },  { name: '追风筝的人', value: '53' },  { name: '1984', value: '98' },  { name: '傲慢与偏见', value: '21' },  { name: '物种起源', value: '67' },  { name: '悲惨世界', value: '45' },  { name: '资本论', value: '3' },  { name: '小王子', value: '82' },  { name: '麦田里的守望者', value: '60' },  { name: '局外人', value: '77' },  { name: '存在与时间', value: '29' },  { name: '不能承受的生命之轻', value: '91' },  { name: '战争与和平', value: '14' },  { name: '安娜·卡列尼娜', value: '55' },  { name: '罪与罚', value: '38' },  { name: '尤利西斯', value: '72' },  { name: '洛丽塔', value: '9' },  { name: '了不起的盖茨比', value: '64' },  { name: '飘', value: '17' },  { name: '简爱', value: '86' },  { name: '老人与海', value: '41' },  { name: '哈姆雷特', value: '95' },  { name: '双城记', value: '7' },  { name: '鲁滨逊漂流记', value: '50' },  { name: '三体', value: '23' },  { name: '白夜行', value: '68' },  { name: '活着', value: '83' }];
const richStyle = {
  b: {
    width: 120
  }
};
let total = 0;
let leftLenged = [];
let rightLenged = [];
for (let i = 0; i < data.length; i++) {
  total = total + Number(data[i].value);
  if (i < data.length / 2) {
    leftLenged.push(data[i].name);
  } else {
    rightLenged.push(data[i].name);
  }
}
option = {
  // color:color不会循环取色,暂时注释,采用下文手动取色。
  // 原因:ECharts默认行为对饼图的颜色分配存在限制。
  //      当数据项较多时,默认会优先使用内置的全局调色盘而非自定义的 color 数组。
  // color:color,
  // 设置中间背景图,此处没有链接到图片暂时注释
  // graphic: {
  //   elements: [
  //     {
  //       type: 'image',
  //       z: -10,
  //       left: 'center',
  //       top: 'center',
  //       style: {
  //         image: require('../img/sample/bg.png'),
  //         width: 100,
  //         height: 100
  //       }
  //     }
  //   ]
  // },
  tooltip: {
    trigger: 'item',
    formatter: '{b} <br/> {c} 个({d}%)',
    backgroundColor: '#002260',
    borderColor: '#0984F3',
    borderWidth: 1,
    padding: [5, 15],
    textStyle: {
      color: '#fff'
    }
  },
  legend: [
    {
      x: 'left',
      type: 'scroll',
      orient: 'vertical',
      height: '50%',
      top: 'center',
      left: '10%',
      itemWidth: 10,
      itemHeight: 10,
      icon: 'rect',
      pageIconColor: '#2F6EE4',
      pageIconSize: 12,
      pageTextStyle: {
        color: '#fff'
      },
      textStyle: {
        fontSize: 14,
        color: '#fff',
        rich: richStyle,
        lineHeight: 16
      },
      data: leftLenged,
      tooltip: {
        show: true
      },
      formatter: function (name) {
        const oa = option.series[0].data;
        for (let i = 0; i < oa.length; i++) {
          if (name == oa[i].name) {
            return (
              '{b' +
              '|' +
              (name.length > 8 ? name.substr(0, 8) + '...' : name) +
              '}' +
              '{style' +
              i +
              '|' +
              oa[i].value +
              '本}'
            );
          }
        }
      }
    },
    {
      x: 'right',
      type: 'scroll',
      orient: 'vertical',
      height: '50%',
      top: 'center',
      left: '68%',
      itemWidth: 10,
      itemHeight: 10,
      icon: 'rect',
      pageIconColor: '#2F6EE4',
      pageIconSize: 12,
      pageTextStyle: {
        color: '#fff'
      },
      textStyle: {
        fontSize: 14,
        color: '#fff',
        rich: richStyle,
        lineHeight: 16
      },
      data: rightLenged,
      tooltip: {
        show: true
      },
      formatter: function (name) {
        const oa = option.series[0].data;
        for (let i = 0; i < oa.length; i++) {
          if (name == oa[i].name) {
            return (
              '{b' +
              '|' +
              (name.length > 8 ? name.substr(0, 8) + '...' : name) +
              '}' +
              '{style' +
              i +
              '|' +
              oa[i].value +
              '本}'
            );
          }
        }
      }
    }
  ],
  series: [
    {
      type: 'pie',
      radius: ['32%', '45%'],
      center: ['50%', '50%'],
      itemStyle: {
        // 手动按索引循环颜色
        color: (params) => {
          return colors[params.dataIndex % colors.length];
        },
        borderColor: 'rgb(16, 12, 42)',
        borderWidth: 1
      },
      labelLine: {
        show: false
      },
      label: {
        show: true,
        position: 'center',
        formatter: () => {
          return `\n{${'bM'}|总数量 ` + total + `}`;
        },
        rich: {
          bM: {
            fontSize: 18,
            color: ' #fff'
          }
        }
      },
      data: data
    }
  ]
};
相关推荐
拉不动的猪1 小时前
vue与react的简单问答
前端·javascript·面试
污斑兔1 小时前
如何在CSS中创建从左上角到右下角的渐变边框
前端
星空寻流年1 小时前
css之定位学习
前端·css·学习
旭久2 小时前
react+antd封装一个可回车自定义option的select并且与某些内容相互禁用
前端·javascript·react.js
是纽扣也是烤奶2 小时前
关于React Redux
前端
阿丽塔~2 小时前
React 函数组件间怎么进行通信?
前端·javascript·react.js
冴羽2 小时前
SvelteKit 最新中文文档教程(17)—— 仅服务端模块和快照
前端·javascript·svelte
uhakadotcom3 小时前
Langflow:打造AI应用的强大工具
前端·面试·github
前端小张同学3 小时前
AI编程-cursor无限使用, 还有谁不会🎁🎁🎁??
前端·cursor