Home » Интеграция Chart.js и ng2-Charts в Angular
Интеграция Chart.js и ng2-Charts в Angular

Интеграция Chart.js и ng2-Charts в Angular

Раньше для создания интерактивных графиков в Angular-приложениях приходилось изобретать велосипед или пользоваться тяжеловесными решениями. Сейчас же у нас есть Chart.js – простая и мощная библиотека для создания красивых диаграмм, а ng2-Charts делает её интеграцию с Angular максимально безболезненной. Если вы разворачиваете дашборды мониторинга на своих серверах или создаете админки для управления инфраструктурой, эта связка станет настоящим спасением.

Забудьте о сложных D3.js конструкциях для простых задач – Chart.js + ng2-Charts позволяет создавать профессиональные графики буквально в несколько строк кода. Особенно актуально для тех, кто работает с метриками серверов, мониторингом нагрузки или аналитикой веб-приложений.

Как это работает под капотом

Chart.js – это JavaScript-библиотека, которая рендерит графики через HTML5 Canvas. ng2-Charts выступает в роли Angular-обёртки, предоставляя reactive-компоненты и TypeScript-типизацию. Связка работает по принципу:

  • Chart.js – отвечает за рендеринг и анимации
  • ng2-Charts – предоставляет Angular-компоненты и биндинги
  • Canvas API – обеспечивает производительный рендеринг
  • Angular Change Detection – автоматически обновляет графики при изменении данных

Архитектура получается довольно элегантная: вы работаете с привычными Angular-компонентами, а вся магия отрисовки происходит в фоне.

Пошаговая установка и настройка

Начинаем с чистого Angular-проекта. Если у вас ещё нет проекта, создаём:

ng new chart-dashboard
cd chart-dashboard

Устанавливаем необходимые пакеты:

npm install chart.js ng2-charts
npm install @types/chart.js --save-dev

Импортируем модуль в app.module.ts:

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { NgChartsModule } from 'ng2-charts';

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

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

Теперь создаём простой компонент с графиком:

import { Component } from '@angular/core';
import { ChartConfiguration, ChartOptions, ChartType } from 'chart.js';

@Component({
  selector: 'app-root',
  template: `
    <div style="width: 600px; height: 400px;">
      <canvas baseChart
        [data]="lineChartData"
        [options]="lineChartOptions"
        [type]="lineChartType">
      </canvas>
    </div>
  `
})
export class AppComponent {
  public lineChartData: ChartConfiguration['data'] = {
    labels: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun'],
    datasets: [
      {
        data: [65, 59, 80, 81, 56, 55],
        label: 'CPU Usage %',
        backgroundColor: 'rgba(54, 162, 235, 0.2)',
        borderColor: 'rgba(54, 162, 235, 1)',
        borderWidth: 2
      }
    ]
  };

  public lineChartOptions: ChartOptions = {
    responsive: true,
    maintainAspectRatio: false,
    scales: {
      y: {
        beginAtZero: true,
        max: 100
      }
    }
  };

  public lineChartType: ChartType = 'line';
}

Практические примеры и кейсы

Вот несколько реальных сценариев использования с готовыми решениями:

Мониторинг нагрузки сервера

export class ServerMonitoringComponent {
  public serverMetrics: ChartConfiguration['data'] = {
    labels: [],
    datasets: [
      {
        label: 'CPU %',
        data: [],
        borderColor: '#ff6384',
        backgroundColor: 'rgba(255, 99, 132, 0.1)'
      },
      {
        label: 'RAM %',
        data: [],
        borderColor: '#36a2eb',
        backgroundColor: 'rgba(54, 162, 235, 0.1)'
      },
      {
        label: 'Disk I/O',
        data: [],
        borderColor: '#4bc0c0',
        backgroundColor: 'rgba(75, 192, 192, 0.1)'
      }
    ]
  };

  ngOnInit() {
    // Обновляем данные каждые 5 секунд
    setInterval(() => {
      this.updateMetrics();
    }, 5000);
  }

  private updateMetrics() {
    const now = new Date().toLocaleTimeString();
    this.serverMetrics.labels?.push(now);
    
    // Имитируем получение данных с сервера
    this.serverMetrics.datasets[0].data.push(Math.random() * 100);
    this.serverMetrics.datasets[1].data.push(Math.random() * 100);
    this.serverMetrics.datasets[2].data.push(Math.random() * 100);
    
    // Оставляем только последние 20 точек
    if (this.serverMetrics.labels!.length > 20) {
      this.serverMetrics.labels?.shift();
      this.serverMetrics.datasets.forEach(dataset => dataset.data.shift());
    }
  }
}

Дашборд трафика

export class TrafficDashboardComponent {
  public donutChartData: ChartConfiguration['data'] = {
    labels: ['Desktop', 'Mobile', 'Tablet'],
    datasets: [{
      data: [65, 25, 10],
      backgroundColor: [
        '#FF6384',
        '#36A2EB',
        '#FFCE56'
      ]
    }]
  };

  public barChartData: ChartConfiguration['data'] = {
    labels: ['00:00', '04:00', '08:00', '12:00', '16:00', '20:00'],
    datasets: [{
      label: 'Requests/hour',
      data: [1200, 800, 1500, 2000, 1800, 1600],
      backgroundColor: 'rgba(54, 162, 235, 0.6)'
    }]
  };
}

Сравнение с альтернативными решениями

