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

相关推荐
hrrrrb17 分钟前
【CSS3】筑基篇
前端·css·css3
boy快快长大20 分钟前
【VUE】day01-vue基本使用、调试工具、指令与过滤器
前端·javascript·vue.js
三原24 分钟前
五年使用vue2、vue3经验,我直接上手react
前端·javascript·react.js
嘉琪coder29 分钟前
React的两种状态哲学:受控与非受控模式
前端·react.js
木胭脂沾染了灰40 分钟前
策略设计模式-下单
java·前端·设计模式
Eric_见嘉44 分钟前
当敦煌壁画遇上 VS Code:我用古风色系开发了编程主题
前端·产品·visual studio code
青红光硫化黑1 小时前
React基础之项目创建
开发语言·javascript·ecmascript
拉不动的猪1 小时前
刷刷题28(http)
前端·javascript·面试