您现在的位置是:网站首页 > 饼图(Pie Chart)实现文章详情

饼图(Pie Chart)实现

饼图(Pie Chart)实现

饼图是一种常见的数据可视化形式,通过扇形区域的大小直观展示各部分在整体中的占比关系。ECharts提供了丰富的配置项来实现各种风格的饼图,从基础展示到复杂的交互效果都能轻松应对。

基础饼图实现

最简单的饼图只需要指定系列类型为'pie'并提供相应的数据即可:

option = {
  title: {
    text: '某站点用户访问来源',
    subtext: '纯属虚构',
    left: 'center'
  },
  tooltip: {
    trigger: 'item',
    formatter: '{a} <br/>{b}: {c} ({d}%)'
  },
  legend: {
    orient: 'vertical',
    left: 'left',
    data: ['直接访问','邮件营销','联盟广告','视频广告','搜索引擎']
  },
  series: [
    {
      name: '访问来源',
      type: 'pie',
      radius: '50%',
      data: [
        {value: 335, name: '直接访问'},
        {value: 310, name: '邮件营销'},
        {value: 234, name: '联盟广告'},
        {value: 135, name: '视频广告'},
        {value: 1548, name: '搜索引擎'}
      ],
      emphasis: {
        itemStyle: {
          shadowBlur: 10,
          shadowOffsetX: 0,
          shadowColor: 'rgba(0, 0, 0, 0.5)'
        }
      }
    }
  ]
};

这段代码创建了一个标准的饼图,包含标题、图例和提示框。radius属性控制饼图的大小,设置为'50%'表示占据容器宽度的一半。

环形饼图

通过设置radius为数组可以实现环形饼图效果:

series: [{
  type: 'pie',
  radius: ['40%', '70%'],
  data: [
    {value: 1048, name: '搜索引擎'},
    {value: 735, name: '直接访问'},
    {value: 580, name: '邮件营销'},
    {value: 484, name: '联盟广告'},
    {value: 300, name: '视频广告'}
  ]
}]

这里radius的第一个值表示内半径,第二个值表示外半径。通过调整这两个值可以控制环形的宽度。

南丁格尔玫瑰图

roseType设置为'area'可以创建南丁格尔玫瑰图:

series: [{
  type: 'pie',
  radius: [30, 120],
  roseType: 'area',
  data: [
    {value: 10, name: 'rose1'},
    {value: 5, name: 'rose2'},
    {value: 15, name: 'rose3'},
    {value: 25, name: 'rose4'},
    {value: 20, name: 'rose5'},
    {value: 35, name: 'rose6'},
    {value: 30, name: 'rose7'},
    {value: 40, name: 'rose8'}
  ]
}]

玫瑰图通过扇区的半径长度来展示数值大小,适合展示大量分类数据的对比。

多级饼图

通过嵌套多个饼图系列可以实现多级饼图效果:

series: [
  {
    type: 'pie',
    radius: ['0%', '30%'],
    label: {show: false},
    data: [
      {value: 335, name: 'A类'},
      {value: 310, name: 'B类'},
      {value: 234, name: 'C类'}
    ]
  },
  {
    type: 'pie',
    radius: ['40%', '70%'],
    data: [
      {value: 135, name: 'A1'},
      {value: 148, name: 'A2'},
      {value: 52, name: 'A3'},
      {value: 210, name: 'B1'},
      {value: 100, name: 'B2'},
      {value: 134, name: 'C1'},
      {value: 100, name: 'C2'}
    ]
  }
]

内层饼图展示大类数据,外层展示详细分类,形成层次关系。

自定义标签样式

饼图的标签可以通过label属性进行高度自定义:

series: [{
  type: 'pie',
  radius: '55%',
  center: ['50%', '60%'],
  data: [
    {value: 335, name: '直接访问'},
    {value: 310, name: '邮件营销'},
    {value: 234, name: '联盟广告'},
    {value: 135, name: '视频广告'},
    {value: 1548, name: '搜索引擎'}
  ],
  label: {
    color: '#333',
    formatter: '{b}: {c} ({d}%)',
    fontSize: 14,
    fontWeight: 'bold',
    lineHeight: 22,
    rich: {
      a: {
        color: '#999',
        lineHeight: 22
      },
      hr: {
        borderColor: '#aaa',
        width: '100%',
        borderWidth: 0.5,
        height: 0
      }
    }
  },
  labelLine: {
    lineStyle: {
      color: 'rgba(0, 0, 0, 0.3)'
    },
    smooth: 0.2,
    length: 10,
    length2: 20
  }
}]

label.formatter支持字符串模板和回调函数两种形式,rich属性可以定义富文本样式。

交互效果增强

ECharts饼图支持丰富的交互效果:

series: [{
  type: 'pie',
  selectedMode: 'single',
  selectedOffset: 30,
  avoidLabelOverlap: false,
  emphasis: {
    scale: true,
    scaleSize: 10,
    label: {
      show: true,
      fontSize: '20',
      fontWeight: 'bold'
    }
  },
  data: [
    {value: 335, name: '直接访问'},
    {value: 310, name: '邮件营销', selected: true},
    {value: 234, name: '联盟广告'},
    {value: 135, name: '视频广告'},
    {value: 1548, name: '搜索引擎'}
  ]
}]

selectedMode控制选中模式,emphasis定义高亮样式,selected可以预设选中状态。

动态数据更新

饼图支持动态数据更新,实现动画效果:

let data = [
  {value: 335, name: '直接访问'},
  {value: 310, name: '邮件营销'},
  {value: 234, name: '联盟广告'},
  {value: 135, name: '视频广告'},
  {value: 1548, name: '搜索引擎'}
];

let option = {
  series: [{
    type: 'pie',
    data: data
  }]
};

