2

I am using chartjs chart in my angular application. And I have using a standart web api result for charts.

this.httpClient.get(this.REST_API_SERVER).subscribe((data: any[])=>{
  console.log(data);

})  

data is:

[
   { "label": "city-1", "data1": 200},
   { "label": "city-2", "data1": 450},
   { "label": "city-2", "data1": 950},
]

or

[
   { "label": "city-1", "data1": 200, "data2": 60 },
   { "label": "city-2", "data1": 450, "data2": 40 },
   { "label": "city-3", "data1": 950, "data2": 78 },
]

I mean, label is label of chart and data1, data2 or data3 is values of chart.

So I want to split this response data to two different array like following.

var labels = [ "city-1", "city-3", "city-3"];
var data = [ 
              { "data": [ 200, 450, 950 ], "label": "data1" },
              { "data": [ 60,  40,  78 ], "label": "data2" }
           ];

is this possible in angular rxjs mapping?

2 Answers 2

2

You can use reduce() to transform the data in required format.

Iterate on given data and if an item with current label exists, then append values to its data array, if not create a new array item with current values.

let input = [
   { "label": "city-1", "data1": 200, "data2": 60 },
   { "label": "city-2", "data1": 450, "data2": 40 },
   { "label": "city-3", "data1": 950, "data2": 78 },
];

let result = input.reduce((acc, curr) => {
  acc.labels = acc.labels || [];
  acc.labels.push(curr.label);
  acc.data = acc.data || [];

  Object.entries(curr).forEach(([key, value]) => {
    if (key !== "label") {
      let item = acc.data.find(item => item.label === key);
      if (item) {
        item.data.push(value);
      } else {
        acc.data.push({
          "data": [value],
          "label": key
        });
      }
    }
  });

  return acc;
}, {});

let labels = result.labels;
let data = result.data;

console.log("Labels", labels);
console.log("Data", data);

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

Comments

1

You can find here a working script:

const list = [
   { "label": "city-1", "data1": 200, "data2": 60 },
   { "label": "city-2", "data1": 450, "data2": 40 },
   { "label": "city-3", "data1": 950, "data2": 78 },
]

const result = list.reduce((acc, item) => {

      const label = item['label'];
      acc[0].push(label);

      const keys = Object.keys(item).filter(key => key !== 'label');
      keys.forEach(key => {
        let labelItem = acc[1].find(value => value.label === key);
        if (!labelItem) {
          acc[1].push({ label:key, data: [item[key]] });
        } else {
          labelItem.data.push(item[key]);
        }
      });

      return acc;
    }, [[], []]);

console.log(result)

For typescript, you will need to add the type.

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.