Решение Размер библиотеки Производительность Простота интеграции Типизация
Chart.js + ng2-Charts ~150KB Высокая Очень простая Полная
D3.js ~250KB Максимальная Сложная Частичная
Plotly.js ~3MB Средняя Средняя Хорошая
ApexCharts ~350KB Хорошая Простая Хорошая

Нестандартные способы использования

Несколько креативных подходов, которые я встречал в проектах:

Интеграция с WebSocket для real-time данных

export class RealTimeChartsComponent {
  private socket: WebSocket;
  
  ngOnInit() {
    this.socket = new WebSocket('ws://your-server.com/metrics');
    
    this.socket.onmessage = (event) => {
      const data = JSON.parse(event.data);
      this.updateChartData(data);
    };
  }

  private updateChartData(newData: any) {
    // Обновляем график в реальном времени
    this.chart.data.labels.push(new Date().toLocaleTimeString());
    this.chart.data.datasets[0].data.push(newData.value);
    this.chart.update('none'); // Отключаем анимацию для плавности
  }
}

Кастомные плагины для Chart.js

const customPlugin = {
  id: 'customCanvasBackgroundColor',
  beforeDraw: (chart: any) => {
    const ctx = chart.canvas.getContext('2d');
    ctx.save();
    ctx.globalCompositeOperation = 'destination-over';
    ctx.fillStyle = '#1a1a1a'; // Тёмная тема
    ctx.fillRect(0, 0, chart.width, chart.height);
    ctx.restore();
  }
};

// Регистрируем плагин глобально
Chart.register(customPlugin);

Оптимизация производительности

Для серверных дашбордов, где данные обновляются часто, важно оптимизировать производительность:

export class OptimizedChartComponent {
  @ViewChild(BaseChartDirective) chart: BaseChartDirective | undefined;
  
  // Используем OnPush для оптимизации
  changeDetection: ChangeDetectionStrategy.OnPush
  
  // Батчим обновления
  private updateQueue: any[] = [];
  private isUpdateScheduled = false;
  
  addDataPoint(data: any) {
    this.updateQueue.push(data);
    
    if (!this.isUpdateScheduled) {
      this.isUpdateScheduled = true;
      requestAnimationFrame(() => {
        this.processBatchUpdate();
      });
    }
  }
  
  private processBatchUpdate() {
    // Обрабатываем все накопленные обновления за один раз
    this.updateQueue.forEach(data => {
      // Логика обновления
    });
    
    this.chart?.update('none'); // Без анимации
    this.updateQueue = [];
    this.isUpdateScheduled = false;
  }
}

Развёртывание на продакшен

Если вы разворачиваете дашборд на VPS или выделенном сервере, учитывайте следующие моменты:

# Оптимизация для продакшена
ng build --prod --build-optimizer

# Настройка nginx для Angular SPA
server {
    listen 80;
    server_name your-dashboard.com;
    
    location / {
        root /var/www/dashboard/dist;
        try_files $uri $uri/ /index.html;
    }
    
    # Кеширование статики
    location ~* \.(js|css|png|jpg|jpeg|gif|svg|ico)$ {
        expires 1y;
        add_header Cache-Control "public, immutable";
    }
}

Полезные ресурсы и документация

Заключение и рекомендации

Chart.js + ng2-Charts – это идеальное решение для 80% задач, связанных с визуализацией данных в Angular. Библиотека достаточно легковесная, чтобы не тормозить приложение, но при этом предоставляет все необходимые возможности для создания профессиональных дашбордов.

Используйте эту связку, если:

  • Создаёте дашборды мониторинга для серверов
  • Нужны стандартные типы графиков (линейные, столбчатые, круговые)
  • Важна производительность и небольшой размер bundle’а
  • Команда не готова изучать сложные решения типа D3.js

Избегайте, если:

  • Нужны сложные кастомные визуализации
  • Работаете с геоданными (лучше взять Leaflet или подобное)
  • Требуется обработка огромных объёмов данных (>10k точек)

В целом, для серверных админок и мониторинга это оптимальный выбор. Быстро внедряется, хорошо документировано, активно поддерживается. Если разворачиваете на своих серверах – помните про оптимизацию bundle’а и правильную настройку кеширования статики.


В этой статье собрана информация и материалы из различных интернет-источников. Мы признаем и ценим работу всех оригинальных авторов, издателей и веб-сайтов. Несмотря на то, что были приложены все усилия для надлежащего указания исходного материала, любая непреднамеренная оплошность или упущение не являются нарушением авторских прав. Все упомянутые товарные знаки, логотипы и изображения являются собственностью соответствующих владельцев. Если вы считаете, что какой-либо контент, использованный в этой статье, нарушает ваши авторские права, немедленно свяжитесь с нами для рассмотрения и принятия оперативных мер.

Данная статья предназначена исключительно для ознакомительных и образовательных целей и не ущемляет права правообладателей. Если какой-либо материал, защищенный авторским правом, был использован без должного упоминания или с нарушением законов об авторском праве, это непреднамеренно, и мы исправим это незамедлительно после уведомления. Обратите внимание, что переиздание, распространение или воспроизведение части или всего содержимого в любой форме запрещено без письменного разрешения автора и владельца веб-сайта. Для получения разрешений или дополнительных запросов, пожалуйста, свяжитесь с нами.

Leave a reply

Your email address will not be published. Required fields are marked