做前端数据可视化这几年我有个特别深的感受图表的“数据正确”只是及格线“看着舒服”才是加分项。而最容易被忽略又最影响观感的细节里坐标轴的 name 绝对排得上号。上周帮业务方调一个销售看板数据没问题但 x 轴那个“日期”孤零零地待在轴线最右端y 轴的“销售额万元”竖着戳在中间怎么看怎么别扭。业务方丢来一句“这俩字能挪一下吗”我就知道得把 ECharts 里 x 轴和 y 轴 name 的位置调整好好梳理一遍了。这篇文章把我实际用 ECharts 调整轴名称位置的经验完整写出来覆盖nameLocation、nameGap、nameRotate、nameTextStyle这几个核心参数再配合几个高频场景的配置模板和踩坑记录给正在做 echarts 数据可视化、尤其是经常跟折线图、柱状图轴标签较劲的朋友一个直接能抄的参考。无论你是刚接触 ECharts 的新手还是已经写了几年配置的老手这篇文章都能让你少翻几次文档。1. 先把坐标轴 name 的“人设”搞清楚1.1 name 到底是什么别和 axisLabel 搞混了很多第一次调轴名称的同学都会犯同一个错把 axisLabel 当成轴名称或者反过来。axisLabel 是坐标轴刻度旁边那个“具体的数值/分类文本”比如 x 轴上的周一、周二、周三y 轴上的 0、10、20而 name 是整根坐标轴的“名字”用来说明这个维度到底代表什么比如“星期”“销售额万元”。这两个东西的定位完全不同。axisLabel 跟着刻度走分布密集字体通常比较小name 只有一行是一个概括性的描述。改位置、改样式操作对象完全不一样。你在 axisLabel 上调 nameLocation 是无效的在 name 里改 formatter 也没反应。记住这句话axisLabel 管刻度文字name 管轴的名字两者不要混。最直观的区分方法用鼠标去点你觉得奇怪的文字如果它出现在每个刻度旁边那是 axisLabel如果只有孤零零一个词那基本就是 name。我调试时还有个习惯先把nameTextStyle.color设成一个醒目的红色值立刻就知道这行字归谁管了。1.2 默认位置为什么总觉得不对劲ECharts 的 xAxis 和 yAxis 都支持配置 name但如果你不显式设置 nameLocation不同主题、不同版本下name 的落点可能会让你摸不着头脑。从我实际使用的情况看x 轴的 name 默认往往落在轴线末端附近y 轴的 name 则是竖排落在轴线的中上段。单独看好像还好一旦图表有标题、有 legend、有网格这个默认位置就很容易跟其他元素挤在一起。所以我的建议很明确只要图表里要显示轴名称就别指望默认值把nameLocation、nameGap、nameTextStyle一起显式声明出来。这样在不同项目、不同主题下效果都是可控的。值得注意的是ECharts 的默认值在不同大版本之间是有过调整的我在升级图表库版本时经常遇到“明明代码没改name 位置却变了”的情况所以显式声明不单是为了美观更是为了可维护性。1.3 坐标轴家族的组件关系为了后面不绕晕先把坐标轴相关的一家人捋清楚。一张表就够了组件作用位置常用配置axisLine坐标轴轴线轴线位置lineStyle、onZeroaxisTick刻度线轴线两侧length、alignWithLabelaxisLabel刻度文字刻度旁interval、rotate、formattersplitLine分割线垂直/水平延伸lineStyle常用来隐藏name轴名称轴线两端或中间nameLocation、nameGap、nameTextStyle注意看name 在表格里和 axisLabel 是两行这说明它俩天然就是不同的配置域。调整位置核心就是围绕 name 那个配置块展开跟 axisLabel 基本无关。2. 四个核心参数拆解location、gap、rotate、textStyle2.1 nameLocation把名字放到轴线的哪个位置nameLocation 取值有start、middle、center、end。其中 middle 和 center 在多数版本里实际表现几乎一样都是居中。nameLocationx 轴效果y 轴效果典型场景start名称在左端名称在底部时间轴从左侧开始、数据从原点起步middle / center名称在中间名称在中间通用均衡布局end名称在右端名称在顶部销售趋势图名称随数据方向延伸到末端我见过很多需求是把 x 轴的“日期”挪到最左边把 y 轴的“销量件”挪到顶部。这两个都是典型的 start 和 end 场景。配置示例xAxis: { type: category, name: 日期, nameLocation: start }这里要注意一个细节x 轴的 start 是“轴线左端”y 轴的 start 是“轴线底端”方向跟坐标轴数值增长方向一致。如果某个轴配置了inverse: true数值反向start 和 end 的表现也会反过来容易踩坑。我有一次把流量数据的时间轴反向显示结果 x 轴名称“日期”从预期的最左端跑到最右端去了排查半天才想起是 inverse 导致的。2.2 nameGap控制名称与轴线的距离nameGap 数值单位是 px表示 name 与轴线之间的距离默认值约 15。如果觉得名称贴着轴线太挤调大到 30-40如果希望名称紧贴轴线调到 5 左右如果调成负数名称会跑到轴线另一侧。这招用来做特殊叠放效果时可以玩一下比如把 x 轴名称放到轴线上方。再补充一个经验nameGap 不是越大越好。它只控制 name 到轴线的距离不会自动帮你避让其他元素调大了 name 可能跑到图表内部去和其他内容重叠。所以调整时一定要配上 grid 的上下左右留白一起看效果。如果你发现加了 nameGap 之后图表区域变小了不用慌那是正常的它本质上是在轴线外侧挤占了一个文字槽位。2.3 nameRotate让长名称竖起来或者斜着站nameRotate 单位是角度不是弧度。0 表示不旋转-45 是向左旋转 45 度45 是向右旋转 45 度。最常见的用法是把 y 轴名称保持竖排默认竖排是自动的但如果你希望 x 轴的长名称不要横着占太多空间可以设置 nameRotate。不过我在实际项目中很少对 name 用 rotate因为 name 通常很短就几个字。真正需要旋转的是 axisLabel刻度文字。如果你发现刻度文字挤成一团那要去调axisLabel.rotate而不是 nameRotate。这个区分很重要写在这里给大家排个雷。2.4 nameTextStyle名字的颜色、字号能控到什么程度nameTextStyle 继承了 ECharts 文本样式的大部分能力color、fontSize、fontWeight、fontFamily、align、verticalAlign、lineHeight、padding甚至 backgroundColor、borderRadius、shadow 这些都能配。如果你希望轴名称和图表主色调配合就可以在这里统一处理。一个我常用的配置模板xAxis: { name: 日期, nameLocation: middle, nameGap: 30, nameTextStyle: { fontSize: 14, color: #333, fontWeight: bold, padding: [10, 0, 0, 0] } }padding 在 nameTextStyle 里很好用。比如 x 轴名称在中间下方时加一点上内边距让名称和轴线隔开比单调 nameGap 更可控。另外nameTextStyle 的 align 和 verticalAlign 在某些 nameLocation 组合下能微调文字的对齐方式比如 x 轴 name 在 end 位置时可以设置 align: right 让文字右缘对齐轴线端点。2.5 最小可用配置模板最后给一个可以直接粘贴的最小模板把 x 轴和 y 轴的 name 都显式声明option { xAxis: { type: category, data: [周一, 周二, 周三, 周四, 周五], name: 星期, nameLocation: middle, nameGap: 30, nameTextStyle: { fontSize: 14, color: #666 } }, yAxis: { type: value, name: 销量件, nameLocation: end, nameGap: 15, nameTextStyle: { fontSize: 14, color: #666 } }, series: [{ type: line, data: [120, 200, 150, 80, 170] }] };这套配置丢到任意 ECharts 示例里轴名称立刻变成可控状态。后面所有调整都是在这个基础上改参数。3. 六个高频场景的配置实测3.1 场景一x 轴名称要放到最左侧业务方经常要求“日期”跟第一根柱子对齐。这种情况就是nameLocation: start再把 nameGap 控制在 15-20文字出现在 x 轴原点上方偏左的位置。实测配置xAxis: { name: 日期, nameLocation: start, nameGap: 18 }注意start 位置下名称默认可能跟左侧 y 轴的刻度文字交错如果挤在一起加 grid.left 留白或者把 nameGap 调大。有一次我把 grid.left 设成 40x 轴名称“日期”和 y 轴刻度“0”几乎贴上去了把 left 加到 60 之后就舒服了。这个场景下文字是从左往右读的名称末尾贴近轴线左端会更协调。3.2 场景二y 轴名称要放到顶部默认竖排、位于中部偏上的 y 轴名称想挪到顶部用nameLocation: end。这里有个细节y 轴的 end 是“顶部”但这里的“顶部”是轴线范围内的顶部不是整个 canvas 的顶部。如果图表的 grid.top 太小顶部的名称可能跟标题或 legend 重叠所以调完 y 轴 name 之后顺手检查 grid.top建议至少留出 30px 以上。yAxis: { name: 销量件, nameLocation: end, nameGap: 12 } grid: { top: 50 }在实际看板里y 轴名称放顶部还有个好处当 y 轴有多个坐标网格线时顶部名称不会遮挡中间的刻度数字阅读顺序也更符合人眼从左上角开始扫视的习惯。3.3 场景三长名称不想横着占地方如果 x 轴名称特别长比如“2023 财年各季度销售统计”不想让它横着占太多宽度可以旋转xAxis: { name: 2023财年各季度销售统计, nameRotate: -30, nameLocation: end, nameGap: 40 }旋转后名称占位从横向变成斜向视觉上更紧凑。但注意旋转后的实际占位计算有点微妙名称末端可能扎进数据区域需要配合 nameGap 多试几个值。我自己的经验是旋转角度绝对值越大nameGap 也要相应加大否则文字末端会跟轴线端点靠得过近看起来像文字被切断了一样。3.4 场景四双 y 轴时两个 name 分别配置图表有两个 y 轴左右各一个时很多人会发现在哪都找不到第二个 name。原因是你只写了一个 yAxis 对象而 ECharts 要求多轴时必须用数组yAxis: [ { type: value, name: 温度(℃), nameLocation: end }, { type: value, name: 销量(件), nameLocation: end, splitLine: { show: false } } ]数组顺序对应 axisIndex第一个元素对应左边轴第二个对应右边轴。xAxis 多轴同理。如果一个数组里的某个轴没有设置 name另一个设置了显示也会对不上号所以多轴配置时一定要把每个轴的 name 都显式写上。另外记住双 y 轴场景下通常要把其中一个轴的 splitLine 关掉否则网格线叠在一起根本分不清谁是谁名称再多也没用。3.5 场景五配合 grid 留白别让 name 没地方站name 的位置和 grid 是强相关的。grid 控制的是绘图区而 name 默认沿轴线延伸方向摆放。如果 grid.left 设置得太小x 轴 name 在 start 位置时会被裁掉grid.right 太小name 在 end 位置时会被裁掉。我调 name 时有个固定套路先设置 name再看 grid哪里挤就补哪里。一个相对不容易出错的 grid 初始值grid: { left: 60, right: 40, top: 50, bottom: 40 }这个基础上再根据 name 位置的实际情况微调。比如 x 轴 name 用了 end 名称比较长那 grid.right 至少要保证名称长度加上 nameGap 后不会超出 canvas。拿不准的时候打开浏览器开发者工具把 canvas 放大几倍看坐标位置一目了然。3.6 场景六名称加单位并保证不出错很多人喜欢把单位写在 name 里比如“销量件”。这种写法没问题但如果单位很长想换行显示直接往 name 里塞\n通常不可靠不同浏览器渲染可能不一致。我的做法是把单位缩写到 name 里或者用后面的进阶方案graphic 手工绘制轴标题。还有一点如果你用formatter动态拼接单位比如name: \销量(${unit})注意 unit 是字符串时不会自动加空格写出来的“销量(件)”和“销量 (件)”在视觉上有差别最好在代码里统一成带空格的模板让中英文混排更自然。4. 踩过的坑与排查速查4.1 配置了 name 却不显示这是最常见的坑。排查顺序很重要第一name 属性有没有写错对象写成 axisLabel 或者 series.name 了第二nameTextStyle.color 是不是和背景色一致很多主题色下透明度调成 0 后看着像没显示第三nameGap 是不是被设成了极大的负数文字跑到画布外去了第四grid 边界是否把 name 区域裁剪掉了。按这个顺序排查90% 的“不显示”问题能在两分钟内解决。我还遇到过一种情况项目里引入了统一的可视化主题包主题把 nameTextStyle.color 统一设置成了白色而页面背景恰好也是白色结果所有轴名称集体“隐身”。这种问题肉眼很难发现选中画布查配置才知道是被主题包的颜色覆盖了。4.2 在 axisLabel 里找 name前面说过很多人会去 axisLabel 里改 name 的位置。axisLabel 确实也有 align、verticalAlign、rotate 等配置但它的角度是相对刻度而言的控制不了整根轴的名称位置。判断自己调的是不是 name直接看配置块xAxis.name、yAxis.name、nameLocation、nameGap、nameRotate、nameTextStyle都在坐标轴的最外层不在 axisLabel 里面。4.3 多轴时 name 张冠李戴双 y 轴图表里左边轴显示了“温度”但实际配的是第二个数组元素的 name这种错位是因为数组顺序和轴位置由 axisIndex 决定。如果你用了多 grid 多轴建议先 console.log 输出 yAxis 数组逐个核对 index 对应的轴位置和 name再上线。如果你发现两个轴的名称都堆在同一边另一个轴空空如也多半是数组写错了顺序要么是第二个 yAxis 没有显式指定position: right。在双轴配置里position 跟 nameLocation 是两码事常见错误是把 nameLocation 当成控制左右的手段实际上它只控制文字在轴线上的走向。4.4 setOption 动态更新把 name 冲掉了动态更新图表时如果直接这样myChart.setOption({ xAxis: { name: 新名称 } });默认 merge 模式下 name 会被更新成新值其他配置保留。但如果你用setOption(option, true)整个 option 会被替换之前调好的 nameTextStyle、nameGap 全部打回原形。动态更新 name 时我建议只传要改的字段保持 merge 模式不要轻易用第二个参数。4.5 name 被数据区域遮挡当 name 位置在 middle/center 时如果图表数据点密集name 可能被数据标签或图形压住。处理办法有三个把 nameGap 调大一点把 name 挪到 end 或 start给 nameTextStyle 配一个背景色和 padding做成小标签效果。最后这个办法我用得最多效果立竿见影nameTextStyle: { backgroundColor: #fff, borderRadius: 4, padding: [4, 8] }4.6 高频问题速查表症状排查思路解决建议name 完全不显示检查属性层级、颜色、负 gap、grid 裁剪逐项排查先从默认配置改起name 位置和预想不符检查 nameLocation 与 inverse 方向用 start/middle/end 显式指定name 太贴轴线nameGap 过小调到 20-40 之间微调name 被图形压住grid 留白不够或 gap 太小加大 grid 对应方向留白双轴只能显示一个 name第二个轴没写 name 或数组错位用数组分别配置并核对索引动态更新后样式丢失setOption 用了 true 或没配置 style保持 merge 模式或把样式带上4.7 name 赋了空值或未定义变量有些项目里 name 是从接口动态取的如果接口字段没返回name 就变成了undefined字符串图表上会诡异地显示一行“undefined”。这类问题通常不是配置问题而是数据源问题。我建议在赋值前做个兜底const axisName data data.axisName ? data.axisName : 默认指标;同时这种“undefined”症状也容易跟 4.1 的完全不显示搞混排查时可以瞄一眼页面 DOM 里是否真的出现了字符串如果出现了“undefined”直接去查接口字段。4.8 中文字体在部分环境下渲染发虚name 用了 fontStyle: italic 或 fontWeight 过重时在某些嵌入浏览器里中文字体会发虚、带毛刺。这不算 ECharts 的 bug更像字体渲染引擎的锅。我的建议是轴名称这种功能性文字优先用fontWeight: normal或bold字体用系统默认的sans-serif别用生僻字体也别轻易加斜体。比如“销量件”四个字斜体渲染出来跟仿宋一样看着很吃力业务方一眼就能挑出来。5. 进阶玩法让轴名称专业起来5.1 把单位从数据区拎出来与其在每个数据里写单位不如把单位挂到轴 name 上。比如销售额数据不写单位y 轴的 name 写“万元”。这样数据区更干净看图的人也知道单位。如果数据量级会变还可以用动态 nameconst unit dataMax 10000 ? 万元 : 元; myChart.setOption({ yAxis: { name: unit } });不过要注意动态改 name 之后最好同步调一下 nameGap因为“万元”和“元”的长度不一样gap 不变的话短单位看起来会离轴线很远长单位又可能贴得太近。5.2 用 rich 文本做差异化样式如果你觉得 nameTextStyle 的普通样式不够用可以用 rich。少数场景下我希望轴名称前面带一个色块或图标直接用 rich 实现nameTextStyle: { rich: { tag: { backgroundColor: #3E7BF5, color: #fff, borderRadius: 4, padding: [2, 6] } } }不过这个配置对 name 来说比较少见更多是用在 legend 和 axisLabel 里。做一个心理准备即可rich 能显著提升文本的信息层级但维护成本偏高项目里如果只是一两个图表没必要为了效果硬上 rich。5.3 用 graphic 手绘一个真正的“主轴标题”如果 name 满足不了需求比如要两行文字、要带单位、要跟某个数据点对齐可以直接停用 name改用 graphic 组件。graphic.type 为 text 时可以自由定位graphic: [ { type: text, left: 30, bottom: 12, style: { text: 日期\n2023-2024, fill: #333, fontSize: 13 } } ]graphic 的定位坐标默认相对整个 canvas所以要先通过 getBoundingClientRect 之类的方式计算好位置。这种方法灵活但可维护性差一点我的建议是常规需求用配置化的 name特殊需求再上 graphic。我之前做过一个季度销售页x 轴名称要压在一行小字说明下方name 做不到这种排版最后就是用 graphic 叠加实现的。5.4 响应式布局下 name 的适配在移动端或大屏适配时name 的配置应该跟着屏幕尺寸变化。如果只用写死的 nameGap 和 fontSize在窄屏上很容易把名称挤出画布。可以做一个简单的响应式方案监听容器宽度动态调整 name 配置后再 setOptionmerge 模式传 name 相关字段。更重要的是窄屏下优先把 xAxis 的 name 隐藏或改成 end 位置别让名称和刻度抢空间。window.addEventListener(resize, () { const width container.clientWidth; if (width 576) { myChart.setOption({ xAxis: { nameGap: 10, nameTextStyle: { fontSize: 12 } }, grid: { left: 40, right: 20, top: 40, bottom: 30 } }); } });5.5 避免 name 和刻度标签的信息重复有些图表 x 轴的 axisLabel 已经显示了“1 月、2 月、3 月”这时候 name 如果还写“月份”就属于重复表达。我见过不少看板把 x 轴名称写成“月份”下面刻度又是“1月、2月”视觉上信息冗余。合理的做法是名称写维度比如“时间”刻度写具体值或者干脆去掉 name把单位信息挪到统计口径说明里。信息架构比参数更重要先想清楚这行字有没有必要存在再谈它的位置。一点收尾的体会调了这几年图表我对轴名称最大的感受是它不负责承载数据却负责解释数据。业务方不会写代码但他们会说“这个轴字儿挡着了”“这个字儿太小了”。把 xAxis 和 yAxis 的 nameLocation、nameGap、nameTextStyle 这几个参数一次性配好能省掉很多来回返工。我自己目前的固定习惯是新建图表时先把这个“轴名称三件套”写进模板再做数据这样图表基本不会出现名字位置不对的问题。如果你也在调 ECharts 的轴名称建议先把 nameLocation 的 start 和 end 在 x 和 y 轴上都试一遍看明白了方向感后面所有调整都顺了。
