首页/文章/echarts

ECharts柱状图相关功能点

2024-03-05
11224 分钟
...

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即可,也就是透明度大小,换成另一种形式,大家可能看着更熟悉,

#21B8FArgb(33,184,250),而加00就是,#21B8FA00rgba(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
    }

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

另一种方式是通过labelrich属性去实现的,也就是给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次即可得到该效果

最终实现效果

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

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

分享文章

相关文章

更多文章 →
AI2026-09-01
Deep Agents 01:何为 Agent Harness,以及如何开始
1、本篇任务:完成一份多步骤、带证据的技术调研 普通客服 Agent 的问题短、工具少、输出即时。技术调研或编码任务会持续很久,产生计划、搜索结果、文件和中间结论。Deep Agents 在 LangChain/LangGraph 之上预装规划、虚拟文件系统、上下文压缩和子 Agent,适合这类开放任务。 本课让 Agent 比较两种向量数据库,并交付一份可验证报告。 2、什么时候需要 Deep Agent 满足以下两项以上再考虑:任务...
学习
AI2026-09-01
Deep Agents 02:子 Agent、虚拟文件系统与长期记忆
1、本篇任务:让主管只看结论,让子 Agent 处理细节 技术调研会产生几十次搜索和大量文件。如果全部进入主管上下文,真正的目标会被噪音淹没。本课用两个子 Agent: 收集证据, 检查结论;主管负责计划与最终合成。 2、什么时候委派,什么时候直接调用工具 适合委派:子任务有多步;需要专门提示或工具;会产生大量中间结果;只需返回有限结论。不适合:一步查询;主管需要全部中间上下文;协调成本超过任务本身。 3、配置专门子 Agent Pyt...
学习
AI2026-09-01
Deep Agents 03:生产化、Sandbox、权限与上线验收
1、本篇任务:让 Deep Agent 在隔离环境中分析代码 只读研究 Agent 风险有限;编码 Agent 需要读写文件、安装依赖和执行测试。本课不讲如何让模型写更漂亮的代码,只讲执行环境、权限、恢复和上线验收。 2、先做威胁模型 资产包括源代码、用户文件、云凭证、生产网络和发布权限;攻击入口包括用户消息、仓库内容、网页、依赖包、MCP 返回和命令输出。 Prompt injection 不是靠一句 system prompt 解决...
学习
AI2026-09-01
LangChain 01:全景、原理与学习路线
1、本篇学完要得到什么 这一篇只解决三个问题:LangChain 到底负责什么;它与 LangGraph、Deep Agents、LangSmith 是什么关系;后面应按什么顺序学习。 贯穿整套课程的项目是“退款政策与订单助手”。它最终能够:回答知识库中的退款规则;查询当前用户的订单;生成结构化答复;对真正的退款操作进行人工审批;断线后恢复;通过评测后发布。 先记住一句话: 模型负责理解与生成,应用负责数据、权限、状态和副作用。 如果把...
学习
AI2026-09-01
LangChain 02:模型、消息与结构化输出
1、本篇任务:让模型输出成为程序可以依赖的合同 上一课只证明 Agent 能运行。本课暂时不接业务工具,只完成一个“客服分诊器”:输入用户问题,输出意图、紧急程度、是否需要人工和给用户的答复。 本课的核心不是学更多模型参数,而是理解三层合同:消息决定模型看到了什么;schema 决定程序期待什么;业务校验决定结果是否真的可用。 2、消息不是一段字符串,而是一条执行记录 一次工具型对话通常包含四种消息: | 类型 | 由谁产生 | 作用...
学习
AI2026-09-01
LangChain 03:工具与 Agent——从函数到可控行动
1、本篇任务:让 Agent 安全地读取订单 上一课得到结构化分诊结果,但模型不知道真实订单。本课增加一个只读工具 ,走通完整 Agent 循环,并把模型、工具包装和领域服务的责任分开。 完成后,用户问“我的 A100 发货了吗”,Agent 会选择工具;工具只按当前登录用户查询;模型基于工具结果回答。它仍然不能退款,因为我们没有提供写工具。 2、工具的本质是受 schema 约束的应用函数 一个好工具需要:稳定名称、清楚描述、窄输入...
学习

评论

请登录后发表评论

去登录
加载评论中...

目录