Смешанные типы на одном холсте

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

Ключевая особенность заключается в том, что тип графика может задаваться как на уровне всей диаграммы, так и индивидуально для каждого набора данных. Это создаёт гибкость, при которой один и тот же контекст данных может быть интерпретирован по-разному.

В Chart.js смешанный график обычно строится на основе одного основного типа, который задаётся на уровне конфигурации, при этом отдельные datasets могут переопределять этот тип.

const config = {
  type: 'bar',
  data: {
    labels: ['Янв', 'Фев', 'Мар', 'Апр'],
    datasets: [
      {
        type: 'bar',
        label: 'Продажи',
        data: [30, 50, 40, 60]
      },
      {
        type: 'line',
        label: 'Тренд',
        data: [35, 45, 42, 58],
        borderColor: 'blue',
        fill: false
      }
    ]
  }
};

new Chart(document.getElementById('chart'), config);

В данном случае базовый тип задан как столбчатый, но второй набор данных явно переопределяет тип на линейный, что приводит к наложению линии поверх столбцов.

Переопределение типа на уровне dataset

Chart.js обрабатывает каждый dataset независимо. Это означает, что:

  • глобальный type действует как значение по умолчанию
  • dataset.type имеет приоритет над глобальным значением

Такой механизм позволяет строить сложные гибридные визуализации без необходимости создавать несколько отдельных графиков.

datasets: [
  {
    label: 'Фактические значения',
    type: 'bar',
    data: [10, 20, 15, 30]
  },
  {
    label: 'Прогноз',
    type: 'line',
    data: [12, 18, 17, 28]
  }
]

Подобная модель часто используется для сравнения факта и прогноза.

Совмещение несовместимых типов

Некоторые типы диаграмм используют разные системы координат или поведение рендеринга. Например, bar, line и scatter могут быть легко объединены, в то время как более специфические типы требуют дополнительной настройки.

Наиболее распространённая комбинация:

  • столбчатая диаграмма + линейная
  • линейная + точечная
  • линейная + пузырьковая (bubble)

Пример с точками и линией:

const config = {
  type: 'line',
  data: {
    datasets: [
      {
        type: 'line',
        label: 'Скользящая средняя',
        data: [5, 10, 15, 20],
        borderColor: 'green'
      },
      {
        type: 'scatter',
        label: 'Сырые данные',
        data: [
          { x: 1, y: 4 },
          { x: 2, y: 12 },
          { x: 3, y: 14 },
          { x: 4, y: 19 }
        ],
        backgroundColor: 'red'
      }
    ]
  }
};

Здесь используется разный формат данных: массив значений и координаты {x, y}, что демонстрирует гибкость системы парсинга Chart.js.

Работа с осями в смешанных графиках

При комбинировании типов часто возникает необходимость разделять шкалы. Это особенно важно при сопоставлении данных разного масштаба.

Chart.js позволяет использовать несколько осей через yAxisID.

const config = {
  type: 'bar',
  data: {
    labels: ['A', 'B', 'C', 'D'],
    datasets: [
      {
        label: 'Доход',
        data: [100, 200, 150, 300],
        yAxisID: 'y'
      },
      {
        label: 'Процент роста',
        type: 'line',
        data: [5, 10, 7, 12],
        yAxisID: 'y1',
        borderColor: 'orange'
      }
    ]
  },
  options: {
    scales: {
      y: {
        type: 'linear',
        position: 'left'
      },
      y1: {
        type: 'linear',
        position: 'right',
        grid: {
          drawOnChartArea: false
        }
      }
    }
  }
};

Использование двух осей позволяет избежать искажения визуального восприятия, когда значения имеют разные порядки величин.

Смешивание временных и категориальных шкал

Chart.js поддерживает временные оси (time scale), что особенно полезно при комбинировании трендов и событий.

