首页/文章/echarts

ECharts柱状图相关功能点

2024-03-05
1122 字约 4 分钟
...

highlight: a11y-dark theme: cyanosis

记录一下在公司遇到的一些功能,以及相关实现

经过之前环形图需求,对ECharts的使用感觉已经非常熟练了,这次写柱状图的时候就快了很多。

在这里还是力推一下这个ECharts图表集,大部分的灵感都来自于这 ^_^

echarts图表集

等会讲具体功能的时候,也会将一些具体的案例提供给大家

柱状样式

首先,我给大家提供一种柱状图样式,个人感觉不错,而且实现也很简单

看着很酷,实现也很简单,只需要改变一下柱状的color即可,改为渐变色

我取巧,弄了种很简单的方式

{
	option.color: [{
    return {
      type: 'linear',
      x: 0,
      y: 0,
      x2: 0,
      y2: 1,
      colorStops: [
        {
          offset: 0,
          color: '#21B8FA' 
        },
        {
          offset: 0.8,
          color: '#21B8FA' + '00'
        }
      ]
    }
  }]
}

可以看到,在颜色后面加00即可,也就是透明度大小,换成另一种形式,大家可能看着更熟悉,

#21B8FA → rgb(33,184,250),而加00就是,#21B8FA00 → rgba(33,184,250, 0)

接下来我们来看具体功能点吧

柱状类型

有个配置项,是设置柱状类型的,有两个选项

  • 方形
  • 子弹头

效果如下

这个很容易实现,通过配置项即可

属性为:seriesitemStyle.borderRadius

borderRadius: 5, 
borderRadius: [5, 5, 0, 0] 

所以方向很明确了,直接设置为[9999, 9999, 0, 0]即可

最终实现效果

顶部装饰

效果如下

也是有两种实现方式,一种是通过再加一个series去实现,把所有的点换成图片即可

使用的是散点图,我的理解是没有折线的折线图

    const headDecoratorSeries = {
      silent: true,
      animation: false,
      type: 'scatter',
      symbol: `image://${url}`,
      symbolSize: [width, height],
      symbolOffset: [offsetX, offsetY],
      label: {
        show: false
      },
      itemStyle: undefined
    }

然后利用symbolSize和symbolOffset来控制大小和偏移去实现的

另一种方式是通过label的rich属性去实现的,也就是给label添加一个样式,样式里添加背景图片,并控制大小和偏移,具体代码如下

    seriesItem.label.formatter = '{bg|{c}}'
    seriesItem.label.rich = {
      bg: {
        align: 'center',
        backgroundColor: {
          image: url
        },
        width: width,
        height: height,
        padding: [offsetX, offsetY]
      }
    }

为了性能上的取舍,最终选中了用label的rich去实现的

最终实现效果

提示框

效果如下

这边的话,主要就是去自定义tooltip的formatter,去自己重新写一个提示框来满足该效果,然后注意系列颜色啥的就好了,其他没啥

我把其中的HTML内容抽离出来

item HTML

    <div style="display: flex;justify-content: space-between;align-items: center;">
      <p style="margin: 0;">
        <span style="display: inline-block;margin-right:5px;width: 10px;height: 10px;border-radius: 50%;background-color: ${param.color.colorStops[0].color}"></span>
        ${param.seriesName}
      </p>
      <span>${param.value}</span>
    </div>

return HTML

    <div style="border-radius: 5px;box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);width: ${width}px;height: ${height}px;transform: translate(${offsetX}px, ${offsetY}px);background: url(url);">
      <p style="margin: 0; margin-bottom: 2px;font-family: inherit;">
        ${params[0].axisValueLabel}
      </p>
      <div style="display: flex;flex-direction: column;gap: '1px';font-family: inherit;">
        ${item}
      </div>
    </div>

最终内容

    props.option.tooltip.formatter = params => {
        const item = params.reduce(
          (sum, param) =>
            sum +
            `
          <div style='display: flex;justify-content: space-between;align-items: center;'>
            <p style='margin: 0;'>
              <span style='display: inline-block;margin-right:5px;width: 10px;height: 10px;border-radius: 50%;background-color: ${param.color.colorStops[0].color}'></span>
              ${param.seriesName}
            </p>
            <span>${param.value}</span>
          </div>`,
          ''
        )

        return `
          <div style="border-radius: 5px;box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
            width: ${width}px;height: ${height}px;transform: translate(${offsetX}px, ${offsetY}px);
    				background: `url(${url}) 50% 50% / 100% 100% no-repeat`;
    			>
            <p style='margin: 0; margin-bottom: 2px;font-family: inherit;'>
              ${params[0].axisValueLabel}
            </p>
            <div style="display: flex;flex-direction: column;gap: '1px';font-family: inherit;">
              ${item}
            </div>
          </div>
    	  `
      }

里面包括了设置背景图片、宽高、偏移等功能

最终实现效果

去除提示框自带的阴影效果

首先给tooltip提供一个className

    option.tooltip.className = 'echarts-tooltip'

然后用CSS样式设置一下即可

    
    .echarts-tooltip {
      box-shadow: unset !important;
    }

提示框动画

效果如下

如果看过我之前那篇文字的同学,可能会对这里很熟悉,实现的方式是一样的,只是同时多了个显示提示框的功能

