You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Chart.js 4.4.2中图表移至不同尺寸容器后无法自适应调整大小

Chart.js v4交换图表容器后尺寸不更新的解决方法

问题场景

两个并排图表分别放在大、小容器中,点击后交换容器位置。该功能在Chart.js v2.9.4可正常自适应尺寸,但升级至v4.4.2后,图表移动后仍保留原尺寸,无法适配新容器。

原始代码

HTML

<div id='chart-container'>
    <div id='big-chart-container'>
      <canvas id='chart1'></canvas>
    </div>
    <div id='small-chart-container'>
      <canvas id='chart2'></canvas>
    </div>
</div>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<!--Swapping charts works in chart.js 2-->
<!--<script src="https://cdn.jsdelivr.net/npm/chart.js@2.8.0"></script>-->

CSS

#chart-container{
    display: flex;
    width: 60vw;
  }

  #big-chart-container{
    width: 60%;
  }

  #small-chart-container{
    width: 30%;
  }

JavaScript

var canvas1 = document.getElementById('chart1')
var canvas2 = document.getElementById('chart2')

let bigChartContainer = document.getElementById('big-chart-container');
let smallChartContainer =document.getElementById('small-chart-container');
let data1 = [5,7,6,2,6,8,4,5]
let data2 = [4,8,15,16,23,42]
let labels1 = [...Array(data1.length).keys()]
let labels2 = [...Array(data2.length).keys()]

let bigChartID = 'chart1';

function chartClicked(chartID){
    if(bigChartID != chartID){ //if small chart is clicked then swap charts
      let smallChart = document.getElementById(chartID)
      let bigChart = document.getElementById(bigChartID)
      bigChartContainer.appendChild(smallChart)
      smallChartContainer.appendChild(bigChart)
      bigChartID = chartID
    }
}
  
const bigChart = new Chart(canvas1.getContext('2d'), {
  type: 'line',
  data: {
    labels: labels1,
    datasets: [{
      label: "Chart 1",
      data: data1
    }]
  },
  options: {
    onClick: function(){
      chartClicked('chart1')
    }
  }
})
const smallChart = new Chart(canvas2.getContext('2d'), {
  type: 'line',
  data: {
    labels: labels2,
    datasets: [{
      label: "Chart 2",
      data: data2,
      borderColor: 'rgb(255, 99, 132)',
    }]
  },
  options: {
    onClick: function(){
      chartClicked('chart2')
    }
  }
})

原因分析

Chart.js v4移除了v2中自动监听DOM元素移动后尺寸变化的逻辑,默认不会主动重新计算容器尺寸。交换canvas元素后,图表实例仍持有原容器的尺寸信息,需要手动触发尺寸更新。

解决方案

在交换容器后,先强制浏览器重新计算布局(确保容器尺寸已更新),再调用图表实例的resize()方法,让图表自适应新容器的尺寸。

修改后的chartClicked函数如下:

function chartClicked(chartID){
    if(bigChartID != chartID){ 
      let smallChartEl = document.getElementById(chartID)
      let bigChartEl = document.getElementById(bigChartID)
      // 交换canvas元素
      bigChartContainer.appendChild(smallChartEl)
      smallChartContainer.appendChild(bigChartEl)
      bigChartID = chartID

      // 强制浏览器重排,获取最新容器尺寸
      void bigChartContainer.offsetWidth;
      void smallChartContainer.offsetWidth;

      // 触发图表尺寸更新
      bigChart.resize();
      smallChart.resize();
    }
}

原理说明

  • void element.offsetWidth:读取元素的offsetWidth属性会强制浏览器立即重新计算布局,确保容器的尺寸已经更新为新的状态。
  • chart.resize():Chart.js的实例方法,会重新读取容器的尺寸并调整图表的大小,适配新容器。

内容的提问来源于stack exchange,提问作者user24917036

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 11:58:14