【Echarts】电池状进度条

使用象形柱状图能够实现很多有意思的效果,这里用象形柱状图实现进度条效果,实现效果如下:

前置知识

基准柱

象形柱图可以被想象为:它首先是个柱状图,但是柱状图的柱子并不显示。这些柱子我们称为『基准柱(reference bar)』,根据基准柱来定位和显示各种象形图形(包括图片)。

每个象形图形根据基准柱的定位,是通过 symbolPosition、symbolOffset 来调整其于基准柱的相对位置。

symbolSize

symbolSize 表示图形的大小。

可以用数组分开表示宽和高,例如 [20, 10] 表示标记宽为 20,高为 10,也可以设置成诸如 10 这样单一的数字,表示 [10, 10]。

可以设置成绝对值(如 10),也可以设置成百分比(如 '120%'、['55%', 23])。

当设置为百分比时,图形的大小是基于基准柱的尺寸计算出来的。

例如,当基准柱基于 x 轴(即柱子是纵向的),symbolSize 设置为 ['30%', '50%'],那么最终图形的尺寸是:

宽度:基准柱的宽度 _ 30%。

高度:

如果 symbolRepeat 为 false:基准柱的高度 _ 50%。

如果 symbolRepeat 为 true:基准柱的宽度 * 50%。

基准柱基于 y 轴(即柱子是横向的)的情况类似对调可得出

此属性可以被设置在系列的 根部,表示对此系列中所有数据都生效;也可以被设置在 data 中的 每个数据项中,表示只对此数据项生效。代码示例如下:

js 复制代码
series: [{
  symbolSize: ... // 对 data 中所有数据项生效。
  data: [23, 56]
}]
或者
series: [{
  data: [{
    value: 23
    symbolSize: ... // 只对此数据项生效
    }, {
    value: 56
    symbolSize: ... // 只对此数据项生效
  }]
}]

symbolClip

symbolClip 表示是否剪裁图形,可选值如下:

false/null/undefined:图形本身表示数值大小。

true:图形被剪裁后剩余的部分表示数值大小。

symbolClip 常用在以下场景:同时表达『总值』和『当前数值』。在这种场景下,可以使用两个系列,一个系列是完整的图形,当做『背景』来表达总数值,另一个系列是使用 symbolClip 进行剪裁过的图形,表达当前数值。

『当前值系列』设置了比『背景系列』更高的 z,使得其覆盖在『背景系列』上。

此属性可以被设置在系列的 根部,表示对此系列中所有数据都生效;也可以被设置在 data 中的 每个数据项中,表示只对此数据项生效。代码示例如下:

js 复制代码
series: [{
  symbolClip: ... // 对 data 中所有数据项生效。
  data: [23, 56]
}]
或者
series: [{
  data: [{
    value: 23
    symbolClip: ... // 只对此数据项生效
    }, {
    value: 56
    symbolClip: ... // 只对此数据项生效
  }]
}]

symbolRepeat

symbolRepeat 用来设置图形元素是否重复。值可为:

false/null/undefined:不重复,即每个数据值用一个图形元素表示。

true:使图形元素重复,即每个数据值用一组重复的图形元素表示。重复的次数依据 data 计算得到。

a number:使图形元素重复,即每个数据值用一组重复的图形元素表示。重复的次数是给定的定值。

'fixed':使图形元素重复,即每个数据值用一组重复的图形元素表示。重复的次数依据 symbolBoundingData 计算得到,即与 data 无关。这在此图形被用于做背景时有用,symbolBoundingData 没有设置时按照基准柱的值来设置。 此属性可以被设置在系列的 根部,表示对此系列中所有数据都生效;也可以被设置在 data 中的 每个数据项中,表示只对此数据项生效。代码示例如下:

js 复制代码
series: [{
    symbolRepeat: ... // 对 data 中所有数据项生效。
    data: [23, 56]
}]
或者
series: [{
    data: [{
        value: 23
        symbolRepeat: ... // 只对此数据项生效
    }, {
        value: 56
        symbolRepeat: ... // 只对此数据项生效
    }]
}]

