Search code examples
chart.js

Chart.js Zoom Limits Not Working: Infinite Scrolling Still Possible


I'm working on a larger project but have created a minimal "working" example here: https://jsfiddle.net/brLh2yk4/16/

HTML:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Chart.js Zoom & Pan Example</title>
  <link rel="stylesheet" href="styles.css">
</head>
<body>
  <div class="container">
    <canvas id="chartCanvas"></canvas>
  </div>
  <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-zoom"></script>
</body>
</html>

CSS:

body {
  margin: 0;
  font-family: Arial, sans-serif;
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
  background-color: #2c3e50;
}

.container {
  width: 80%;
  max-width: 800px;
}

canvas {
  background-color: #34495e;
  border-radius: 8px;
}

JS:

document.addEventListener('DOMContentLoaded', function() {
  const ctx = document.getElementById('chartCanvas').getContext('2d');

  const data = {
    labels: Array.from({
      length: 50
    }, (_, i) => `Label ${i + 1}`),
    datasets: [{
        label: 'CPU Usage (%)',
        data: Array.from({
          length: 50
        }, () => Math.random() * 100),
        borderColor: 'rgba(255, 165, 0, 1)',
        backgroundColor: 'rgba(255, 165, 0, 0.2)',
        fill: false,
        yAxisID: 'y-axis-cpu',
      },
      {
        label: 'Memory Usage (MB)',
        data: Array.from({
          length: 50
        }, () => Math.random() * 500),
        borderColor: 'rgba(25, 153, 255, 1.0)',
        backgroundColor: 'rgba(25, 153, 255, 0.2)',
        fill: false,
        yAxisID: 'y-axis-memory',
      }
    ]
  };

  const options = {
    responsive: true,
    scales: {
      x: {
        type: 'category',
        title: {
          display: true,
          text: 'Time',
          color: '#ffffff'
        },
        ticks: {
          color: '#ffffff',
        },
        grid: {
          color: 'rgba(255, 255, 255, 0.2)',
        }
      },
      'y-axis-cpu': {
        type: 'linear',
        position: 'left',
        beginAtZero: true,
        max: 100,
        title: {
          display: true,
          text: 'CPU Usage (%)',
          color: '#ffffff'
        },
        ticks: {
          color: '#ffffff',
        },
        grid: {
          color: 'rgba(255, 255, 255, 0.2)',
        }
      },
      'y-axis-memory': {
        type: 'linear',
        position: 'right',
        beginAtZero: true,
        max: 500,
        title: {
          display: true,
          text: 'Memory Usage (MB)',
          color: '#ffffff'
        },
        ticks: {
          color: '#ffffff',
        },
        grid: {
          color: 'rgba(255, 255, 255, 0.2)',
        }
      }
    },
    plugins: {
      zoom: {
        pan: {
          enabled: true,
          mode: 'xy',
        },
        zoom: {
          wheel: {
            enabled: true,
          },
          pinch: {
            enabled: true,
          },
          mode: 'xy',
          limits: {
            x: {
              min: 'original',
              max: 'original'
            },
            y: {
              min: 'original',
              max: 'original'
            }
          }
        }
      }
    }
  };

  const chart = new Chart(ctx, {
    type: 'line',
    data: data,
    options: options
  });
});

I've defined the zoom limits using 'original' as described in the Chart.js zoom plugin documentation. However, I'm still able to scroll infinitely, even though I've set specific limits. Furthermore, I tried setting custom limits and specific for each axis, but they still had no effect. Why aren't the zoom limits working? How can I prevent infinite zooming out?


Solution

  • You've made a slight mistake. According to the docs, the limits should be in a higher node level. It should be options.plugins.zoom.limits, and in your fiddle it's options.plugins.zoom.zoom.limits.

    Here's a working fork: https://jsfiddle.net/g6wr8d3m/ where I moved the limits node one level up.