Пузырьковая диаграмма в Chart.js расширяет точечную диаграмму за счёт
третьего измерения — радиуса окружности. Если в scatter-графике каждая
точка задаётся координатами x и y, то в
bubble-доске добавляется параметр r, определяющий размер
пузырька.
Базовая структура данных выглядит следующим образом:
const data = {
datasets: [
{
label: 'Набор данных',
data: [
{ x: 10, y: 20, r: 8 },
{ x: 15, y: 10, r: 12 },
{ x: 25, y: 30, r: 6 }
]
}
]
};
Каждый объект в массиве data содержит:
Радиус не является прямым значением масштаба в пикселях, Chart.js дополнительно нормализует его в зависимости от области отрисовки.
Для создания пузырьковой диаграммы используется тип
bubble:
const config = {
type: 'bubble',
data: data,
options: {
responsive: true,
scales: {
x: {
title: {
display: true,
text: 'Ось X'
}
},
y: {
title: {
display: true,
text: 'Ось Y'
}
}
}
}
};
new Chart(
document.getElementById('chart'),
config
);
Ключевой момент — обязательное использование числовых шкал
(linear, logarithmic), поскольку
категориальные оси не поддерживают корректную интерпретацию координат
пузырьков.
Значение r не отображается напрямую как пиксельный
радиус. Chart.js использует внутреннюю формулу нормализации:
r в наборе данных
вычисляются автоматическиЭто позволяет избежать ситуации, когда один большой пузырёк перекрывает весь график.
Контроль поведения осуществляется через параметр
pointRadius и настройки элементов:
options: {
elements: {
point: {
borderWidth: 1
}
}
}
Цвет и стилизация задаются на уровне датасета:
datasets: [
{
label: 'Продажи',
data: [
{ x: 5, y: 10, r: 10 },
{ x: 10, y: 15, r: 20 }
],
backgroundColor: 'rgba(54, 162, 235, 0.5)',
borderColor: 'rgba(54, 162, 235, 1)',
borderWidth: 1
}
]
Каждый пузырёк наследует стиль набора данных, но можно задавать индивидуальные цвета:
data: [
{ x: 10, y: 20, r: 8, backgroundColor: 'red' },
{ x: 15, y: 10, r: 12, backgroundColor: 'green' }
]
Bubble-диаграмма поддерживает несколько серий, что позволяет сравнивать группы объектов:
datasets: [
{
label: 'Группа A',
data: [
{ x: 10, y: 20, r: 8 },
{ x: 15, y: 25, r: 10 }
]
},
{
label: 'Группа B',
data: [
{ x: 12, y: 18, r: 12 },
{ x: 20, y: 30, r: 6 }
]
}
]
Каждая серия отображается отдельным цветом, а легенда автоматически
формируется на основе label.
Пузырьковая диаграмма чувствительна к настройкам осей. Основные параметры:
scales: {
x: {
type: 'linear',
min: 0,
max: 50
},
y: {
type: 'linear',
min: 0,
max: 50
}
}
Фиксация диапазонов позволяет стабилизировать визуализацию при динамических данных.
Дополнительно можно управлять сеткой:
grid: {
display: true,
color: 'rgba(200, 200, 200, 0.2)'
}
Tooltip в bubble-диаграммах часто требует кастомизации, так как кроме
x и y важно отображать r:
options: {
plugins: {
tooltip: {
callbacks: {
label: function(context) {
const point = context.raw;
return `x: ${point.x}, y: ${point.y}, r: ${point.r}`;
}
}
}
}
}
Это позволяет явно интерпретировать размер пузырька как дополнительную метрику.
При работе с большим количеством точек возникает проблема перекрытия пузырьков. Chart.js рисует элементы в порядке массива данных.
Для управления визуальной иерархией используется сортировка:
data.sort((a, b) => a.r - b.r);
Меньшие пузырьки можно рисовать поверх крупных или наоборот — в зависимости от цели визуализации.
Bubble-графики поддерживают стандартную систему анимаций Chart.js:
options: {
animation: {
duration: 1000,
easing: 'easeOutQuart'
}
}
При обновлении данных каждый пузырёк плавно изменяет позицию и радиус.
Изменение данных выполняется через update():
chart.data.datasets[0].data.push({ x: 30, y: 40, r: 15 });
chart.update();
Удаление элементов:
chart.data.datasets[0].data.pop();
chart.update();
Полная замена набора данных:
chart.data.datasets[0].data = newData;
chart.update();
При тысячах точек bubble-диаграмма может замедляться из-за:
Оптимизации:
decimation (в новых версиях
Chart.js)Chart.js позволяет отслеживать клики по пузырькам:
options: {
onClick: (event, elements) => {
if (elements.length > 0) {
const el = elements[0];
const data = el.element.$context.raw;
console.log(data);
}
}
}
Каждый элемент содержит доступ к исходному объекту данных, включая
r.
При использовании реальных метрик (например, продажи, население, стоимость) часто требуется нормализация:
const max = Math.max(...values);
const normalized = values.map(v => ({
x: v.x,
y: v.y,
r: (v.value / max) * 20
}));
Это предотвращает доминирование одного значения над остальными и делает распределение визуально читаемым.
Bubble-диаграммы иногда комбинируются с линейными или scatter-графиками в одном canvas через мульти-датасеты:
datasets: [
{
type: 'bubble',
data: [...]
},
{
type: 'line',
data: [...]
}
]
Это позволяет накладывать тренды поверх распределения точек и анализировать зависимости более глубоко.