const config = {
  type: 'line',
  data: {
    datasets: [
      {
        type: 'line',
        label: 'Температура',
        data: [
          { x: '2024-01-01', y: 2 },
          { x: '2024-01-02', y: 4 },
          { x: '2024-01-03', y: 3 }
        ]
      },
      {
        type: 'scatter',
        label: 'Аномалии',
        data: [
          { x: '2024-01-02', y: 6 }
        ]
      }
    ]
  },
  options: {
    scales: {
      x: {
        type: 'time'
      }
    }
  }
};

Подобная комбинация используется для выделения событий на фоне непрерывного процесса.

Наложение линий на столбцы

Один из наиболее практичных сценариев — сравнение фактических значений с эталонными через комбинацию bar + line.

const config = {
  type: 'bar',
  data: {
    labels: ['Q1', 'Q2', 'Q3', 'Q4'],
    datasets: [
      {
        label: 'Факт',
        data: [40, 55, 60, 70],
        backgroundColor: 'rgba(0, 123, 255, 0.5)'
      },
      {
        type: 'line',
        label: 'План',
        data: [45, 50, 65, 75],
        borderColor: 'black',
        borderWidth: 2,
        fill: false,
        tension: 0.3
      }
    ]
  }
};

Линия при этом визуально становится ориентиром, а столбцы показывают фактическое выполнение.

Порядок отрисовки и приоритет слоёв

В смешанных графиках порядок dataset влияет на визуальное перекрытие. Последние элементы массива рисуются поверх предыдущих, если не заданы дополнительные параметры управления порядком.

Дополнительный контроль возможен через:

  • order у dataset
  • z в некоторых конфигурациях элементов
datasets: [
  {
    type: 'bar',
    order: 2,
    data: [10, 20, 30]
  },
  {
    type: 'line',
    order: 1,
    data: [15, 25, 35]
  }
]

В этом случае линия будет визуально поверх столбцов независимо от порядка в массиве.

Смешивание пузырьковых и линейных данных

Bubble chart вводит третье измерение через параметр r, что добавляет дополнительную ось интерпретации.

const config = {
  type: 'bubble',
  data: {
    datasets: [
      {
        type: 'bubble',
        label: 'Рынок',
        data: [
          { x: 10, y: 20, r: 5 },
          { x: 15, y: 10, r: 8 }
        ],
        backgroundColor: 'rgba(255,0,0,0.4)'
      },
      {
        type: 'line',
        label: 'Тренд',
        data: [
          { x: 10, y: 18 },
          { x: 15, y: 12 }
        ],
        borderColor: 'blue'
      }
    ]
  }
};

Такая комбинация применяется в аналитике, где требуется сопоставить плотность или вес с динамикой изменения.

Особенности взаимодействия и tooltip

В смешанных графиках tooltip агрегирует данные по точке пересечения координат. Это означает, что при наведении курсора отображаются значения всех datasets, попадающих в одну категорию или координату.

Настройка поведения:

options: {
  interaction: {
    mode: 'index',
    intersect: false
  }
}
  • index — группировка по индексу категории
  • nearest — ближайшая точка независимо от набора данных
  • intersect — строгое попадание в точку

Практические ограничения смешанных графиков

При объединении типов важно учитывать:

  • несовместимость некоторых scale типов
  • различия в формате данных (категории vs координаты)
  • нагрузку на рендер при большом числе datasets
  • визуальную перегруженность при более чем 3–4 слоях

Чрезмерное количество комбинаций ухудшает читаемость, особенно при использовании разных систем масштабирования одновременно.

Управление стилями в гибридных диаграммах

Каждый dataset сохраняет независимые стили:

  • backgroundColor
  • borderColor
  • borderWidth
  • pointRadius
  • tension
{
  type: 'line',
  borderColor: '#4bc0c0',
  borderWidth: 3,
  pointRadius: 2,
  tension: 0.4
}

Согласованное стилевое оформление критично при смешивании визуальных типов, так как различие форм уже создаёт сильную когнитивную нагрузку.