实现

设置背景

首先设置基础参数,因为是设置背景,种类需要设置的 z 为一个相对较小的值,代码示例及效果如下:

js 复制代码
series: [
    {
        type: "pictorialBar",
        animationDuration: 0,
        symbol: "rect",
        itemStyle: {
            normal: {
                color: "#EFEFEF",
            },
        },
        label: {
            normal: {
                show: true,
                position: "right",
                offset: [0, 2],
                distance: 30,
                textStyle: {
                    color: "#409EFF",
                    fontSize: 14,
                },
                formatter: function (a) {
                    return `${a.value}%`;
                },
            },
        },
        data: [90, 70, 80],
        z: 0,
        animationEasing: "elasticOut",
    },
];

此时的柱状图的宽度是均分的,可以通过设置 symbolSize 来调整大小,这里设置为[10, 20];通过设置 symbolRepeat 来设置图形元素是否重复及重复的类型,因为效果是类似电池的进度条,所以这里需要通过 symbolMargin 设置间隔,修改后的代码及效果如下:

js 复制代码
{
  // 背景
  type: "pictorialBar",
  animationDuration: 0,
  symbolRepeat: "fixed",
  symbolMargin: 2, // 背景间隔
  symbol: "rect",
  symbolSize: [10, 20],
  itemStyle: {
    normal: {
      color: "#EFEFEF",
    },
  },
  label: {
    normal: {
      show: true,
      position: "right",
      offset: [0, 2],
      distance: 30,
      textStyle: {
        color: "#409EFF",
        fontSize: 14,
      },
      formatter: function (a) {
        return `${a.value}%`;
      },
    },
  },
  data: [90, 70, 80],
  z: 0,
  animationEasing: "elasticOut",
},

设置真实值

真实值与设置背景基本类似,这里需要多设置一个 symbolClip,根据真实值来进行裁切,如果不设置 symbolClip,则会填满整个柱状图。代码示例及效果如下:

js 复制代码
{
  type: "pictorialBar",
  itemStyle: {
    color: {
      type: "linear",
      x: 0,
      y: 0,
      x2: 1,
      y2: 0,
      colorStops: [
        {
          offset: 0,
          color: "#1577FF", // 0% 处的颜色
        },
        {
          offset: 1,
          color: "#409EFF", // 100% 处的颜色
        },
      ],
    },
  },
  symbolRepeat: "fixed",
  symbolMargin: 2, // 背景间隔
  symbol: "rect",
  symbolSize: [10, 20],
  symbolClip: true,
  data: [90, 70, 80],
  z: 2,
  animationEasing: "elasticOut",
},

至此,电池进度柱状图完成。

代码地址:

stackblitz.com/edit/vitejs...

相关推荐
腾讯TNTWeb前端团队6 小时前
helux v5 发布了,像pinia一样优雅地管理你的react状态吧
前端·javascript·react.js
范文杰9 小时前
AI 时代如何更高效开发前端组件?21st.dev 给了一种答案
前端·ai编程
拉不动的猪9 小时前
刷刷题50(常见的js数据通信与渲染问题)
前端·javascript·面试
拉不动的猪9 小时前
JS多线程Webworks中的几种实战场景演示
前端·javascript·面试
FreeCultureBoy10 小时前
macOS 命令行 原生挂载 webdav 方法
前端
uhakadotcom10 小时前
Astro 框架:快速构建内容驱动型网站的利器
前端·javascript·面试
uhakadotcom11 小时前
了解Nest.js和Next.js:如何选择合适的框架
前端·javascript·面试
uhakadotcom11 小时前
React与Next.js:基础知识及应用场景
前端·面试·github
uhakadotcom11 小时前
Remix 框架:性能与易用性的完美结合
前端·javascript·面试
uhakadotcom11 小时前
Node.js 包管理器:npm vs pnpm
前端·javascript·面试