I have some data like this (ignore that they all have the same date, they will normally have different dates):
[
{
"Raise Hand": 0,
"Be Quiet": 1,
"Ask For Help": 2,
"Be Good": 3,
"Comment": "four?",
"date": "2022-03-05",
"email": "[email protected]"
},
{
"Raise Hand": 0,
"Be Quiet": 1,
"Ask For Help": 2,
"Be Good": 3,
"Comment": "four?",
"date": "2022-03-05",
"email": "[email protected]"
},
{
"Raise Hand": 0,
"Be Quiet": 1,
"Ask For Help": 2,
"Be Good": 3,
"Comment": "four?",
"date": "2022-03-05",
"email": "[email protected]"
},
{
"Raise Hand": 0,
"Be Quiet": 1,
"Ask For Help": 1,
"Be Good": 1,
"Comment": "a",
"date": "2022-03-05",
"email": "[email protected]"
},
{
"Raise Hand": 0,
"Be Quiet": 0,
"Ask For Help": 0,
"Be Good": 0,
"Comment": "a",
"date": "2022-03-05",
"email": "[email protected]"
},
{
"Raise Hand": 2,
"Be Quiet": 2,
"Ask For Help": 2,
"Be Good": 2,
"Comment": "asd",
"date": "2022-03-05",
"email": "[email protected]"
},
{
"Raise Hand": 4,
"Be Quiet": 4,
"Ask For Help": 4,
"Be Good": 4,
"Comment": "asds",
"date": "2022-03-05",
"email": "[email protected]"
},
{
"Raise Hand": 1,
"Be Quiet": 2,
"Ask For Help": 1,
"Be Good": 0,
"Comment": "asdsd",
"date": "2022-03-05",
"email": "[email protected]"
},
{
"Raise Hand": 2,
"Be Quiet": 1,
"Ask For Help": 1,
"Be Good": 3,
"Comment": "asdsd",
"date": "2022-03-05",
"email": "[email protected]"
},
{
"Raise Hand": 3,
"Be Quiet": 2,
"Ask For Help": 1,
"Be Good": 2,
"Comment": "ads",
"date": "2022-03-05",
"email": "[email protected]"
},
{
"Raise Hand": 1,
"Be Quiet": 2,
"Ask For Help": 1,
"Be Good": 1,
"Comment": "asds",
"date": "2022-03-05",
"email": "[email protected]"
},
{
"Raise Hand": 3,
"Be Quiet": 2,
"Ask For Help": 1,
"Be Good": 2,
"Comment": "asds",
"date": "2022-03-05",
"email": "[email protected]"
}
]
And I need the data formatted into something like this with a new array for each 'challenge'. X would be the date and Y would be the value of that 'challenge' on that particular day:
[{x:"2-22-22", y:2}, {x:"2-23-22", y:3}]
For example, it would have an array for 'Raise Hand', an array for 'Be Quiet', etc. but also be dynamic so I can add more 'challenges' or replace them later. I also don't need date, email, and anything containing 'comment' taken out. Raise Hand:
[{x:"2-22-22", y:0},{x:"2-23-22", y:0},{x:"2-24-22", y:1}, ect]
I've spent a few hours working on this and this is how far I've gotten:
function formatData() {
let labels = []
let keys = []
//* Get keys
for(let i = 0; i < data.length; i ) {
for(let j = 0; j < Object.keys(data[i]).length; j ) {
if(keys.indexOf(Object.keys(data[i])[j]) == -1) {
keys.push(Object.keys(data[i])[j])
}
}
}
keys = reduceKeys(keys)
let totalData = {}
//* Get data for each key
for(let i = 0; i < data.length; i ) {
for(let j = 0; j < keys.length; j ) {
//* If data[i] DOES NOT have keys[j] then do this
if(Object.keys(data[i]).indexOf(keys[j]) != -1) {
//* Make new key with array if it does not exist
if(Object.keys(totalData).indexOf(keys[j]) == -1) {
totalData[keys[j]] = []
}
totalData[keys[j]].push(data[i][keys[j]])
} else {
//* Make new key with array if it does not exist
if(Object.keys(totalData).indexOf(keys[j]) == -1) {
totalData[keys[j]] = []
}
//* If the key does not exist for that entry the put 0
totalData[keys[j]].push(0)
}
if(data[i].date == null || data[i].date == undefined) {
labels.push("Error: No date")
} else {
labels.push(data[i].date)
}
}
}
console.log(totalData)
console.log(labels)
let outputData = []
for(let i = 0; i < labels.length; i ) {
let tempArr = []
for(let j = 0; j < Object.keys(totalData).length; j ) {
// Object.keys(totalData)
let length = totalData[Object.keys(totalData)[j]].length
for(let k = 0; i < )
}
}
}
//* remove comments, date, and email
function reduceKeys(keyArr) {
let output = []
for(let i = 0; i < keyArr.length; i ) {
let key = keyArr[i]
if(key.toLowerCase().includes("comment") || key.toLowerCase().includes("date") || key.toLowerCase().includes("email")) continue
output.push(key)
}
return output
}
For more info on how I need the data formatted please look at this ChartJS docs page
CodePudding user response:
Sounds like the simplest straightforward approach would be to have a single nested loop, where you iterate over all properties but Comment
, date
, and email
, pushing to an array identified by the property being iterated over, and creating the array first if it doesn't exist - then take the Object.values
of the resulting object of arrays at the end.
const input = [
{
"Raise Hand": 0,
"Be Quiet": 1,
"Ask For Help": 2,
"Be Good": 3,
"Comment": "four?",
"date": "2022-03-05",
"email": "[email protected]"
},
{
"Raise Hand": 0,
"Be Quiet": 1,
"Ask For Help": 2,
"Be Good": 3,
"Comment": "four?",
"date": "2022-03-06",
"email": "[email protected]"
},
];
const outputByExercise = {};
for (const item of input) {
const { Comment, date, email, ...rest } = item;
for (const [key, value] of Object.entries(rest)) {
outputByExercise[key] ??= [];
outputByExercise[key].push({ date, value });
}
}
const output = Object.values(outputByExercise);
console.log(output);
CodePudding user response:
You don't need parse manually. You can use ChartJs parser like
const data = [{x: 'Jan', "Raise Hand": 100, "Be Quiet": 50, "Ask For Help": 50}, {x: 'Feb', "Raise Hand": 100, "Be Quiet": 50, "Ask For Help": 50}];
const cfg = {
type: 'bar',
data: {
labels: ['Jan', 'Feb'],
datasets: [{
label: 'Rise hand',
data: data,
parsing: {
yAxisKey: "Raise Hand"
}
}, {
label: 'Be Quiet',
data: data,
parsing: {
yAxisKey: "Be Quiet"
}
}, {
label: 'Help',
data: data,
parsing: {
yAxisKey: "Ask For Help"
}
}]
},
};
I took example from the link you shared :)