Графики Chart.js рендерятся внутри HTML5 <canvas>,
что позволяет напрямую извлекать растровое изображение без серверной
обработки. После построения диаграммы доступ к пиксельному буферу
осуществляется через методы canvas или экземпляра графика.
Ключевая функция для экспорта:
chart.toBase64Image()
Результат выполнения — строка в формате Data URL, содержащая PNG-изображение:
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgA...
Эта строка может использоваться как:
<img>const chart = new Chart(ctx, {
type: 'bar',
data: {
labels: ['A', 'B', 'C'],
datasets: [{
label: 'Пример',
data: [10, 20, 30]
}]
}
});
const base64Image = chart.toBase64Image();
const img = document.createElement('img');
img.src = base64Image;
document.body.appendChild(img);
Для преобразования base64 в загружаемый файл используется создание временной ссылки:
function downloadChart(chart, filename = 'chart.png') {
const link = document.createElement('a');
link.href = chart.toBase64Image();
link.download = filename;
link.click();
}
Механизм работает без серверной стороны, полностью на клиенте.
Метод toBase64Image() поддерживает дополнительные
настройки, влияющие на качество итогового изображения.
chart.toBase64Image('image/png', 1)
Параметры:
type — формат изображения (image/png,
image/jpeg)quality — коэффициент качества от 0 до
1 (для JPEG)Для PNG параметр качества игнорируется, так как формат без потерь.
По умолчанию экспорт соответствует размеру canvas. Для улучшения четкости используется масштабирование через device pixel ratio.
function exportHighResolution(chart, scale = 2) {
const originalWidth = chart.width;
const originalHeight = chart.height;
const tempCanvas = document.createElement('canvas');
tempCanvas.width = originalWidth * scale;
tempCanvas.height = originalHeight * scale;
const ctx = tempCanvas.getContext('2d');
ctx.scale(scale, scale);
ctx.drawImage(chart.canvas, 0, 0);
return tempCanvas.toDataURL('image/png');
}
Такой подход повышает детализацию при печати и вставке в документы.
toBase64Image() и canvas.toDataURL()Chart.js предоставляет обертку над стандартным API canvas:
| Метод | Назначение |
|---|---|
chart.toBase64Image() |
Экспорт с учетом внутренних настроек Chart.js |
canvas.toDataURL() |
Прямой снимок canvas без логики библиотеки |
Различие проявляется при наличии:
Chart.js по умолчанию поддерживает анимации, которые могут быть активны в момент вызова экспорта.
Чтобы получить статичное изображение, анимацию отключают:
const chart = new Chart(ctx, {
type: 'line',
data: {...},
options: {
animation: false
}
});
Альтернативный вариант — временное отключение:
chart.options.animation = false;
chart.update();
const img = chart.toBase64Image();
Canvas по умолчанию имеет прозрачный фон, что влияет на результат PNG.
Для задания фона используется плагин или кастомный рендер:
const chart = new Chart(ctx, {
type: 'bar',
data: {...},
options: {
plugins: {
legend: { display: true }
}
},
plugins: [{
id: 'custom_bg',
beforeDraw: (chart) => {
const ctx = chart.ctx;
ctx.save();
ctx.fillStyle = '#ffffff';
ctx.fillRect(0, 0, chart.width, chart.height);
ctx.restore();
}
}]
});
При использовании изображений в датасетах (например, иконок или фоновых картинок) canvas может быть “tainted”, если ресурсы загружены с внешнего домена без CORS-заголовков.
Последствия:
toBase64Image() выбрасывает ошибку безопасностиtoDataURL() блокируется браузеромРешение:
image: {
src: 'https://example.com/image.png',
crossOrigin: 'anonymous'
}
И сервер должен отдавать:
Access-Control-Allow-Origin: *
При работе с набором диаграмм возможна пакетная генерация изображений:
function exportCharts(charts) {
return charts.map((chart, index) => ({
id: index,
image: chart.toBase64Image()
}));
}
Результат может использоваться для формирования отчётов или загрузки на сервер.
Base64-строка передается как обычные данные:
fetch('/upload', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
image: chart.toBase64Image()
})
});
На сервере строка декодируется в бинарный PNG-файл.
Base64 увеличивает размер данных примерно на 33% по сравнению с бинарным PNG. Для оптимизации применяются:
responsive: falseoptions: {
responsive: false,
elements: {
point: { radius: 0 }
}
}
Экспорт через toBase64Image() часто применяется в
системах:
Полученное изображение интегрируется как статический ресурс без зависимости от Chart.js.