Ramesh S
Ramesh S

Reputation: 661

Angular ApexCharts - Transform data to display as bar chart

I have used ApexCharts in my Angular 16 application.

Here my response is not appending on the chart. Please help me to modify the API response.

Response from API:

let data = [
  {
    tenantName: 'OBC+',
    labelName: 'Application',
    total: 85,
    postiveTotal: '21',
    negativeTotal: '64',
  },
  {
    tenantName: 'Discovery-world',
    labelName: 'Application',
    total: 194,
    postiveTotal: '119',
    negativeTotal: '75',
  },
  {
    tenantName: 'OBC+',
    labelName: 'Channels',
    total: 40,
    postiveTotal: '0',
    negativeTotal: '40',
  },
  {
    tenantName: 'Discovery-world',
    labelName: 'Channels',
    total: 59,
    postiveTotal: '0',
    negativeTotal: '59',
  },
];

I need to modify my response with this format.

Expected Format:

this.stackedChartData = [
  {
    name: 'OBC Postivie',
    group: 'OBC',
    data: [21, 0],
  },
  {
    name: 'OBC Negative',
    group: 'OBC',
    data: [64, 40],
  },
  {
    name: 'Discovery-world Postivie',
    group: 'Discovery-world',
    data: [119, 0],
  },
  {
    name: 'Discovery-world Negative',
    group: 'Discovery-world',
    data: [75, 59],
  },
];

I have tried with this code but it is not working properly.

let labels = [...new Set(data.map((x: any) => x.labelName))];
let subLabels = data.reduce((acc, cur: any) => {
  if (
    acc.findIndex(
      (x) =>
        //console.log(x)
        x.tenantName == cur.tenantName && x.labelName == cur.labelName
    ) == -1
  )
    acc.push({
      tenantName: cur.tenantName,
      labelName: cur.labelName,
      postiveTotal: cur.postiveTotal,
      negativeTotal: cur.negativeTotal,
    });

  return acc;
}, [] as { tenantName: string; labelName: string; postiveTotal: number; negativeTotal: number }[]);

console.log(subLabels);

I am going to try postiveTotal, negativeTotal with group of labelName.

This is my chart demo link.

Upvotes: 0

Views: 604

Answers (1)

Yong Shun
Yong Shun

Reputation: 51195

You are in the right way to iterate and transform the array via .reduce().

Changes that you need:

  1. The result of the array should be in { group: string; name: string; data: number[] }[] type.

  2. Check the group whether it was inserted previously. If not inserted, you should add two objects with "Positive" and "Negative".

  3. If the group is inserted previously, get the objects by group and name and add the value into data array in the object.

let subLabels = data.reduce((acc, cur: any) => {
  if (
    acc.findIndex(
      (x) =>
        x.group == cur.tenantName
    ) == -1
  ) {
    acc.push({
      group: cur.tenantName,
      name: cur.tenantName + ' Positive',
      data: [Number(cur.postiveTotal)],
    });

    acc.push({
      group: cur.tenantName,
      name: cur.tenantName + ' Negative',
      data: [Number(cur.negativeTotal)],
    });
  } else {
    let groupPositive = acc.find(
      (x) =>
        x.group == cur.tenantName && x.name == cur.tenantName + ' Positive'
    );

    groupPositive.data.push(Number(cur.postiveTotal));

    let groupNegative = acc.find(
      (x) =>
        x.group == cur.tenantName && x.name == cur.tenantName + ' Negative'
    );

    groupNegative.data.push(Number(cur.negativeTotal));
  }

  return acc;
}, [] as { group: string; name: string; data: number[] }[]);

this.stackedChartData = subLabels;

Demo @ StackBlitz

Upvotes: 1

Related Questions