简介:ECharts柱状图-柱图16.rar是一份面向网页开发者和数据分析人员的ECharts柱状图学习案例,适合在统计分析、数据对比与大屏可视化场景中快速搭建可交互图表。压缩包共3个文件,包含2个JavaScript脚本和1个HTML页面,整体仅864KB,轻量易用,其中JS文件承载图表配置与交互逻辑,HTML页面用于直接运行演示。资源基于ECharts 5.5.0构建,内置SVG、geo等常用配置,用户可重点学习如何调整柱状图的大小、颜色、间隔、标签、图例、工具箱、提示框等高级定制选项,也能通过鼠标悬停、缩放和平移等交互方式深入探索数据。同时可熟悉setOption、showLoading、hideLoading、resize等核心API,掌握图表数据更新、加载状态控制和自适应尺寸等实际操作。目前已有66人学习下载,对刚接触ECharts或需要在项目中快速实现柱状图展示的开发者来说,是一份小巧而实用的参考资源。
1. 打开 ECharts 柱状图资源包前,先确认你拖进页面的是模板还是配置思路
很多同事从网盘拿到「ECharts柱状图-柱图16.rar」这类编号命名的压缩包,解压之后通常是一套 HTML、一段内联 JS 和一组写死的示例数据。复制进项目里改几个数字,图表能显示,但类目一多就开始挤成细线,间距怎么调都不对,于是怀疑是资源包版本太老。真正的差异往往不在版本,而在没有把压缩包里的内容拆成「模板结构」和「配置参数」两层来对待。柱状图是 ECharts 里最基础的系列类型,但围绕它至少有五种变体:普通柱图、堆叠柱、横向柱图、柱线混合图、带缩放窗的密集柱图。拿到编号资源包后先确认业务落在哪种变体里,再去改 series 和坐标轴,半小时能完成原本拖一下午的工作。本文按这条路径,从最小可运行模板推进到可直接交付的交互柱状图。
2. ECharts 柱状图最小工程:引入方式、坐标轴分工与 setOption 更新
2.1 解压 .rar 后先确认 echarts 全局对象能不能拿到
资源包的文件结构无非三种:单 HTML、单 JS、HTML 加若干分号拼接的配置片段。不管哪种,第一件事是打开浏览器控制台执行console.log(window.echarts),确认全局命名空间存在。ECharts 5.x 的全局对象是echarts,返回undefined通常是脚本加载顺序问题——jquery 项目里常见的是把 echarts.min.js 放在页面底部,却在头部 script 块里直接调用echarts.init,此时浏览器还没执行到那行加载代码。
另一个检查点是版本。ECharts 4 和 5 的 API 大体兼容,但 4.x 的itemStyle.borderRadius只支持数字,不支持四元素数组;dataZoom的滚轮行为也有细微差异。拿不准版本时,去百度 ECharts 官网的示例页跑一组相同配置,可以快速区分是自己配置写错还是版本能力覆盖不到。
<script src="https://cdn.jsdelivr.net/npm/echarts@5/dist/echarts.min.js"></script> <script> if (window.echarts) { console.log('ECharts 版本:', echarts.version); } </script>echarts.version返回类似'5.4.3'的字符串,可以和官网发布时间交叉核对。实际项目里如果版本低于 5.0,建议优先升级,因为 4.x 在多层嵌套对象的setOption合并上偶尔会出现字段覆盖不完整的问题,这种 bug 在堆叠柱状图里尤其隐蔽。
2.2 柱状图最小运行模板:init 和容器尺寸的耦合关系
第一个柱状图跑通需要的最少代码很短,但有一个隐藏前提:容器必须拥有有效的宽度和高度。ECHarts init 时如果容器clientWidth是 0,图表只渲染出坐标轴刻度线,柱体区域全是空白。资源包里自带的 HTML 通常写着width: 100%; height: 480px;,迁到后台管理系统局部区域后,如果父容器用了 flex 布局且没有min-height,高度会被压缩成 0。
const chartDom = document.getElementById('chart'); const myChart = echarts.init(chartDom); const option = { xAxis: { type: 'category', data: ['一月', '二月', '三月'] }, yAxis: { type: 'value' }, series: [{ type: 'bar', data: [120, 200, 150] }] }; myChart.setOption(option);echarts.init接收一个 HTMLElement 作为挂载点,不传主题参数时使用亮色默认主题。xAxis.type = 'category'声明横轴为类目轴,处理「一月」「二月」这类离散文本;yAxis.type = 'value'声明纵轴为数值轴,ECharts 根据series.data最大值自动计算刻度范围。注意后端接口返回的数字如果被 JSON 序列化成字符串'120',图表不会报错但数值排序会错乱,清洗数据阶段尽量把该字段Number()转回数值类型。
2.3 类目轴与数值轴的分工:横向柱状图的轴角色互换
坐标轴是柱状图信息表达的核心。类目轴回答「是什么」,数值轴回答「是多少」。默认纵向柱图把类目放 x 轴、数值放 y 轴,适合宽度大于高度的报表区块。当类目名超过 8 个汉字时,横向柱图可读性明显更好,因为文本在 y 轴方向可以完整展开,不会被 x 轴宽度截断成省略号。
option = { xAxis: { type: 'value' }, yAxis: { type: 'category', data: ['华东', '华北', '华南'], inverse: true }, series: [{ type: 'bar', data: [320, 250, 410], label: { show: true, position: 'right' } }] };类目轴从 xAxis 换到 yAxis 之后,柱体由纵向变为横向。inverse: true让第一个类目出现在 y 轴顶部,符合多数后台报表从上方开始阅读的习惯,不加这个参数时类目顺序从底部排起。series.label开启柱端数值标签,position: 'right'将数值放在柱体右侧,横向柱图里也可以取'inside',数值较小时放柱体内部更紧凑。
| 坐标轴配置项 | 作用域 | 典型取值 | 适用场景 |
|---|---|---|---|
xAxis.axisLabel.rotate | 类目轴文字倾斜角度 | 30 / 45 | 长类目名避免文字重叠 |
yAxis.axisLabel.formatter | 类目文字格式化 | '{value} 件' | 在轴刻度上追加单位 |
grid.left | 绘图区左边距 | 70(像素) | 横向柱图预留 y 轴文字空间 |
axisLine.lineStyle.color | 轴线颜色 | '#e5e5e5' | 深色大屏主题 |
splitLine.lineStyle.type | 背景网格线型 | 'dashed' | 弱化网格视觉干扰 |
轴角色互换后要同步调整grid.left:纵向柱图的 y 轴数值标签通常只有三到四位数字,80px 足够;横向柱图的 y 轴类目名如果超过 10 个字符,grid.left需要撑到 140px 以上,否则类目文本被截断后很难看出是哪条数据。
2.4 setOption 的增量合并:ajax 拉数据不重建图表
资源包里如果写的是myChart.setOption(option)一次性铺满配置,数据变化时新手会调用clear()再重新 init,导致交互状态全部丢失。ECharts 的setOption默认采用合并语义:传入对象中未声明的字段沿用上次值,声明过的字段按路径覆盖。
fetch('/api/sales') .then(res => res.json()) .then(data => { myChart.setOption({ series: [{ data: data.values }], xAxis: { data: data.categories } }); });这段代码只更新series[0].data和xAxis.data,柱子的颜色、图例、tooltip 配置全部保持初始值。注意setOption对 series 按数组下标匹配,初始配置中的 series 是对象而不是数组时,ECharts 会自动包装成单元素数组,后续传入数组即可。每次请求返回后不要销毁实例,这种思路就是「原生 js、jquery、ajax、echarts 结合制作网页」时最核心的性能设计,反复请求可以避免重绘整块 canvas 的额外开销。
3. 柱状图 series 参数调优:柱宽、圆角、多系列间距与堆叠归组
3.1 柱宽与圆角:barMaxWidth 的显式控制和大屏适配
默认柱宽由绘图区宽度和类目数量共同决定,类目 5 个时柱子宽度约 60px,类目 50 个时柱宽会掉到 5px 以下。数据可视化大屏上如果类目数量是动态的,推荐用barMaxWidth而不是barWidth做硬约束:类目少时柱子被限制在合理宽度内,类目变多时还能自动压缩,不会出现柱子互相重叠。
series: [{ type: 'bar', barMaxWidth: 40, itemStyle: { borderRadius: [6, 6, 0, 0], color: '#4f8ff7' } }]itemStyle.borderRadius四个值按「左上、右上、右下、左下」顺时针排列。顶部导圆角的柱体在大屏项目中很常见,比直角柱柔和,但圆角过大会造成「柱子实际高度比视觉短」的错觉,一般控制在柱宽的四分之一以内。如果要实现单柱渐变,把color换成linearGradient对象,渐变方向0, 0, 0, 1表示从柱顶到柱底。
// 渐变柱体写法 itemStyle: { color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ { offset: 0, color: '#5fb2ff' }, { offset: 1, color: '#2f6ed6' } ]) }offset是渐变止点位置,0 对应柱顶、1 对应柱底。两个色值之间可以插入多个中间色,常用于表示数值高低的状态区分。注意整个option配置对象可以是 JSON,但linearGradient必须由 echarts 提供的类创建,因此在线 JSON 编辑工具里没法直接用这种方式。
3.2 多系列并排:barGap 与 barCategoryGap 的联动效应
series 数组里出现两个type: 'bar'系列时,ECharts 会在同一个类目下并排渲染。控制间距的参数有两个:barGap控制同一类目下不同系列之间的空隙,默认'30%';barCategoryGap控制相邻类目之间的空隙,默认'20%'。两个值都是相对该类别总宽的百分比,改其中一个会影响整体疏密。
option = { xAxis: { type: 'category', data: ['Q1', 'Q2', 'Q3'] }, yAxis: { type: 'value' }, series: [ { name: '订单量', type: 'bar', data: [320, 332, 301] }, { name: '完成量', type: 'bar', data: [180, 220, 240] } ] };默认状态下两组柱子之间有约 30% 柱宽的空隙,类目之间有约 20% 空隙,视觉上「组内紧、组间松」。若两组柱子几乎粘在一起,增大barGap到'40%';若类目之间过松导致图表横向占不满,调小barCategoryGap。实际排错时先调barCategoryGap,因为它影响的整体布局更宏观,barGap只在同一类目下生效。
| 参数 | 默认值 | 语义 | 调大后的视觉变化 |
|---|---|---|---|
barGap | '30%' | 同系列柱间空隙宽度相对于柱宽 | 同组柱子分离更明显 |
barCategoryGap | '20%' | 类目区块之间空隙宽度相对于类目宽 | 相邻组间距加大,整体变疏 |
barWidth | null | 显式指定柱宽像素或百分比 | 柱子变粗,直到与类目宽冲突 |
barMaxWidth | null | 柱宽上限 | 类目少时柱子不无限增粗 |
3.3 堆叠柱的 stack 归组与 null 数据陷阱
堆叠柱的语义是「每一段代表整体的一部分」。配置只需要在每个 series 里加一个stack字段,值相同即归入同一栈。stack 的字符串取值没有业务含义,统一命名为'total'最省心,避免后续加系列时还要想一套不同的分组名。
series: [ { name: '新增', type: 'bar', stack: 'total', data: [320, 332, 301] }, { name: '活跃', type: 'bar', stack: 'total', data: [120, 132, 101] }, { name: '流失', type: 'bar', stack: 'total', data: [80, 62, 91] } ]三段 series 设同一个stack之后,图例会显示三条色带,柱子总高度是三者之和。生产环境最常见的故障是接口返回的数组顺序不一致:某个类目下「活跃」缺失,前端map得到的不是 0 而是undefined,转成 JSON 后变成null。堆叠柱遇到null会跳过这个段位,柱体中间出现一个向下的缺口,视觉上看着像数据断层。处理方式是清洗阶段对每个类目补 0 而不是 null,0 同样不占用柱体高度,但能保证 series 数据长度对齐。
3.4 柱状图叠加折线图:双 y 轴与 splitLine 冲突
柱线混合图是数据大屏的高频形态,柱体表达量级,折线表达趋势。最容易踩的坑是两个系列量纲差异过大,折线被压缩成贴顶部的直线,完全看不出波动。解决方案是启用双 y 轴,把折线系列绑定到第二套坐标轴上。
option = { xAxis: { type: 'category', data: ['1月', '2月', '3月'] }, yAxis: [ { type: 'value', name: '销售额(万)' }, { type: 'value', name: '增长率(%)', splitLine: { show: false } } ], series: [ { name: '销售额', type: 'bar', data: [820, 932, 901] }, { name: '增长率', type: 'line', yAxisIndex: 1, data: [12, 18, 22] } ] };yAxis 数组中的第一项下标为 0,第二项下标为 1。柱状图系列不写yAxisIndex时默认绑第 0 个轴,折线系列显式指定yAxisIndex: 1。第二个 y 轴的splitLine.show = false必须写,否则背景网格会在柱状图基础上再叠加一套横线,深浅两色错位,大屏暗色背景时非常脏。折线系的smooth: true会让曲线更柔和,lineStyle.width保持默认 2px 即可,太宽的折线会盖住柱子,影响数据读取。
4. 柱状图交互实战:click 下钻、tooltip 格式化与 dataZoom 缩放
4.1 鼠标点哪儿看哪儿:click 事件先过滤空白区域
「鼠标点那儿在哪儿显示柱状图」的场景,本质是点击某个区域后图表切换到对应维度的数据。ECharts 的on('click')事件回调里包含componentType、seriesType、name、value等字段。图表容器内的空白区域也会触发 click,所以第一步必须做过滤。
myChart.on('click', (params) => { if (params.componentType !== 'series' || params.seriesType !== 'bar') return; fetch('/api/detail?category=' + encodeURIComponent(params.name)) .then(res => res.json()) .then(data => { myChart.setOption({ xAxis: { data: data.months }, series: [{ data: data.values }] }); }); });componentType === 'series'保证只有柱体本身响应点击,网格空白处会被忽略。params.name是类目的原始文本,拼进 URL 时必须encodeURIComponent,否则类目名带斜杠或中文时后端会解析错误。下钻之后如果要返回上一级,可以把父级数据缓存到闭包变量里,点击返回按钮时用setOption重新铺回主数据,不必重新 init。
| 回调字段 | 含义 | 典型使用方式 |
|---|---|---|
params.name | 类目文本 | 用作下钻请求参数 |
params.value | 当前柱体的数值 | 判断阈值或写入日志 |
params.seriesName | 所属系列名 | 多系列图表区分来源 |
params.dataIndex | 类目在 data 中的下标 | 定位原始数据行 |
params.event.event.stop | 事件对象 | 需要阻断默认行为时用 |
4.2 tooltip 格式化与 label 的信息密度控制
多系列柱状图的默认 tooltip 会把所有系列逐行列出,字段名较长时浮层横向撑得太宽。用formatter函数重组文本,入参是触发轴上的全部系列信息数组。
tooltip: { trigger: 'axis', formatter: (params) => { return params.map(p => `${p.seriesName}:${p.value} 台`).join('<br/>'); } }params数组中每个元素的seriesName对应系列名,value对应当前类目下的数值。返回的字符串支持 HTML 标签,<br/>用于换行。这是 ECharts 5 的默认 HTML 渲染模式,模板字符串里的用户自定义文本必须转义,防止意外插入脚本。trigger: 'axis'适合比较连续 x 轴刻度上的多个系列,类目名称特别长时用trigger: 'item'只显示鼠标悬停的那一根柱体,信息更聚焦。
柱体上的 label 也需要控制密度。类目 12 个以内建议直接用label: { show: true, position: 'top' };类目超过 20 个时柱体变窄,顶部标签互相压字,此时要么开启axisLabel.rotate旋转 x 轴文字,要么关闭柱体 label 让 tooltip 承担数值读数功能。
4.3 dataZoom:类目数量失控之前加缩放保底
单图超过 30 个类目时柱子被压成细条,这时第一反应不应该是调小barMaxWidth,而是加dataZoom组件。dataZoom 有inside和slider两种类型,前者绑定滚轮和拖拽,后者在图表底部渲染一条可拖动的缩放条。
dataZoom: [ { type: 'inside', start: 0, end: 40 }, { type: 'slider', bottom: 10, height: 22 } ]start和end控制初始显示区间的百分比,0到40表示展示前 40% 的类目。inside 类型会拦截滚轮事件,页面本身需要纵向滚动时容易冲突,可以只保留 slider 或者给 inside 加zoomOnMouseWheel: false仅用拖拽平移。大屏场景下 slider 的bottom要和grid.bottom联动,避免缩放条压在 x 轴类目名上。类目超过 200 个时,dataZoom 的分段渲染是保证交互流畅度最直接的手段。
5. 把柱状图模板迁移到 vue3:ref 时序、resize 与三个验证点
5.1 vue3 里的 echarts.init 必须在 onMounted 之后执行
资源包里的原生 JS 模板迁移到 vue3,最常见的报错是Cannot read property 'init' of undefined,或者容器尺寸为 0。同一个根因:echarts.init执行时 DOM 尚未挂载到视图树。vue3 组合式 API 中初始化必须放进onMounted,并且通过ref拿到真实元素。
import * as echarts from 'echarts'; import { ref, onMounted, onBeforeUnmount } from 'vue'; const chartRef = ref(null); let chart; onMounted(() => { chart = echarts.init(chartRef.value); chart.setOption({ xAxis: { type: 'category', data: ['A', 'B', 'C'] }, yAxis: { type: 'value' }, series: [{ type: 'bar', data: [30, 45, 28] }] }); }); onBeforeUnmount(() => { chart.dispose(); });chartRef.value在onMounted阶段已经在模板中与ref="chartRef"的 div 绑定。dispose()释放事件监听和 canvas 上下文,组件卸载后不调用会导致内存里积累不可见的图表实例。vue3 echarts 生态里也有封装好的组件可以直接用,但手写这个模板更贴近资源包的原始结构,后续插入业务逻辑也更灵活。
5.2 交付前十分钟:resize 监听、series id 与 null 值压测
自检清单三条,顺序别打乱。第一条是resize:容器宽度变化时柱状图不会主动重绘,大屏分辨率切换后图表会拉伸变形。标准兜底写法加在初始化后:
window.addEventListener('resize', () => { chart.resize(); });第二条是series.id。多系列动态更新时 ECharts 对 series 的匹配规则是 id 优先、下标兜底。不写 id 时按下标依次替换,系列顺序一旦错位或新增一个系列,旧数据会残留在图表上。规范做法是初始配置里给每个系列加上稳定 id,例如id: 'order'、id: 'complete'。
第三条是 null 值压测。把数据源中某一项改成null,观察柱体是否断档、tooltip 是否异常;同时把barMaxWidth移除,测试类目 50 个时的压缩表现。这两个测试覆盖了从数据清洗到布局自适应的两条主要链路,跑完这两步,压缩包里那份「柱图16」才算是真正并入了工程。
本文还有配套的精品资源,点击获取