Responsive Charts

When it comes to changing the chart size based on the window size, a major limitation is that the canvas render size (canvas.width and .height) can not be expressed with relative values, contrary to the display size (canvas.style.width and .height). Furthermore, these sizes are independent from each other and thus the canvas render size does not adjust automatically based on the display size, making the rendering inaccurate.

The following examples do not work:

  • <canvas height="40vh" width="80vw">: invalid values, the canvas doesn’t resize (example Responsive Charts - 图1 (opens new window))
  • <canvas style="height:40vh; width:80vw">: invalid behavior, the canvas is resized but becomes blurry (example Responsive Charts - 图2 (opens new window))
  • <canvas style="margin: 0 auto;">: invalid behavior, the canvas continually shrinks. Chart.js needs a dedicated container for each canvas and this styling should be applied there.

Chart.js provides a few options to enable responsiveness and control the resize behavior of charts by detecting when the canvas display size changes and update the render size accordingly.

Configuration Options

Namespace: options

NameTypeDefaultDescription
responsivebooleantrueResizes the chart canvas when its container does (important note…).
maintainAspectRatiobooleantrueMaintain the original canvas aspect ratio (width / height) when resizing.
aspectRationumber2Canvas aspect ratio (i.e. width / height, a value of 1 representing a square canvas). Note that this option is ignored if the height is explicitly defined either as attribute or via the style.
onResizefunctionnullCalled when a resize occurs. Gets passed two arguments: the chart instance and the new size.
resizeDelaynumber0Delay the resize update by give amount of milliseconds. This can ease the resize process by debouncing update of the elements.

Important Note

Detecting when the canvas size changes can not be done directly from the canvas element. Chart.js uses its parent container to update the canvas render and display sizes. However, this method requires the container to be relatively positioned and dedicated to the chart canvas only. Responsiveness can then be achieved by setting relative values for the container size (example Responsive Charts - 图3 (opens new window)):

  1. <div class="chart-container" style="position: relative; height:40vh; width:80vw">
  2. <canvas id="chart"></canvas>
  3. </div>

The chart can also be programmatically resized by modifying the container size:

  1. chart.canvas.parentNode.style.height = '128px';
  2. chart.canvas.parentNode.style.width = '128px';

Note that in order for the above code to correctly resize the chart height, the maintainAspectRatio option must also be set to false.

Printing Resizable Charts

CSS media queries allow changing styles when printing a page. The CSS applied from these media queries may cause charts to need to resize. However, the resize won’t happen automatically. To support resizing charts when printing, you need to hook the onbeforeprint Responsive Charts - 图4 (opens new window) event and manually trigger resizing of each chart.

  1. function beforePrintHandler () {
  2. for (var id in Chart.instances) {
  3. Chart.instances[id].resize();
  4. }
  5. }

You may also find that, due to complexities in when the browser lays out the document for printing and when resize events are fired, Chart.js is unable to properly resize for the print layout. To work around this, you can pass an explicit size to .resize() then use an onafterprint Responsive Charts - 图5 (opens new window) event to restore the automatic size when done.

  1. window.addEventListener('beforeprint', () => {
  2. myChart.resize(600, 600);
  3. });
  4. window.addEventListener('afterprint', () => {
  5. myChart.resize();
  6. });