Skip to content

Chart.js Framework Integration

In modern web development, Chart.js often needs to integrate with various frontend frameworks. This chapter will detail how to use Chart.js in React, Vue.js, and Angular.

React Integration

React is one of the most popular frontend libraries, and there are several ways to integrate Chart.js into React applications.

Using react-chartjs-2

react-chartjs-2 is a React wrapper for Chart.js, providing better React integration experience.

First install necessary dependencies:

bash
npm install chart.js react-chartjs-2

Then create a simple chart component:

jsx
import React from 'react';
import {
  Chart as ChartJS,
  CategoryScale,
  LinearScale,
  BarElement,
  Title,
  Tooltip,
  Legend,
} from 'chart.js';
import { Bar } from 'react-chartjs-2';

// Register Chart.js components
ChartJS.register(
  CategoryScale,
  LinearScale,
  BarElement,
  Title,
  Tooltip,
  Legend
);

// Chart data
const data = {
  labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'],
  datasets: [
    {
      label: 'Sales Data',
      data: [12, 19, 3, 5, 2, 3, 9],
      backgroundColor: 'rgba(75, 192, 192, 0.2)',
      borderColor: 'rgba(75, 192, 192, 1)',
      borderWidth: 1,
    },
  ],
};

// Chart options
const options = {
  responsive: true,
  plugins: {
    legend: {
      position: 'top',
    },
    title: {
      display: true,
      text: 'Chart.js Bar Chart',
    },
  },
};

// Chart component
const BarChart = () => {
  return <Bar data={data} options={options} />;
};

export default BarChart;

Create Dynamic Chart Component

jsx
import React, { useState, useEffect } from 'react';
import {
  Chart as ChartJS,
  CategoryScale,
  LinearScale,
  PointElement,
  LineElement,
  Title,
  Tooltip,
  Legend,
} from 'chart.js';
import { Line } from 'react-chartjs-2';

ChartJS.register(
  CategoryScale,
  LinearScale,
  PointElement,
  LineElement,
  Title,
  Tooltip,
  Legend
);

const DynamicLineChart = () => {
  const [chartData, setChartData] = useState({
    labels: [],
    datasets: [
      {
        label: 'Real-time Data',
        data: [],
        fill: false,
        backgroundColor: 'rgb(75, 192, 192)',
        borderColor: 'rgba(75, 192, 192, 0.2)',
      },
    ],
  });

  useEffect(() => {
    const interval = setInterval(() => {
      const now = new Date();
      const timeString = `${now.getHours()}:${now.getMinutes()}:${now.getSeconds()}`;
      const newValue = Math.floor(Math.random() * 100);

      setChartData(prevData => {
        const newLabels = [...prevData.labels, timeString];
        const newData = [...prevData.datasets[0].data, newValue];

        // Keep maximum 20 data points
        if (newLabels.length > 20) {
          newLabels.shift();
          newData.shift();
        }

        return {
          labels: newLabels,
          datasets: [
            {
              ...prevData.datasets[0],
              data: newData,
            },
          ],
        };
      });
    }, 1000);

    return () => clearInterval(interval);
  }, []);

  const options = {
    responsive: true,
    plugins: {
      legend: {
        position: 'top',
      },
      title: {
        display: true,
        text: 'Real-time Data Chart',
      },
    },
    scales: {
      y: {
        beginAtZero: true,
      },
    },
  };

  return <Line data={chartData} options={options} />;
};

export default DynamicLineChart;

Vue.js Integration

Vue.js is another popular frontend framework, and there are also multiple ways to integrate Chart.js into Vue applications.

Using vue-chartjs

vue-chartjs is a Vue wrapper for Chart.js.

First install dependencies:

bash
npm install chart.js vue-chartjs

Create a simple chart component:

vue
<template>
  <div>
    <Bar
      :data="chartData"
      :options="chartOptions"
    />
  </div>
</template>

<script>
import {
  Chart as ChartJS,
  Title,
  Tooltip,
  Legend,
  BarElement,
  CategoryScale,
  LinearScale
} from 'chart.js'
import { Bar } from 'vue-chartjs'

ChartJS.register(Title, Tooltip, Legend, BarElement, CategoryScale, LinearScale)

export default {
  name: 'BarChart',
  components: {
    Bar
  },
  data() {
    return {
      chartData: {
        labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'],
        datasets: [
          {
            label: 'Sales Data',
            backgroundColor: 'rgba(75, 192, 192, 0.2)',
            borderColor: 'rgba(75, 192, 192, 1)',
            borderWidth: 1,
            data: [12, 19, 3, 5, 2, 3, 9]
          }
        ]
      },
      chartOptions: {
        responsive: true,
        plugins: {
          legend: {
            position: 'top',
          },
          title: {
            display: true,
            text: 'Chart.js Bar Chart'
          }
        }
      }
    }
  }
}
</script>

Create Reactive Chart Component

