Home > Net >  Combine data from multiple objects into something readable by chartJS
Combine data from multiple objects into something readable by chartJS

Time:03-07

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 :)

  • Related