Echarts 饼图的创新绘制技巧(附 Demo 和源码)

大家好,我是 前端架构师 - 大卫

初心为助前端人🚀,进阶路上共星辰✨,

您的点赞👍与关注❤️,是我笔耕不辍的灯💡。

更多优质内容,欢迎关注我的微信公众号 @前端大卫,一起探索前端技术的无限可能!

背景

Echarts 是前端开发中常用的可视化库,很多人都用过。但你是否遇到过这样的情况:当某个数据项的 value 值过小时(比如 Apple 的值为 1),饼图的渲染效果会显得不太理想,影响数据的可读性。

例如,下面的代码:

js 复制代码
option = {
  series: [{
    type: "pie",
    data: [
      { value: 1, name: "Apple" },
      { value: 50, name: "Grapes" },
      { value: 100, name: "Pineapples" }
    ]
  }]
}

渲染结果如下,可以看到 Apple 这一项几乎看不到:

在线示例代码

codesandbox.io/p/sandbox/m...

解决方案

我们可以通过 叠加多个圆 来调整 value 的值,使得小数据项在视觉上更加明显,同时仍然保留真实值的展示。例如最终的效果如下:

接下来,我们详细讲解实现步骤。

具体实现

1. 给数据项增加 realValue 属性

默认情况下,Echarts 需要的数据格式如下:

js 复制代码
type ChartDataItem = {
  name: string;
  value: number;
}[];

为了解决 value 过小的问题,我们可以增加 realValue 字段,代表真实数值,而 value 用于调整视觉效果。

js 复制代码
type ChartDataItem = {
  name: string;
  value: number;
  realValue: number;
}[];

2. 计算调整后的 value

value 需要在 realValue 的基础上做一定的调整,以保证视觉效果不会太过失真。例如,我们可以让 value 增加最大值的一半,使其更加均衡。

核心数据处理逻辑如下:

js 复制代码
const normalizeChartData = (data: ChartDataItem) => {
  const maxValue = Math.max(...data.map((item) => item.value));
  const adjustmentValue = Math.round(maxValue * 0.5);

  return data.map((item) => ({
    name: item.name,
    realValue: item.value,
    value: item.value === 0 ? 0 : item.value + adjustmentValue,
  }));
};

data 最终调整成 processedData

js 复制代码
const data = [
  { value: 1, name: "Apple" },
  { value: 50, name: "Grapes" },
  { value: 100, name: "Pineapples" }
];

const processedData = normalizeChartData(data);

3. 使用 formatter 仅展示 realValue

我们可以利用 formatter 让 Echarts 只展示 realValue,而不是修改后的 value,代码如下:

js 复制代码
{
  name: "数据饼图",
  type: "pie",
  roseType: "area",
  label: {
    show: true,
    position: "inside",
    formatter: (params) => {
      return `{styleRich|${params.data.realValue}}`;
    },
    rich: {
      styleRich: {
        fontSize: 16,
        color: "#FFF",
      },
    },
  },
  data: processedData,
}

4. 添加外边框

如果 value0,可以通过绘制一个透明的外边框来增强视觉层次感:

js 复制代码
{
  name: "外边框",
  type: "pie",
  radius: outerBorderRadius,
  itemStyle: {
    borderWidth: 1,
    borderColor: "#2985e0",
    color: "transparent",
  },
  data: [{ value: 0 }],
}

渲染效果如下:

5. 添加标签引导线

引导线可以让用户更容易理解数据项的名称。

js 复制代码
{
  name: "标签引导线",
  type: "pie",
  roseType: "area",
  itemStyle: {
    color: "transparent",
  },
  label: {
    position: "outside",
    fontSize: 16,
    color: "#fff",
    formatter: "{b}",
  },
  labelLine: {
    length: 0,
    length2: 0,
    lineStyle: {
      width: 1,
      type: "solid",
      color: "#5bbffe",
    },
  },
  data: processedData,
}

渲染效果如下:

6. 添加中心圆

在中心增加一个固定的文本,例如 fruits,增强整体美观性。

js 复制代码
{
  name: "中心黑色圆",
  type: "pie",
  itemStyle: {
    color: "rgba(0,0,0,0.6)",
  },
  label: {
    position: "center",
    formatter: "{styleRich|fruits}",
    rich: {
      styleRich: {
        fontSize: 15,
        lineHeight: 18,
        color: "#FFF",
      },
    },
  },
  data: [{ value: 0 }],
}

总结

在 Echarts 饼图中,当某个数据项的 value 过小时,会导致其几乎不可见。为了解决这个问题,我们可以:

  1. 使用 realValue 记录真实数据,value 进行视觉调整,避免过小数据项难以识别。
  2. 利用 formatter 仅展示 realValue真实的值,确保用户看到的是正确的数据。
  3. 增加外边框和引导线,提高视觉层次感和可读性。
  4. 添加中心圆,让整体图表更加美观。

这样,我们不仅可以让小数据项清晰可见,还能保持数据的真实性,使得图表既有视觉冲击力,又不失专业性。

在线demo和源码

codesandbox.io/p/devbox/sa...

相关推荐
augenstern41615 分钟前
webpack重构优化
前端·webpack·重构
海拥✘18 分钟前
CodeBuddy终极测评:中国版Cursor的开发革命(含安装指南+HTML游戏实战)
前端·游戏·html
寧笙(Lycode)1 小时前
React系列——HOC高阶组件的封装与使用
前端·react.js·前端框架
asqq81 小时前
CSS 中的 ::before 和 ::after 伪元素
前端·css
拖孩1 小时前
【Nova UI】十五、打造组件库之滚动条组件(上):滚动条组件的起步与进阶
前端·javascript·css·vue.js·ui组件库
苹果电脑的鑫鑫1 小时前
element中表格文字剧中可以使用的属性
javascript·vue.js·elementui
Hejjon1 小时前
Vue2 elementUI 二次封装命令式表单弹框组件
前端·vue.js
一丝晨光2 小时前
数值溢出保护?数值溢出应该是多少?Swift如何让整数计算溢出不抛出异常?类型最大值和最小值?
java·javascript·c++·rust·go·c·swift
小堃学编程2 小时前
前端学习(3)—— CSS实现热搜榜
前端·学习
Wannaer2 小时前
从 Vue3 回望 Vue2:响应式的内核革命
前端·javascript·vue.js