Градиентная заливка в Chart.js строится на использовании возможностей
HTML Canvas API, в частности объекта CanvasGradient. Он
создаётся через 2D-контекст холста и применяется как значение свойств
визуализации данных, таких как backgroundColor,
borderColor и pointBackgroundColor.
Ключевая особенность заключается в том, что градиент нельзя задать
статически в конфигурации JSON — он формируется в момент рендеринга,
когда доступен контекст canvas.
В Chart.js доступ к контексту осуществляется через:
chart.ctx — 2D-контекст холстаchart.chartArea — область построения графикаcontext), позволяющие вычислять
значения динамическиЛинейный градиент создаётся методом:
const gradient = ctx.createLinearGradient(x0, y0, x1, y1);
Параметры задают направление:
(x0, y0) — начало градиента(x1, y1) — конец градиентаПосле создания добавляются цветовые остановки:
gradient.addColorStop(0, 'rgba(75, 192, 192, 0.8)');
gradient.addColorStop(1, 'rgba(75, 192, 192, 0.0)');
Наиболее частое использование — заполнение области под линией графика:
const ctx = document.getElementById('chart').getContext('2d');
const gradient = ctx.createLinearGradient(0, 0, 0, 400);
gradient.addColorStop(0, 'rgba(54, 162, 235, 0.6)');
gradient.addColorStop(1, 'rgba(54, 162, 235, 0)');
const chart = new Chart(ctx, {
type: 'line',
data: {
labels: ['Янв', 'Фев', 'Мар', 'Апр', 'Май'],
datasets: [{
label: 'Продажи',
data: [10, 25, 18, 30, 22],
backgroundColor: gradient,
borderColor: 'rgba(54, 162, 235, 1)',
fill: true,
tension: 0.4
}]
}
});
Градиент применяется как обычный цвет, но вместо строки используется объект CanvasGradient.
Жёстко заданные координаты (например, 400px) приводят к
проблемам при ресайзе. Более корректный подход — вычислять градиент
после определения области графика.
Используется доступ к chart.chartArea:
const chart = new Chart(ctx, {
type: 'line',
data: {
labels: ['A', 'B', 'C', 'D'],
datasets: [{
data: [5, 10, 7, 12],
fill: true,
backgroundColor: (context) => {
const chart = context.chart;
const { ctx, chartArea } = chart;
if (!chartArea) {
return null;
}
const gradient = ctx.createLinearGradient(
0,
chartArea.top,
0,
chartArea.bottom
);
gradient.addColorStop(0, 'rgba(255, 99, 132, 0.5)');
gradient.addColorStop(1, 'rgba(255, 99, 132, 0)');
return gradient;
}
}]
}
});
Такой подход обеспечивает адаптивность: градиент всегда совпадает с реальной высотой графика.
Chart.js поддерживает вычисляемые свойства через функцию:
backgroundColor: (context) => { ... }
Объект context содержит:
chart — экземпляр графикаdataIndex — индекс точкиdataset — данные набораtype — тип элементаЭто позволяет строить разные градиенты в зависимости от данных.
Пример градиента, зависящего от значения:
backgroundColor: (context) => {
const value = context.raw;
const ctx = context.chart.ctx;
const chartArea = context.chart.chartArea;
if (!chartArea) return null;
const gradient = ctx.createLinearGradient(
0,
chartArea.bottom,
0,
chartArea.top
);
if (value > 20) {
gradient.addColorStop(0, 'rgba(40, 167, 69, 0.6)');
gradient.addColorStop(1, 'rgba(40, 167, 69, 0)');
} else {
gradient.addColorStop(0, 'rgba(220, 53, 69, 0.6)');
gradient.addColorStop(1, 'rgba(220, 53, 69, 0)');
}
return gradient;
}
Кроме линейного градиента используется
createRadialGradient:
const gradient = ctx.createRadialGradient(
200, 200, 0,
200, 200, 200
);
gradient.addColorStop(0, 'rgba(255, 206, 86, 0.8)');
gradient.addColorStop(1, 'rgba(255, 206, 86, 0)');
Параметры:
В Chart.js такой градиент часто применяется для точечных графиков и bubble chart.
Основное применение — заливка под линией:
fill: truebackgroundColor: CanvasGradientКаждая колонка может иметь собственный градиент:
backgroundColor: (context) => {
const chart = context.chart;
const { ctx, chartArea } = chart;
if (!chartArea) return null;
const gradient = ctx.createLinearGradient(0, chartArea.bottom, 0, chartArea.top);
gradient.addColorStop(0, 'rgba(54, 162, 235, 0.2)');
gradient.addColorStop(1, 'rgba(54, 162, 235, 0.9)');
return gradient;
}
Используется радиальный градиент для эффекта объёма:
const gradient = ctx.createRadialGradient(150, 150, 50, 150, 150, 150);
gradient.addColorStop(0, '#4bc0c0');
gradient.addColorStop(1, '#1e7f7f');
Создание градиента на каждый рендер может быть затратным. Оптимизация заключается в кэшировании:
let cachedGradient = null;
function getGradient(chart) {
const { ctx, chartArea } = chart;
if (!chartArea) return null;
if (cachedGradient) return cachedGradient;
const gradient = ctx.createLinearGradient(
0,
chartArea.bottom,
0,
chartArea.top
);
gradient.addColorStop(0, 'rgba(153, 102, 255, 0.6)');
gradient.addColorStop(1, 'rgba(153, 102, 255, 0)');
cachedGradient = gradient;
return gradient;
}
Кэширование особенно важно при анимации и частых обновлениях данных.
Градиенты должны пересоздаваться при изменении:
Chart.js вызывает повторный рендер, но не всегда пересоздаёт
контекстные объекты автоматически. Поэтому использование
context.chart.chartArea внутри функции — обязательная
практика для стабильной отрисовки.
chartAreaundefined вместо null в scriptable
optionschartAreaДополнительная выразительность достигается через:
rgba с альфа-каналомborderColor с высокой насыщенностьюpointBackgroundColor для акцентовПример:
borderColor: 'rgba(75, 192, 192, 1)',
backgroundColor: gradient,
pointBackgroundColor: 'rgba(75, 192, 192, 1)'
Также можно использовать borderWidth и
tension для усиления визуального эффекта плавности.
При обновлении данных градиент остаётся синхронизированным с
геометрией графика, если он вычисляется через context. Это
позволяет сохранять визуальную целостность при:
Градиент становится частью реактивной модели визуализации, а не статическим стилем.