vue
<template>
  <div>
    <Line
      :data="chartData"
      :options="chartOptions"
    />
  </div>
</template>

<script>
import {
  Chart as ChartJS,
  CategoryScale,
  LinearScale,
  PointElement,
  LineElement,
  Title,
  Tooltip,
  Legend
} from 'chart.js'
import { Line } from 'vue-chartjs'

ChartJS.register(
  CategoryScale,
  LinearScale,
  PointElement,
  LineElement,
  Title,
  Tooltip,
  Legend
)

export default {
  name: 'ReactiveLineChart',
  components: {
    Line
  },
  data() {
    return {
      chartData: {
        labels: [],
        datasets: [
          {
            label: 'Real-time Data',
            data: [],
            fill: false,
            borderColor: 'rgb(75, 192, 192)',
            backgroundColor: 'rgba(75, 192, 192, 0.2)',
            tension: 0.1
          }
        ]
      },
      chartOptions: {
        responsive: true,
        maintainAspectRatio: false,
        plugins: {
          legend: {
            position: 'top',
          },
          title: {
            display: true,
            text: 'Real-time Data Chart'
          }
        },
        scales: {
          y: {
            beginAtZero: true
          }
        }
      }
    }
  },
  mounted() {
    this.startDataUpdate();
  },
  methods: {
    startDataUpdate() {
      setInterval(() => {
        const now = new Date();
        const timeString = `${now.getHours()}:${now.getMinutes()}:${now.getSeconds()}`;
        const newValue = Math.floor(Math.random() * 100);

        // Update labels
        this.chartData.labels.push(timeString);
        if (this.chartData.labels.length > 20) {
          this.chartData.labels.shift();
        }

        // Update data
        this.chartData.datasets[0].data.push(newValue);
        if (this.chartData.datasets[0].data.length > 20) {
          this.chartData.datasets[0].data.shift();
        }

        // Trigger re-render
        this.chartData = { ...this.chartData };
      }, 1000);
    }
  }
}
</script>

Angular Integration

To integrate Chart.js in Angular applications, you can use the ng2-charts library.

Install Dependencies

bash
npm install chart.js ng2-charts

Import in Module

typescript
// app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { ChartsModule } from 'ng2-charts';

import { AppComponent } from './app.component';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    ChartsModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

Create Chart Component

typescript
// bar-chart.component.ts
import { Component, OnInit } from '@angular/core';
import { ChartOptions, ChartType, ChartDataSets } from 'chart.js';
import { Label } from 'ng2-charts';

@Component({
  selector: 'app-bar-chart',
  template: `
    <div>
      <canvas baseChart
        [datasets]="barChartData"
        [labels]="barChartLabels"
        [options]="barChartOptions"
        [legend]="barChartLegend"
        [chartType]="barChartType">
      </canvas>
    </div>
  `
})
export class BarChartComponent implements OnInit {
  public barChartOptions: ChartOptions = {
    responsive: true,
    plugins: {
      legend: {
        position: 'top',
      },
      title: {
        display: true,
        text: 'Chart.js Bar Chart'
      }
    }
  };

  public barChartLabels: Label[] = ['January', 'February', 'March', 'April', 'May', 'June', 'July'];
  public barChartType: ChartType = 'bar';
  public barChartLegend = true;

  public barChartData: ChartDataSets[] = [
    {
      data: [12, 19, 3, 5, 2, 3, 9],
      label: 'Sales Data',
      backgroundColor: 'rgba(75, 192, 192, 0.2)',
      borderColor: 'rgba(75, 192, 192, 1)',
      borderWidth: 1
    }
  ];

  constructor() { }

  ngOnInit(): void {
  }
}

Create Dynamic Chart Component

typescript
// dynamic-chart.component.ts
import { Component, OnInit, OnDestroy } from '@angular/core';
import { ChartOptions, ChartType, ChartDataSets } from 'chart.js';
import { Label } from 'ng2-charts';
import { Subscription, timer } from 'rxjs';

@Component({
  selector: 'app-dynamic-chart',
  template: `
    <div>
      <canvas baseChart
        [datasets]="lineChartData"
        [labels]="lineChartLabels"
        [options]="lineChartOptions"
        [legend]="lineChartLegend"
        [chartType]="lineChartType">
      </canvas>
    </div>
  `
})
export class DynamicChartComponent implements OnInit, OnDestroy {
  private subscription: Subscription;

  public lineChartOptions: ChartOptions = {
    responsive: true,
    plugins: {
      legend: {
        position: 'top',
      },
      title: {
        display: true,
        text: 'Real-time Data Chart'
      }
    },
    scales: {
      yAxes: [{
        ticks: {
          beginAtZero: true
        }
      }]
    }
  };

  public lineChartLabels: Label[] = [];
  public lineChartType: ChartType = 'line';
  public lineChartLegend = true;

