2

Explanation of what i am doing right now:

This resembles the data array I get from the API response

responseBarDataStacked = [
    { sku: "Data 1", month: "Jun", value: 20 },
    { sku: "Data 2", month: "Jun", value: 25 },
    { sku: "Data 3", month: "Jun", value: 35 },
    { sku: "Data 4", month: "Jun", value: 10 },
    { sku: "Data 5", month: "Jun", value: 10 },
    { sku: "Data 1", month: "Jul", value: 20 },
    { sku: "Data 2", month: "Jul", value: 30 },
    { sku: "Data 3", month: "Jul", value: 15 },
    { sku: "Data 4", month: "Jul", value: 20 },
    { sku: "Data 5", month: "Jul", value: null },
    { sku: "Data 1", month: "Aug", value: 20 },
    { sku: "Data 2", month: "Aug", value: 30 },
    { sku: "Data 3", month: "Aug", value: 15 },
    { sku: "Data 4", month: "Aug", value: 20 },
    { sku: "Data 5", month: "Aug", value: 15 },
];

Note: this only resembles the data, it does not mean there will be only 5 sets of sku data or 3 months all the time. but is sure that sku or month will not be null.

I am trying to use this response data on Charts (ng2-chart), for Stacked Bar Graph. For this data to work on Stacked Bar Chart, I needed to format the data with some logic so that I'll get final data as such,

{
  data: [20, 25, 35, 10, 10], label: 'Jun', stack: 'sameStack',
  data: [20, 30, 15, 20, null], label: 'Jul', stack: 'sameStack',
  data: [20, 30, 15, 20, 15], label: 'Aug', stack: 'sameStack',
}

If you see for data array it is arranged in order as this

data: [valueof[Data 1] for month Jun, valueof[Data 2] for month Jun, valueof[Data 3] for month Jun, valueof[Data 3] for month Jun, valueof[Data 5] for month Jun]

and so on and so forth for others.

Why is this particular order?? Because if you see below in the method formatStackedBarData() uniqueSku is set in FCFS i.e.

["Data 1", "Data 2", "Data 3", "Data 4", "Data 5"]

This is the method I am using to format the data accordingly.

  formatStackedBarData(dataToFormat: Array<any>) {
    let uniqueMonth = [...new Set(dataToFormat.map(item => item.month))];
    let uniqueSku = [...new Set(dataToFormat.map(item => item.sku))];
    let stackedBarChartData = [];

    uniqueMonth.forEach(month => {
      let uniqueMonthData = dataToFormat
        .filter(barStackData => barStackData.month == month)
        .map(uniqueStackData => uniqueStackData.value);
      stackedBarChartData.push({
        data: uniqueMonthData,
        label: month,
        stack: 'sameStack'
      });
    });

    return {
      stackedBarChartData,
      uniqueSku
    };
  }

Question:

Now when the response is jumbled up or if the order is changed for sku, I am not able to get appropriate data on the stackedBarChartData.

Now the response data is changed as such

  responseBarDataStacked = [
    { sku: 'Data 1', month: 'Jun', value: 20 },
    { sku: 'Data 2', month: 'Jun', value: 25 },
    { sku: 'Data 3', month: 'Jun', value: 35 },
    { sku: 'Data 5', month: 'Jun', value: 10 },
    { sku: 'Data 1', month: 'Jul', value: 20 },
    { sku: 'Data 2', month: 'Jul', value: 30 },
    { sku: 'Data 1', month: 'Aug', value: 20 },
    { sku: 'Data 2', month: 'Aug', value: 30 },
    { sku: 'Data 3', month: 'Aug', value: 15 },
    { sku: 'Data 4', month: 'Aug', value: 20 },
    { sku: 'Data 5', month: 'Aug', value: 15 }
  ];

As you may see

  • there is no Data 4 for month of Jun
  • there is no Data 3, Data 4, and Data 5 for month of Jul

For such case, expected value for stackedBarChartData is like this

[
  {data:[20, 25, 35, 10, null], label: 'Jun', stack: 'sameStack'},
  {data:[20, 30, null, null, null], label: 'Jun', stack: 'sameStack'},
  {data:[20, 30, 15, 15, 20], label: 'Jun', stack: 'sameStack'},
]

Note: If you see there in the first object's data, last value is null, this is because when uniquesku is create, the array will be like, This is because of FCFS used, and Data 5 comes before Data 4 in our API Response.

["Data 1", "Data 2", "Data 3", "Data 5", "Data 4"]

For the ease, I have implemented it here to test. stackblitz implementation

2
  • 2
    What is your question? Commented Jun 18, 2021 at 17:46
  • @GaëlJ I have added details, please have a look at it again. Let me know if it is still not clear. Commented Jun 18, 2021 at 17:56

1 Answer 1

2

You can get all unique sku by using array#map and Set. Once you have this array, you can create an order object which will map sku with index, which will be used to assign value to data for a given sku value.

Now, using array#reduce you can group the data based on month and populate the data based on the sku value.

const dataToFormat = [ { sku: 'Data 1', month: 'Jun', value: 20 }, { sku: 'Data 2', month: 'Jun', value: 25 }, { sku: 'Data 3', month: 'Jun', value: 35 }, { sku: 'Data 5', month: 'Jun', value: 10 }, { sku: 'Data 1', month: 'Jul', value: 20 }, { sku: 'Data 2', month: 'Jul', value: 30 }, { sku: 'Data 1', month: 'Aug', value: 20 }, { sku: 'Data 2', month: 'Aug', value: 30 }, { sku: 'Data 3', month: 'Aug', value: 15 }, { sku: 'Data 4', month: 'Aug', value: 20 }, { sku: 'Data 5', month: 'Aug', value: 15 } ],
      uniqueSku = [...new Set(dataToFormat.map(item => item.sku))],
      order = Object.fromEntries(uniqueSku.map((v,i) => ([v, i]))),
      result = Object.values(dataToFormat.reduce((r, {month, value, sku}) => {
        r[month] ||= {data: Array(uniqueSku.length).fill(null), label: month, stack: 'sameStack'};
        r[month].data[order[sku]] = value;
        return r;
      },{}));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Sign up to request clarification or add additional context in comments.

8 Comments

Thanks for your time, but the results are not as expected, if you see for month of June, I am getting only 4 data, and for month of July I am getting just 2. I have updated my question some extra details and expected results. Could you please look into that?
Can you check now if the solution is as per your expectation?
Now, if we look at the data for month of August, it should be [data1, data2, data3, data5, data4] first data5 and then data4 because uniqueSku will be set like that.
For Aug this would be "data": [20,30,15,15,20]
Please check now.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.