Graphics Chart.js Basics

This lesson introduces Chart.js, a canvas-based charting library, and walks through building, configuring, and updating a first chart with its declarative API.

What Chart.js Adds on Top of Canvas

Everything drawn so far, the clock face, ticks, hands, used raw canvas calls: arc(), moveTo(), rotate(). Chart.js is built on exactly those same primitives, but it hides them behind a configuration object. Instead of computing bar positions or axis tick spacing by hand, you describe your data and a chart type, and Chart.js works out the drawing, scaling, legend, and tooltip behavior for you.

Example

<!DOCTYPE html>
<html>
<head>
  <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
</head>
<body>

<canvas id="myChart" width="400" height="200"></canvas>

</body>
</html>

Creating Your First Chart

Example

<!DOCTYPE html>
<html>
<head>
  <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
</head>
<body>

<canvas id="myChart" width="400" height="200"></canvas>

<script>
const ctx = document.getElementById('myChart').getContext('2d');

const myChart = new Chart(ctx, {
  type: 'bar',
  data: {
    labels: ['Jan', 'Feb', 'Mar', 'Apr', 'May'],
    datasets: [{
      label: 'Signups',
      data: [12, 19, 8, 15, 22],
      backgroundColor: 'rgba(54, 162, 235, 0.6)',
      borderColor: 'rgb(54, 162, 235)',
      borderWidth: 1
    }]
  },
  options: {
    responsive: true,
    scales: {
      y: { beginAtZero: true }
    }
  }
});
</script>

</body>
</html>

Every Chart.js config revolves around three top-level keys. type picks the chart kind, 'bar' here. data holds the labels for each position along the category axis and one or more datasets, each with its own array of values and its own styling. options controls everything else: whether the chart resizes with its container, how the axes are scaled, and how legends and tooltips behave.

  • bar - vertical or horizontal bars
  • line - connected points, good for trends over time
  • pie / doughnut - parts of a whole
  • radar - multiple variables on axes radiating from a center point
  • scatter / bubble - individual x,y (and size) data points
Option pathWhat it controls
responsiveWhether the chart canvas resizes to fill its container
options.plugins.legend.displayWhether the legend is shown at all
options.plugins.legend.positionWhere the legend sits: top, bottom, left, or right
options.scales.y.beginAtZeroWhether the y-axis is forced to start at 0 instead of the data minimum

Example

<!DOCTYPE html>
<html>
<head>
  <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
</head>
<body>

<canvas id="lineChart" width="400" height="200"></canvas>

<script>
new Chart(document.getElementById('lineChart').getContext('2d'), {
  type: 'line',
  data: {
    labels: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri'],
    datasets: [
      {
        label: 'This week',
        data: [5, 9, 7, 12, 10],
        borderColor: 'rgb(255, 99, 132)',
        tension: 0.3
      },
      {
        label: 'Last week',
        data: [4, 6, 8, 9, 11],
        borderColor: 'rgb(75, 192, 192)',
        tension: 0.3
      }
    ]
  },
  options: {
    plugins: {
      legend: { position: 'bottom' }
    }
  }
});
</script>

</body>
</html>

Charts rarely stay static. Since myChart holds a reference to the live Chart instance, you can mutate its data directly and then call update() to redraw with the new values, without recreating the chart or its DOM node, for example myChart.data.datasets[0].data = [20, 15, 25, 18, 30]; myChart.update(); Chart.js diffs the change and animates the transition automatically.

Note: Newer Chart.js versions (v3 and v4) support tree-shaking: if you import from the ES module build, you must register only the chart types, scales, and plugins you actually use with Chart.register(...). The plain script-tag CDN build shown above already registers everything, which is the simpler choice while you are learning.
Note: If you rebuild a chart on the same canvas element, for example when a user changes a filter, call the existing chart's destroy() method first. Otherwise Chart.js throws an error that the canvas is already in use, because the old chart instance is still attached to that canvas.