这里我就直接附上代码了,有兴趣的可以去看我的上一篇文章

    const timer = useRef<NodeJS.Timer>()
    const currentIndex = useRef<number>(0)

    const resetSelect = () => {
      eChartInstance.current?.dispatchAction({
        type: 'downplay',
        seriesIndex: 0
      })
    }

    const selectSector = () => {
      eChartInstance.current?.dispatchAction({
        type: 'highlight',
        seriesIndex: 0,
        dataIndex: currentIndex.current
      })
      eChartInstance.current?.dispatchAction({
        type: 'showTip',
        seriesIndex: 0,
        dataIndex: currentIndex.current
      })
    }

    
    const rotatingAnimation = () => {
      if (props.tooltip.isActive) {
        clearInterval(timer.current)
        timer.current = setInterval(() => {
          const dataLen = eChartOption.current?.series[0].data.length ?? 0
          currentIndex.current = (currentIndex.current + 1) % dataLen
          resetSelect()
          selectSector()
        }, props.tooltip.duration * 1000)
      } else {
        resetSelect()
      }
    }

    useEffect(() => {
      rotatingAnimation()

      return () => {
        clearInterval(timer.current)
      }
    }, [props.tooltip])

这边的实现会比环形图简单不少,少了一些功能

最终实现效果

水球图

这次的内容比较少,所以我就把刚做的这个需求也添加到这次的文章里了 ^_^

实现效果

参考案例

echarts图表集

看着确实非常酷炫,实现其实也很简单,echarts没有,但有一个这个水球图插件扩展

安装

    npm install echarts
    npm install echarts-liquidfill

引入

    import * as echarts from 'echarts';
    import 'echarts-liquidfill'

使用

    option = {
      backgroundColor: 'transparent',
      series: [{
        type: 'liquidFill',
        radius: '72%',
        data: [0.6, 0.6, 0.6],
        backgroundStyle: {
          color: 'transparent'
        },
        label: {
          show: false
        },
        outline: {
          show: false
        },
        color: [convertColor(color)]
      }]
    }

其中文字的话,我是额外附加的,放到一个div里面去处理的

还有一个就是背景图片了,需要根据图表位置进行调整和偏移

最终将其抽离为一个组件,遍历3次即可得到该效果

最终实现效果

好了,今天的内容点就到这里啦🎉🎉🎉 ^_^

如果您觉得这篇文章有帮助,请点个赞吧~

分享文章

相关文章

更多文章 →
八股文2026-07-30
一、TypeScript与类型系统(20题)
1\. 在定义AI接口返回的嵌套数据结构(如多轮对话、工具调用结果)时,如何用TypeScript的泛型与条件类型实现灵活的类型推导? 场景:为“AI助手”定义统一的消息类型系统,需兼容不同模型供应商(OpenAI/Anthropic)及内部(Moonshot)的返回格式。 核心答案: 构建一个以泛型为基础、条件类型为分支的层次化类型系统。核心是利用泛型参数化“消息内容”、“工具调用”和“提供商”,再通过条件类型精确匹配不同场景下的数据...
学习
godot2026-07-27
Godot 4 常用 UI 节点详解
Godot 4 常用 UI 节点详解 在 Godot 4 中,UI 系统基于 Control(控件) 节点构建。所有 UI 节点都继承自 Control,形成一棵完整的 UI 树。与游戏引擎中常见的"Canvas + DOM"模式不同,Godot 的 UI 系统是声明式的——你在场景中搭好节点树,引擎自动完成布局计算。 一、布局系统:Container 家族 Container 是 Godot UI 的 骨架 。它决定了子节点的大小和位...
学习
cocos2026-07-22
🎯 Cocos Creator 生命周期详解
Cocos Creator 生命周期详解 一、前言 Cocos Creator 作为主流的游戏开发引擎,其组件化架构的核心就是 生命周期回调函数 。理解这些回调的触发时机、执行顺序和使用场景,是写出高质量游戏逻辑的基础。 本文基于 Cocos Creator 3.x ,系统梳理从引擎启动到场景切换、从节点创建到销毁的完整生命周期。 二、组件生命周期回调总览 Cocos Creator 的生命周期回调按触发顺序排列如下: | 回调函数 |...
学习
cocos2026-07-22
🚀 Cocos Creator 新手入门指南
一、Cocos Creator 是什么 Cocos Creator 是一款专注于 2D 和 3D 游戏开发的引擎,由 Cocos 团队开发。它的核心理念是 组件化开发 ——把游戏中的每个功能拆成独立的组件,像搭积木一样组合起来。 主要特点 : 完全免费,支持发布到 Web、iOS、Android、桌面等多平台 使用 TypeScript 编写脚本,对前端开发者非常友好 编辑器可视化操作,所见即所得 内置资源管理、动画系统、UI 系统、物...
学习
前端2026-07-17
HTML Form 可以把 POST 响应加载进 iframe
在接入支付验证、身份认证或第三方授权页面时,我们经常会遇到这样的流程: 1. 后端返回一个第三方接口地址。 2. 这个地址必须通过 请求访问。 3. 接口返回 HTML,或者重定向到真正的验证页面。 4. 验证页面需要嵌入当前网站,而不是打开新标签页。 5. 验证完成后,当前页面继续执行后续业务。 第一次遇到这个需求,很容易想到: 但涉及第三方支付时,这种方式通常会遇到 CORS、Cookie、重定向和跨域页面读取限制。 实际上,HTM...
学习
godot2026-07-09
Godot 4 自动地形系统(AutoTileSet / Terrains)完全指南
前言 在 2D 游戏开发中,地形瓦片(tile)的拼接是一个绕不开的问题。想象一下:你有一片草地、一条河流、一段平台——如果每一块边缘、角落、过渡区域都要手动选择对应的瓦片图,工作量将是巨大的。 自动地形系统 就是为了解决这个问题而生的。 一、什么是自动地形(Autotiling)? 自动地形的核心思想很简单: 你只管画,引擎帮你选对瓦片 。 当你在 TileMap 上绘制地形时,引擎会自动检测每个瓦片的上下左右邻居,然后根据预设的规则...
学习

评论

请登录后发表评论

去登录
加载评论中...

目录