ECharts 切换 Tab 后空白或变形是因为非激活 Tab 的 .tab-pane 为 display: none,导致 init 时获取宽高为 0;应在 shown.bs.tab 事件中调用 chart.resize() 并确保容器可见。
ECharts 实例初始化时会读取容器 offsetWidth 和 offsetHeight 计算绘图区域,而 Bootstrap 的 .tab-pane 在非激活状态默认是 display: none —— 此时尺寸为 0,echarts.init() 拿到的宽高就是 0,导致渲染失败或 canvas 留白。不是代码写错,是 DOM 可见性与图表生命周期不匹配。
shown.bs.tab 并调用 resize()
必须等 Tab 面板完全显示(即 shown.bs.tab 事件触发)后再通知图表重算尺寸。注意事件名和 data-toggle 属性要一致:
data-toggle="tab"(常见于 .nav-tabs),监听 shown.bs.tab
data-toggle="pill"(常见于 .nav-pills),监听 shown.bs.pill
示例:
const myChart = echarts.init(document.getElementById('chart1'));// ... setOption$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) { // 确保只对当前激活 tab 下的 chart 生效(避免误 resize 其他图表) if ($(e.target).attr('href') === '#tab-charts') { myChart.resize(); }});
手动维护每个 chart 变量容易遗漏,推荐用数组集中注册 + 循环 resize:
const charts = []
echarts.init() 后立即 charts.push(myChart)
shown.bs.tab 回调里遍历调用 resize(),但要注意:仅当对应 tab 面板可见时才 resize,否则可能因容器不可见再次拿不到尺寸更稳妥的做法是加一层可见性判断:
$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) { const targetPane = $($(e.target).attr('href')); charts.forEach(chart => { if (targetPane.find(chart.getDom()).length) { chart.resize(); } });});
show.bs.tab 或 click 里 resizeshow.bs.tab 触发时面板尚未添加 .active 类,DOM 还没完成重排,offsetWidth 仍为 0;click 更早,此时面板甚至还没开始切换。只有 shown.bs.tab 是唯一能确保面板已渲染、尺寸可读的时机。另外,如果图表容器用了 flex 或 grid 布局且未设明确宽高,resize() 也可能失效——这时得检查 CSS 是否给了父容器最小尺寸(如 min-width: 300px)。