// 定时更新数据
setInterval(function() {
  data = data.map(item => {
    return {
      name: item.name,
      value: item.value * (0.9 + Math.random() * 0.2)
    };
  });
  myChart.setOption({
    series: [{
      data: data
    }]
  });
}, 2000);

自定义图形样式

通过itemStyle可以完全自定义饼图的图形样式:

series: [{
  type: 'pie',
  radius: '55%',
  itemStyle: {
    color: function(params) {
      const colorList = ['#c23531','#2f4554','#61a0a8','#d48265','#91c7ae'];
      return colorList[params.dataIndex];
    },
    borderColor: '#fff',
    borderWidth: 2,
    shadowBlur: 10,
    shadowColor: 'rgba(0, 0, 0, 0.3)',
    borderRadius: 5
  },
  data: [
    {value: 335, name: '直接访问'},
    {value: 310, name: '邮件营销'},
    {value: 234, name: '联盟广告'},
    {value: 135, name: '视频广告'},
    {value: 1548, name: '搜索引擎'}
  ]
}]

颜色可以使用回调函数根据数据索引动态分配,borderRadius可以创建圆角效果。

大数据量优化

当数据量较大时,可以通过以下方式优化性能:

series: [{
  type: 'pie',
  radius: '55%',
  data: largeData,
  large: true,
  largeThreshold: 1000,
  progressive: 400,
  animation: false,
  label: {
    show: false
  }
}]

largelargeThreshold启用大数据模式,progressive控制渐进渲染的块大小,关闭动画和标签可以进一步提升性能。

与其他图表组合

饼图可以与其他图表类型组合使用:

option = {
  tooltip: {
    trigger: 'axis',
    axisPointer: {type: 'shadow'}
  },
  legend: {
    data: ['利润', '支出', '收入']
  },
  grid: {
    left: '3%',
    right: '4%',
    bottom: '3%',
    containLabel: true
  },
  xAxis: {
    type: 'value'
  },
  yAxis: {
    type: 'category',
    data: ['周一','周二','周三','周四','周五','周六','周日']
  },
  series: [
    {
      name: '利润',
      type: 'bar',
      data: [200, 170, 240, 244, 200, 220, 210]
    },
    {
      name: '收入',
      type: 'pie',
      radius: [0, '30%'],
      center: ['75%', '25%'],
      data: [
        {value: 335, name: '直接访问'},
        {value: 310, name: '邮件营销'},
        {value: 234, name: '联盟广告'},
        {value: 135, name: '视频广告'},
        {value: 1548, name: '搜索引擎'}
      ]
    }
  ]
};

这个例子将柱状图和饼图组合在一起,通过centerradius控制饼图的位置和大小。

事件处理

ECharts饼图支持丰富的事件交互:

myChart.on('click', function(params) {
  console.log(params);
});

myChart.on('mouseover', function(params) {
  console.log('鼠标悬停在'+params.name);
});

myChart.on('globalout', function() {
  console.log('鼠标移出图表区域');
});

可以通过事件回调实现点击扇形跳转、显示详细信息等交互功能。

主题定制

ECharts内置了多种主题,也可以自定义主题:

// 使用内置dark主题
echarts.init(dom, 'dark');

// 自定义主题
let myTheme = {
  color: ['#dd6b66','#759aa0','#e69d87','#8dc1a9','#ea7e53'],
  backgroundColor: '#f5f5f5',
  textStyle: {},
  title: {
    textStyle: {color: '#333'},
    subtextStyle: {color: '#aaa'}
  }
};
echarts.registerTheme('myTheme', myTheme);
echarts.init(dom, 'myTheme');

主题可以统一控制图表的颜色、背景、文字等样式属性。

服务端渲染

对于Node.js环境,可以使用node-echarts实现服务端渲染:

const echarts = require('echarts');
const { createCanvas } = require('canvas');

// 创建canvas实例
const canvas = createCanvas(800, 600);
const chart = echarts.init(canvas);

// 设置选项
chart.setOption({
  series: [{
    type: 'pie',
    data: [
      {value: 335, name: 'A'},
      {value: 310, name: 'B'},
      {value: 234, name: 'C'}
    ]
  }]
});

// 输出图片
const buffer = canvas.toBuffer('image/png');
require('fs').writeFileSync('pie.png', buffer);

这种方式适合生成静态图表图片用于邮件、报告等场景。

移动端适配

针对移动设备需要进行特殊适配:

option = {
  series: [{
    type: 'pie',
    radius: ['30%', '70%'],
    label: {
      fontSize: (window.innerWidth / 20) + 'px'
    },
    labelLine: {
      length: window.innerWidth > 500 ? 15 : 5,
      length2: window.innerWidth > 500 ? 30 : 10
    },
    data: pieData
  }]
};

通过检测屏幕宽度动态调整字体大小和标签线长度,确保在小屏幕上也能清晰显示。

无障碍访问

为提升可访问性,可以添加ARIA属性:

series: [{
  type: 'pie',
  data: [
    {
      value: 335, 
      name: '直接访问',
      itemStyle: {color: '#c23531'},
      aria: {
        label: '直接访问占比26.7%'
      }
    }
    // 其他数据...
  ],
  aria: {
    enabled: true,
    label: {
      description: '这是一个饼图,展示了不同访问来源的占比情况'
    }
  }
}]

这些属性可以帮助屏幕阅读器用户理解图表内容。

我的名片

网名:~川~

岗位:console.log 调试员

坐标:重庆市-九龙坡区

邮箱:cc@qdcc.cn

沙漏人生

站点信息

  • 建站时间:2013/03/16
  • 本站运行
  • 文章数量
  • 总访问量
微信公众号
每次关注
都是向财富自由迈进的一步