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...

相关推荐
coding随想1 小时前
JavaScript ES6 解构:优雅提取数据的艺术
前端·javascript·es6
年老体衰按不动键盘1 小时前
快速部署和启动Vue3项目
java·javascript·vue
小小小小宇1 小时前
一个小小的柯里化函数
前端
灵感__idea1 小时前
JavaScript高级程序设计(第5版):无处不在的集合
前端·javascript·程序员
小小小小宇1 小时前
前端双Token机制无感刷新
前端
小小小小宇1 小时前
重提React闭包陷阱
前端
小小小小宇2 小时前
前端XSS和CSRF以及CSP
前端
UFIT2 小时前
NoSQL之redis哨兵
java·前端·算法
超级土豆粉2 小时前
CSS3 的特性
前端·css·css3
星辰引路-Lefan2 小时前
深入理解React Hooks的原理与实践
前端·javascript·react.js