1๐
โ
My solution will create chartjs data with two steps first step I will create grouping data and template data.
- Grouping data which contain each
name
andverticalName
with hiscountOfKeywords
. - Template data which contain chartjs data with 0 percentages
Second step I will get data from grouping and put it in the template.
Input
const array = [
{
name: 'Attrition',
verticalName: 'BCM',
countOfKeywords: 20,
},
{
name: 'Others',
verticalName: 'BCM',
countOfKeywords: 26,
},
{
name: 'Others',
verticalName: 'CGLR',
countOfKeywords: 24,
},
{
name: 'Attrition',
verticalName: 'NEW',
countOfKeywords: 20,
},
{
name: 'Others',
verticalName: 'NEW',
countOfKeywords: 1,
},
];
After Grouping
{
"BCM": {
"sum": 46,
"keywords": {
"Attrition": 20,
"Others": 26
}
},
"CGLR": {
"sum": 24,
"keywords": {
"Others": 24
}
},
"NEW": {
"sum": 21,
"keywords": {
"Attrition": 20,
"Others": 1
}
}
}
Template
{
"labels": [
"BCM",
"CGLR",
"NEW"
],
"datasets": [
{
"label": "Attrition",
"data": [
0,
0,
0
]
},
{
"label": "Others",
"data": [
0,
0,
0
]
}
]
}
Output
{
"labels": [
"BCM",
"CGLR",
"NEW"
],
"datasets": [
{
"label": "Attrition",
"data": [
43.47826086956522,
0,
95.23809523809523
]
},
{
"label": "Others",
"data": [
56.52173913043478,
100,
4.761904761904762
]
}
]
}
Full code
// input
const array = [
{
name: 'Attrition',
verticalName: 'BCM',
countOfKeywords: 20,
},
{
name: 'Others',
verticalName: 'BCM',
countOfKeywords: 26,
},
{
name: 'Others',
verticalName: 'CGLR',
countOfKeywords: 24,
},
{
name: 'Attrition',
verticalName: 'NEW',
countOfKeywords: 20,
},
{
name: 'Others',
verticalName: 'NEW',
countOfKeywords: 1,
},
];
// declare variables
let uniqueNames = new Set();
const grouping = {};
const template = {
labels: [],
datasets: []
}
// create grouping object and create template labels
for (let i = 0; i < array.length; i += 1) {
const element = array[i];
if (grouping[element.verticalName] === undefined) {
template.labels.push(element.verticalName);
grouping[element.verticalName] = { sum: 0, keywords: {} };
};
grouping[element.verticalName].sum += element.countOfKeywords;
grouping[element.verticalName].keywords[element.name] = grouping[element.verticalName].keywords[element.name] ? grouping[element.verticalName].keywords[element.name] + element.countOfKeywords : element.countOfKeywords
uniqueNames.add(element.name);
}
// uniqueNames Set to Array
uniqueNames = [...uniqueNames];
// create template datasets with 0 percentage
// I did it after first loop because I want to makesure the template.labels.length completed
template.datasets = uniqueNames.map(label => ({ label, data: new Array(template.labels.length).fill(0) }));
// target for now create grouping & create template with labels and 0 percentages
// console.log(JSON.stringify(grouping, null, 2));
// console.log(JSON.stringify(template, null, 2));
// calculate the percentages
for (let i = 0; i < template.datasets.length; i++) {
const uniqueName = uniqueNames[i];
for (let j = 0; j < template.labels.length; j++) {
const label = template.labels[j];
if (grouping[label].keywords[uniqueName] === undefined) {
template.datasets[i].data[j] = 0;
} else {
template.datasets[i].data[j] = grouping[label].keywords[uniqueName] / grouping[label].sum * 100;
}
}
}
// output
console.log(JSON.stringify(template, null, 2));
UPDATE
More optimized code by skip add datasets to template before second loop
// input
const array = [
{
name: 'Attrition',
verticalName: 'BCM',
countOfKeywords: 20,
},
{
name: 'Others',
verticalName: 'BCM',
countOfKeywords: 26,
},
{
name: 'Others',
verticalName: 'CGLR',
countOfKeywords: 24,
},
{
name: 'Attrition',
verticalName: 'NEW',
countOfKeywords: 20,
},
{
name: 'Others',
verticalName: 'NEW',
countOfKeywords: 1,
},
];
// declare variables
let uniqueNames = new Set();
const grouping = {};
const template = {
labels: [],
datasets: []
}
// create grouping object and create template labels
for (let i = 0; i < array.length; i += 1) {
const element = array[i];
if (grouping[element.verticalName] === undefined) {
template.labels.push(element.verticalName);
grouping[element.verticalName] = { sum: 0, keywords: {} };
};
grouping[element.verticalName].sum += element.countOfKeywords;
grouping[element.verticalName].keywords[element.name] = grouping[element.verticalName].keywords[element.name] ? grouping[element.verticalName].keywords[element.name] + element.countOfKeywords : element.countOfKeywords
uniqueNames.add(element.name);
}
// uniqueNames Set to Array
uniqueNames = [...uniqueNames];
// target for now create grouping & create template with labels and without datasets
// console.log(JSON.stringify(grouping, null, 2));
// console.log(JSON.stringify(template, null, 2));
// add datasets
// calculate the percentages
for (let i = 0; i < uniqueNames.length; i++) {
const uniqueName = uniqueNames[i];
template.datasets.push({ label: uniqueName, data: [] })
for (let j = 0; j < template.labels.length; j++) {
const label = template.labels[j];
if (grouping[label].keywords[uniqueName] === undefined) {
template.datasets[i].data[j] = 0;
} else {
template.datasets[i].data[j] = grouping[label].keywords[uniqueName] / grouping[label].sum * 100;
}
}
}
// output
console.log(JSON.stringify(template, null, 2));
Source:stackexchange.com