1

I'm trying to populate some data I'm receiving from an API into a chart, and for it to "work properly" I need to make sure that each object in the array has 12 values under the sum property (one value for each month of the year).

The data I receive from the API looks like this:

[
  {
    "sum": {
      "201901": 8,
      "201902": 16,
      "201903": 8,
      "201904": 8,
      /* This project is missing data for month 5 and 6 */
      "201907": 5,
      "201908": 2,
      "201909": 0,
      "201910": 2,
      "201911": 5,
      "201912": 8
    },
    "project": "Project Name 1"
  },
  {
    "sum": {
      "201901": 9,
      "201902": 18,
      "201903": 9,
      "201904": 9,
      "201905": 17,
      "201906": 5,
      "201907": 2,
      "201908": 4,
      /* This project is missing data for month 9, 10, 11, 12 */
    },
    "project": "Project Name 2"
  },
  {
    "sum": {
      "201901": 2,
      "201902": 2,
      "201903": 5,
      "201904": 2,
      "201905": 0,
      "201906": 10,
      "201907": 45,
      "201908": 21,
      "201909": 3,
      "201910": 2,
      "201911": 17,
      "201912": 16
    },
    "project": "Project Name 3"
  }
]

So, as you can see, project 1 and project 2 are missing points for some months, but I still need to populate them with an empty value (example: "201905": 0, "201906": 0, etc) because the X-axis in my chart will always be 12 values and it messes things up if the Y-axis does not have 12 values given. So my question is: how would I populate each object to always provide a value for each month of the year?

So far, I'm looping through the data as such:

for (let key in this.chartData) {
    emptyArr.push({
        name: this.chartData[key].project,
        data: Object.values(this.chartData[key].sum),
    });
}

which effectively gives me something to work with:

[
  {
    "name": "Project 1",
    "data": [8, 16, 8, 8, 21, 4, 5, 2, 0, 2, 5, /*Need a "0" here*/]
  },
  {
    "name": "Project 2",
    "data": [9, 18, 9, 9, 17, 5, 2, 4, /*Need 4 more 0's here*/]
  },
  {
    "name": "Project 3",
    "data": [2, 2, 5, 2, 0, 10, 45, 21, 3, 2, 17, 16]
  }
]
2
  • What library are you using to render chart? Lot of libs actually have an option to automatically fill missing values Commented Aug 13, 2019 at 21:04
  • A wrapper for apexcharts - VueApexCharts Commented Aug 13, 2019 at 21:07

3 Answers 3

1

If you define an object with all the 12 keys, such as:

const normalizedSum = {
  "201901": 0,
  "201902": 0,
  "201903": 0,
  "201904": 0,
  "201905": 0,
  "201906": 0,
  "201907": 0,
  "201908": 0,
  "201909": 0,
  "201910": 0,
  "201911": 0,
  "201912": 0
};

Then, you can use Array.map() on your input array like this:

input.map(({sum, project}) => ({sum: {...normalizedSum, ...sum}, project}));

Full Example:

const input = [{"sum":{"201901":8,"201902":16,"201903":8,"201904":8,"201907":5,"201908":2,"201909":0,"201910":2,"201911":5,"201912":8},"project":"Project Name 1"},{"sum":{"201901":9,"201902":18,"201903":9,"201904":9,"201905":17,"201906":5,"201907":2,"201908":4,},"project":"Project Name 2"},{"sum":{"201901":2,"201902":2,"201903":5,"201904":2,"201905":0,"201906":10,"201907":45,"201908":21,"201909":3,"201910":2,"201911":17,"201912":16},"project":"Project Name 3"}];

const normalizedSum = {
  "201901": 0,
  "201902": 0,
  "201903": 0,
  "201904": 0,
  "201905": 0,
  "201906": 0,
  "201907": 0,
  "201908": 0,
  "201909": 0,
  "201910": 0,
  "201911": 0,
  "201912": 0
};

let res = input.map(
  ({sum, project}) => ({sum: {...normalizedSum, ...sum}, project})
);

console.log(res);
.as-console {background-color:black !important; color:lime;}
.as-console-wrapper {max-height:100% !important; top:0;}

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

Comments

1

You could take an empty sum object and assign the values to a new object.

var data = [{ sum: { 201901: 8, 201902: 16, 201903: 8, 201904: 8, 201907: 5, 201908: 2, 201909: 0, 201910: 2, 201911: 5, 201912: 8 }, project: "Project Name 1" }, { sum: { 201901: 9, 201902: 18, 201903: 9, 201904: 9, 201905: 17, 201906: 5, 201907: 2, 201908: 4 }, project: "Project Name 2" }, { sum: { 201901: 2, 201902: 2, 201903: 5, 201904: 2, 201905: 0, 201906: 10, 201907: 45, 201908: 21, 201909: 3, 201910: 2, 201911: 17, 201912: 16 }, project: "Project Name 3" }], empty = { 201901: 0, 201902: 0, 201903: 0, 201904: 0, 201905: 0, 201906: 0, 201907: 0, 201908: 0, 201909: 0, 201910: 0, 201911: 0, 201912: 0 },
    empty = { 201901: 0, 201902: 0, 201903: 0, 201904: 0, 201905: 0, 201906: 0, 201907: 0, 201908: 0, 201909: 0, 201910: 0, 201911: 0, 201912: 0 },
    result = data.map(({ sum, ...rest }) => ({ sum: { ...empty, ...sum }, ...rest }));

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Comments

1

What you can do is make a template object which has all the 12 months with default values of 0. Then go through the sum items and if they have the matching date key then set it to the value of the key in sum:

for (let key in chartData) {
  // template object holding 0s
  let data = { "201901": 0, "201902": 0, "201903": 0, "201904": 0, "201905": 0, "201906": 0, "201907": 0, "201908": 0, "201909": 0, "201910": 0, "201911": 0, "201912": 0 };
  // For each key that exist in the sum object populate data with that value
  for (let month in chartData[key].sum) data[month] = chartData[key].sum[month];

  emptyArr.push({
    name: chartData[key].project,
    data: Object.values(data), // Now you can do the same thing you where doing before
  });
}

Here is a full example:

let chartData = [
  {
    "sum": {
      "201901": 8,
      "201902": 16,
      "201903": 8,
      "201904": 8,
      /* This project is missing data for month 5 and 6 */
      "201907": 5,
      "201908": 2,
      "201909": 0,
      "201910": 2,
      "201911": 5,
      "201912": 8
    },
    "project": "Project Name 1"
  },
  {
    "sum": {
      "201901": 9,
      "201902": 18,
      "201903": 9,
      "201904": 9,
      "201905": 17,
      "201906": 5,
      "201907": 2,
      "201908": 4,
      /* This project is missing data for month 9, 10, 11, 12 */
    },
    "project": "Project Name 2"
  },
  {
    "sum": {
      "201901": 2,
      "201902": 2,
      "201903": 5,
      "201904": 2,
      "201905": 0,
      "201906": 10,
      "201907": 45,
      "201908": 21,
      "201909": 3,
      "201910": 2,
      "201911": 17,
      "201912": 16
    },
    "project": "Project Name 3"
  }
];

let emptyArr = []

for (let key in chartData) {
	let data = { "201901": 0, "201902": 0, "201903": 0, "201904": 0, "201905": 0, "201906": 0, "201907": 0, "201908": 0, "201909": 0, "201910": 0, "201911": 0, "201912": 0 };
	for (let month in chartData[key].sum) data[month] = chartData[key].sum[month];
  	
  emptyArr.push({
    name: chartData[key].project,
    data: Object.values(data),
  });
}

console.log(emptyArr);

Comments

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.