- Home »

Интеграция 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’а и правильную настройку кеширования статики.
В этой статье собрана информация и материалы из различных интернет-источников. Мы признаем и ценим работу всех оригинальных авторов, издателей и веб-сайтов. Несмотря на то, что были приложены все усилия для надлежащего указания исходного материала, любая непреднамеренная оплошность или упущение не являются нарушением авторских прав. Все упомянутые товарные знаки, логотипы и изображения являются собственностью соответствующих владельцев. Если вы считаете, что какой-либо контент, использованный в этой статье, нарушает ваши авторские права, немедленно свяжитесь с нами для рассмотрения и принятия оперативных мер.
Данная статья предназначена исключительно для ознакомительных и образовательных целей и не ущемляет права правообладателей. Если какой-либо материал, защищенный авторским правом, был использован без должного упоминания или с нарушением законов об авторском праве, это непреднамеренно, и мы исправим это незамедлительно после уведомления. Обратите внимание, что переиздание, распространение или воспроизведение части или всего содержимого в любой форме запрещено без письменного разрешения автора и владельца веб-сайта. Для получения разрешений или дополнительных запросов, пожалуйста, свяжитесь с нами.