typescript Angular 9 Chart.js多条堆叠条形图

b09cbbtk  于 2023-06-24  发布在  TypeScript
关注(0)|答案(1)|浏览(127)

我在Angular 9应用程序中实现了Chart.js。没有预期的图表值。
我有一个API响应,我想让barChartData如下所述stackblitz Demo.
这是我的API响应:

let data = [
  { operatorName: 'MBC', label: 'Application', subLabel: 'Positive', count: 1 },
  { operatorName: 'MBC', label: 'Channels', subLabel: 'Negative', count: -1 },
  { operatorName: 'MBC', label: 'Customer Care', subLabel: 'Negative', count: -1 },
  { operatorName: 'MBC', label: 'Customer Care', subLabel: 'Positive', count: 1 },
  { operatorName: 'OSEN+', label: 'Application', subLabel: 'Negative', count: -1 },
  { operatorName: 'OSEN+', label: 'Application', subLabel: 'Positive', count: 1 },
  { operatorName: 'OSEN+', label: 'Channels', subLabel: 'Positive', count: 1},
  { operatorName: 'OSEN+', label: 'Customer Care', subLabel: 'Positive', count: 1 }
];

我想用API响应设置barChartData
预期数据集:

this.barChartLabels = ['Application', 'Customer Care', 'Package'];
this.barChartData = [
  {
    label: 'OSEN+ Passtive',
    type: 'bar',
    stack: 'OSEN+',
    data: [30, 31, 23],
  },
  {
    label: 'OSEN+ Negative',
    type: 'bar',
    stack: 'OSEN+',
    data: [-15, -16],
  },
  {
    label: 'MBC Passtive',
    type: 'bar',
    stack: 'MBC',
    data: [20, 21],
  },
  {
    label: 'MBC Negative',
    type: 'bar',
    stack: 'MBC',
    data: [-10, -11],
  },
];

我尝试在这里实现逻辑:

let labels = [...new Set(data.map((x) => x.label))];
let operators = [...new Set(data.map((x) => x.operatorName))];
let subLabels = [...new Set(data.map((x) => x.subLabel))];
let subLabelDatasets = subLabels.map((x) => {
  let datasets = [];
  let opratorlabes = [];
  for (let label of labels) {
    datasets.push(
      data.find((y) => y.label == label && y.subLabel == x)?.count || 0
    );
  }

  //console.log(data)
  return {
    label: opratorlabes,
    data: datasets,
  };
});

预期结果:

ogq8wdun

ogq8wdun1#

与我以前写的answer相比,概念是相似的。
对于subLabels,由于需要按operatorNamesubLabel对数据进行分组,因此需要区分包含这两个属性的对象的分组。
subLabelDatasets中每个对象的dataset中,您可以通过从data数组中获取valueoperatorNamesubLabel来找到该值。

let labels = [...new Set(data.map((x) => x.label))];
let subLabels = data.reduce((acc, cur: any) => {
  if (
    acc.findIndex(
      (x) =>
        x.operatorName == cur.operatorName && x.subLabel == cur.subLabel
    ) == -1
  )
    acc.push({ operatorName: cur.operatorName, subLabel: cur.subLabel });

  return acc;
}, [] as { operatorName: string; subLabel: string }[]);

let subLabelDatasets = subLabels.map((x) => {
  let datasets = [];

  for (let label of labels) {
    datasets.push(
      data.find(
        (y) =>
          y.label == label &&
          y.subLabel == x.subLabel &&
          y.operatorName == x.operatorName
      )?.count || 0
    );
  }

  return {
    label: x.operatorName + ' ' + x.subLabel,
    data: datasets,
    stack: x.operatorName,
    type: 'bar',
  };
});

this.barChartLabels = labels;
this.barChartData = subLabelDatasets;

Demo @ StackBlitz

相关问题