  public lineChartData: ChartDataSets[] = [
    {
      data: [],
      label: 'Real-time Data',
      fill: false,
      borderColor: 'rgb(75, 192, 192)',
      backgroundColor: 'rgba(75, 192, 192, 0.2)',
      tension: 0.1
    }
  ];

  constructor() { }

  ngOnInit(): void {
    this.subscription = timer(0, 1000).subscribe(() => {
      const now = new Date();
      const timeString = `${now.getHours()}:${now.getMinutes()}:${now.getSeconds()}`;
      const newValue = Math.floor(Math.random() * 100);

      // Update labels
      this.lineChartLabels.push(timeString);
      if (this.lineChartLabels.length > 20) {
        this.lineChartLabels.shift();
      }

      // Update data
      if (this.lineChartData[0].data) {
        this.lineChartData[0].data.push(newValue);
        if (this.lineChartData[0].data.length > 20) {
          this.lineChartData[0].data.shift();
        }
      }
    });
  }

  ngOnDestroy(): void {
    if (this.subscription) {
      this.subscription.unsubscribe();
    }
  }
}

Server-side Rendering (SSR) Considerations

When integrating Chart.js in SSR applications, you need to pay attention to some special issues.

React SSR

jsx
import React, { useEffect, useRef } from 'react';
import { Bar } from 'react-chartjs-2';

const SSRBarChart = () => {
  const chartRef = useRef(null);
  const [isClient, setIsClient] = useState(false);

  useEffect(() => {
    setIsClient(true);
  }, []);

  const data = {
    labels: ['January', 'February', 'March', 'April', 'May'],
    datasets: [
      {
        label: 'Sales Data',
        data: [12, 19, 3, 5, 2],
        backgroundColor: 'rgba(75, 192, 192, 0.2)',
      },
    ],
  };

  if (!isClient) {
    return <div>Loading...</div>;
  }

  return <Bar ref={chartRef} data={data} />;
};

export default SSRBarChart;

Data Integration

Fetching Data from API

javascript
import Chart from 'chart.js/auto';

async function createChartFromAPI(canvasId, apiUrl) {
    try {
        const response = await fetch(apiUrl);
        const data = await response.json();

        // Transform API data to Chart.js format
        const chartData = {
            labels: data.map(item => item.label),
            datasets: [{
                label: 'API Data',
                data: data.map(item => item.value),
                backgroundColor: 'rgba(54, 162, 235, 0.8)',
                borderColor: 'rgba(54, 162, 235, 1)',
                borderWidth: 1
            }]
        };

        const ctx = document.getElementById(canvasId).getContext('2d');
        new Chart(ctx, {
            type: 'bar',
            data: chartData,
            options: {
                responsive: true,
                scales: {
                    y: {
                        beginAtZero: true
                    }
                }
            }
        });

    } catch (error) {
        console.error('Error fetching data:', error);
    }
}

// Usage
createChartFromAPI('myChart', '/api/chart-data');

Real-time Data with WebSocket

javascript
import Chart from 'chart.js/auto';

function createRealtimeChart(canvasId) {
    const ctx = document.getElementById(canvasId).getContext('2d');

    const chart = new Chart(ctx, {
        type: 'line',
        data: {
            labels: [],
            datasets: [{
                label: 'Real-time Data',
                data: [],
                borderColor: 'rgb(75, 192, 192)',
                backgroundColor: 'rgba(75, 192, 192, 0.2)',
                tension: 0.1
            }]
        },
        options: {
            responsive: true,
            scales: {
                x: {
                    display: true
                },
                y: {
                    beginAtZero: true
                }
            }
        }
    });

    // WebSocket connection
    const ws = new WebSocket('ws://localhost:8080/realtime-data');

    ws.onmessage = (event) => {
        const data = JSON.parse(event.data);

        // Add new data point
        chart.data.labels.push(new Date().toLocaleTimeString());
        chart.data.datasets[0].data.push(data.value);

        // Keep only last 20 points
        if (chart.data.labels.length > 20) {
            chart.data.labels.shift();
            chart.data.datasets[0].data.shift();
        }

        chart.update('none');  // Update without animation for real-time feel
    };

    ws.onerror = (error) => {
        console.error('WebSocket error:', error);
    };

    ws.onclose = () => {
        console.log('WebSocket connection closed');
    };

    return chart;
}

// Usage
const realtimeChart = createRealtimeChart('realtimeChart');

Summary

In this chapter, we learned how to integrate Chart.js in different frontend frameworks:

  1. React - Use react-chartjs-2 library to create chart components
  2. Vue.js - Use vue-chartjs library to create chart components
  3. Angular - Use ng2-charts library to create chart components
  4. SSR Considerations - Special handling in server-side rendering applications
  5. Data Integration - Fetching data from APIs and real-time updates

With these integration methods, you can easily use Chart.js in modern frontend applications to create rich data visualization charts. In next chapter, we will learn Chart.js best practices.

Content is for learning and research only.