多轴图表需用echarts或highcharts等支持多y轴的库,chart.js不支持;echarts需显式配置yaxis数组,highcharts需为yaxis设id并绑定series;容器div必须有固定宽高,数据长度须严格一致。

多轴图表必须用支持多Y轴的库,Chart.js 默认不支持
Chart.js 的 yAxes 配置早在 v2.x 就已废弃,v3+ 完全移除;它只允许单 Y 轴(scales.y),强行写多个会静默忽略第二项。真要多 Y 轴,得换库——ECharts 和 Highcharts 是目前最稳的选择。ECharts 的 yAxis 接受数组,Highcharts 的 yAxis 也明确支持对象数组,两者都默认启用 offset、opposite、color 同步控制。
常见错误现象:Uncaught TypeError: Cannot read properties of undefined (reading 'length'),往往是因为你把 Chart.js 的配置直接套到 ECharts 的 setOption() 里,或漏传了 yAxis 数组中的某一项。
- ECharts 多 Y 轴必须显式设
yAxis: [{}, {}],不能只写一个对象 - Highcharts 中每个
yAxis对象需带id,series 里用yAxis: 'id1'显式绑定 - 所有库都要求容器 div 有固定
width和height,否则init()或new Chart()返回 null
ECharts 实现左右分栏 + 右侧上下双图的关键 DOM 结构
不是靠 CSS Grid 或 Flex 布局“撑开”图表,而是每个图表必须挂载在独立、宽高明确的 <div> 上。ECharts 不会自动拉伸父容器,也不会响应父级 <code>display: none —— 初始化前若容器不可见,图表会空白且不报错。
正确结构示例:
<div style="display: flex; height: 600px;">
<div id="left-chart" style="width: 40%; height: 100%;"></div>
<div style="width: 60%; display: flex; flex-direction: column;">
<div id="right-top" style="flex: 1;"></div>
<div id="right-bottom" style="flex: 1;"></div>
</div>
</div>
注意点:
- 每个
id必须唯一,重复会导致后初始化的实例覆盖前一个 -
flex: 1有效,但父级必须有明确高度(如上例的height: 600px) - 初始化顺序无关紧要,但推荐按 DOM 顺序依次调
echarts.init()
Highcharts 多 Y 轴配色和图例对齐容易错位
Highcharts 默认把所有 series 的图例项堆在左上角,但多 Y 轴时,不同轴的数据线颜色若没和对应 yAxis 的 title.style.color 一致,用户根本分不清哪条线对应哪个轴。更麻烦的是:图例项点击切换 series 时,如果没同步 toggle 对应 yAxis 的 visibility,视觉逻辑就断了。
实操建议:
- 给每个
yAxis设id和title.style.color,再让对应series.color与之完全相同(复制粘贴 HEX 值,别靠脑记) - 在
plotOptions.series.events.legendItemClick里手动控制this.yAxis.setVisible(!this.yAxis.visible) - 避免用
opposite: true加offset组合微调位置——容易在缩放后错位,优先用opposite+height+top粗粒度定位
数据长度不一致会导致多轴图表渲染失败但不报错
ECharts 和 Highcharts 都不会校验 series.data 和 xAxis.data(或 categories)长度是否匹配。一旦不一致,可能只渲染出部分柱子、折线中断、坐标轴刻度漂移,甚至整个 canvas 空白——控制台却风平浪静。
最容易被忽略的场景:
- API 返回的数组是对象列表,你用
Object.keys(res)提取 labels,但后端返回顺序不保证,导致 labels 和 data 错位 - 前端过滤了某些数据点(比如剔除 null),但忘了同步过滤 labels 数组
- 多 Y 轴共用同一份
xAxis.categories,但某个 series 的 data 缺失某时段值,没补null
上线前必做检查:console.log(xAxis.categories.length, series[0].data.length, series[1].data.length) —— 三者必须全等。











