Преобразование данных для графиков Chart.js с использованием JavaScript

Проблема с преобразованием данных для составного графика

Здравствуйте! Мне нужна помощь в преобразовании данных для создания составной диаграммы в Chart.js. Данные, которые я получаю от сервера, не подходят для использования в Chart.js. Я должен рассчитать процентное соотношение количества ключевых слов по конкретным категориям. Например, в случае с “Увольнениями” в “Продажах” значение составляет 56.52.

Полученные данные от сервера:

const inputData = [
  {
    title: 'Увольнения',
    keywordId: 1,
    verticalId: 1,
    verticalTitle: 'Продажи',
    keywordCount: 20,
  },
  {
    title: 'Прочие',
    keywordId: 2,
    verticalId: 1,
    verticalTitle: 'Продажи',
    keywordCount: 26,
  },
  {
    title: 'Прочие',
    keywordId: 2,
    verticalId: 2,
    verticalTitle: 'Маркетинг',
    keywordCount: 24,
  },
];

Что я уже попробовал:

const processedData = inputData.map((item) => {
  const vertTitle = item.verticalTitle;
  if (intermediateObj && vertTitle in intermediateObj) {
    intermediateObj[item.verticalTitle].total += item.keywordCount;
    intermediateObj[item.verticalTitle].items.push({ title: item.title, count: item.keywordCount });
  } else {
    intermediateObj[item.verticalTitle] = {};
    intermediateObj[item.verticalTitle].items = [];
    intermediateObj[item.verticalTitle].items.push({ title: item.title, count: item.keywordCount });
    intermediateObj[item.verticalTitle].total = item.keywordCount;
  }
});

for (let key in intermediateObj) {
  intermediateObj[key].items.forEach(el => {
    el.percentage = (el.count / intermediateObj[key].total) * 100;
  })
}

Ожидаемый результат для Chart.js:

Chart.js требует, чтобы массив datasets содержал объекты с массивами data. Если какое-либо название (ключевое слово, например, “Увольнения” или “Прочие”) отсутствует для определенной категории, мы должны добавить значение 0 в массив data по соответствующему индексу.

{
    labels: ['Продажи', 'Маркетинг'],
      datasets: [
        {
          label: 'Увольнения',
          data: [43.47, 0]
        },
        {
          label: 'Прочие',
          data: [56.52, 100]
        }
      ]
}

Заранее спасибо за вашу помощь!

Проблема в том, что ты используешь map для заполнения объекта - это не его задача. Лучше forEach или for…of. И intermediateObj у тебя вообще не объявлен. Я бы сделал проще: группируешь по verticals, считаешь totals, потом проходишь по всем уникальным titles и для каждого vertical либо берешь процент, либо ставишь 0. В 20 строк укладывается. И не забудь отсортировать labels перед созданием datasets, а то порядок поплывет.

Можно решить через reduce - создаешь промежуточный объект, потом собираешь финальный формат. Я бы сделал так: сначала собираю все уникальные titles и verticals, потом для каждого title создаю массив data. Для каждого vertical либо беру процент, либо ставлю 0. Главное - не забыть правильно посчитать total для каждой категории перед расчетом процентов. У меня была похожая задача с графиками продаж, этот подход отлично работает. И помни - порядок в массиве data должен соответствовать порядку в labels.

Двойной цикл тут поможет. Собери все уникальные titles в массив, потом для каждого title пробегись по всем verticals и найди соответствие. Нашел - считай процент, не нашел - ставь 0. Только сначала посчитай общий total для каждого vertical, а потом уже проценты.