Javascript code to split JSON data into two datapoints array to bind with stackedbar chart canvasjs? - javascript

I have variable data having json data as below:
[
{
"BillingMonth":"11",
"BillingYear":"2016",
"Volume":"72",
"BillingMonthName":"November",
"BillingProduct":"Product1"
},
{
"BillingMonth":"11",
"BillingYear":"2016",
"Volume":"617",
"BillingMonthName":"November",
"BillingProduct":"Product2"
},
{
"BillingMonth":"12",
"BillingYear":"2016",
"Volume":"72",
"BillingMonthName":"December",
"BillingProduct":"Product1"
},
{
"BillingMonth":"12",
"BillingYear":"2016",
"Volume":"72",
"BillingMonthName":"December",
"BillingProduct":"Product2"
}
]
What I want to split above json data using javascript/jquery and get them stored in two variables data1, data2 having json data as below as result:
{
type: "stackedBar",
legendText: "Product1",
showInLegend: "true",
data1: [
{ x: November, y: 72 },
{ x: December, y: 72 },
]
}
and
{
type: "stackedBar",
legendText: "Product2",
showInLegend: "true",
data2: [
{ x: November, y: 617 },
{ x: December, y: 72 },
]
}
The above will bind in canvas js stackedbar chart.
Thanks!

Hey here's a solution I had a lot of fun working on I hope it works well for you. I wasn't sure if you would always have 2 products product1, product2 so I went with a more general approach for n amount of products. The result is in an array format, but you can use es6 destructuring to get the two variables data1 and data2 like I did below:
/*
* helper function to restructure json in the desired format
*/
function format(obj) {
var formatted = {
"type": "stackedBar",
"legendText": obj.BillingProduct,
"showInLegend": "true",
"data": [{
"x": obj.BillingMonthName,
"y": obj.Volume
}]
}
return formatted;
}
/*
* returns an array of unique products with corresponding BillingMonth/Volume data
*/
function getStackedBarData(data) {
// transform each obj in orignal array to desired structure
var formattedData = data.map(format);
// remove duplicate products and aggregate the data fields
var stackedBarData =
formattedData.reduce(function(acc, val){
var getProduct = acc.filter(function(item){
return item.legendText == val.legendText
});
if (getProduct.length != 0) {
getProduct[0].data.push(val.data[0]);
return acc;
}
acc.push(val);
return acc;
}, []);
return stackedBarData;
}
var data = [{
"BillingMonth": "11",
"BillingYear": "2016",
"Volume": "72",
"BillingMonthName": "November",
"BillingProduct": "Product1"
}, {
"BillingMonth": "11",
"BillingYear": "2016",
"Volume": "617",
"BillingMonthName": "November",
"BillingProduct": "Product2"
}, {
"BillingMonth": "12",
"BillingYear": "2016",
"Volume": "72",
"BillingMonthName": "December",
"BillingProduct": "Product1"
}, {
"BillingMonth": "12",
"BillingYear": "2016",
"Volume": "72",
"BillingMonthName": "December",
"BillingProduct": "Product2"
}]
var dataVars = getStackedBarData(data);
var data1 = dataVars[0];
var data2 = dataVars[1];
console.log(data1);
console.log(data2);
Hope this helps you!

Related

how to foreach array to array object in javascript

I'm very confused about doing foreach array to array object in Javascript, I already did a lot of research about foreach object in Javascript and I tried many ways but nothing works. All that I'm trying to achieve is to have data JSON like this :
[
{
"name": "First Data",
"data": [
{
"y": 95,
"total":100,
"md": "1",
"name": "National",
"drillup" : 'level0',
"drilldown" : "3",
"next" : "level2"
}
]
}
,{
"name": "Second Data",
"data": [
{
"y": 95,
"total":100,
"md": "1",
"name": "National",
"drillup" : 'National',
"drilldown" : "3",
"next" : "level2"
}
]
}
]
and I tried to do foreach based on some finding of my research but the result wasn't like what I want or like what I'm try to achieve ..
and here is the script that I tried :
dataFirstSecond = await informationModel.getdata();
Object.entries(dataRegularSecondary).forEach(entry => {
const [key, value] = entry;
returnData[key] = [
{
name: value.name,
data: [{
y: value.y,
total: value.total_ada,
next: 'level_2',
drilldown: true,
}]
}]
});
and here is the result or the output of my script that I try it :
{
"0": [
{
"name": "First Data",
"data": [
{
"y": 22.973,
"total": 17,
"next": "level_2",
"drilldown": true
}
]
}
],
"1": [
{
"name": "Second Data",
"data": [
{
"y": 5.4054,
"total": 4,
"next": "level_2",
"drilldown": true
}
]
}
]
}
can someone help me to achieve the data that I want?
returnData[key] = [{ ... }] should just be returnData.push({ ... }), and make sure returnData is an array (e.g. returnData = [])
If the function informationModel.getdata(); returns an Object you could use the method JSON.stringify(Object) to easily convert and Object to JSON. For example you could try to do to convert this Object to a String then cast the String to JSON.
let JSONString = JSON.stringify(informationModel.getdata());
let JSON_Object = JSON.parse(JSONString);
If dataRegularSecondary is an array and not an object you could use map:
dataRegularSecondary.map(value => {
return {
name: value.name,
data: [{
y: value.y,
total: value.total_ada,
next: 'level_2',
drilldown: true,
}]
}
}
Your question is how to forEach array to array object. Then that means dataRegularSecondary is an array, right? Object.entries returns an array of key value pairs. If you pass an array to that method, it will return the indices as keys and the items as values.
const arr = ['hello', 'world'];
Object.entries(arr); // [['0', 'hello'], ['1', 'world']]
Skip the Object.entries and use dataRegularSecondary directly for forEach.
As for your output, it looks like returnData is an object as well. Make sure it's an array and just push the data into that.
dataRegularSecondary.forEach(value => {
returnData.push({
name: value.name,
data: [{
y: value.y,
total: value.total_ada,
next: 'level_2',
drilldown: true,
}],
});
});
Or you can use map as well.
const returnData = dataRegularSecondary.map(value => ({
name: value.name,
data: [{
y: value.y,
total: value.total_ada,
next: 'level_2',
drilldown: true,
}],
}));

how to make nested array objects in javascript in a key value pair format

array data=[
{
"id":1,
"name":"john",
"income":22000,
"expenses":15000
},
{
"id":2,
"name":"kiran",
"income":27000,
"expenses":13000
},
{
"id":1,
"name":"john",
"income":35000,
"expenses":24000
}
]
i want to make a new array set in following format which is in a key value pair. ie result set.
can you please explain the best method. ? how to achive using foreach.?
tried using foreach method by looping each element. but cant get the desired output format
var result= [ {
"name": "john",
"series": [
{
"name": "income",
"value": 22000
},
{
"name": "expenses",
"value": 15000
},
]
},
{
"name": "kiran",
"series": [
{
"name": "income",
"value": 27000
},
{
"name": "expenses",
"value": 13000
},
]
}]
// Your array
const result = [
{
name: "john",
series: [
{
name: "income",
value: 22000,
},
{
name: "expenses",
value: 15000,
},
],
},
{
name: "kiran",
series: [
{
name: "income",
value: 27000,
},
{
name: "expenses",
value: 13000,
},
],
},
];
// What is .map function?
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map
// Output
// map return a new function.
// it's a loop method but more equipped
result.map((item, index) => {
const seriesKeyValues = {};
// forEach is too, it's a loop method.
// but not have a return value,
// just loops and give you item on each loop
item.series.forEach(serie => {
//seriesKeyValues is a object.
// different between seriesKeyValues.serie.name
// it's a bracket notation
// look this documentation
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Object_initializer#computed_property_names
seriesKeyValues[serie.name] = serie.value;
});
// return new Object
// ... is 'spread syntax' basically combine objects
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Object_initializer#spread_properties
// spread syntax is a new way.
// old way is https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
return {
id: index,
name: item.name,
...seriesKeyValues,
};
});
I hope it will help :). if you don't understand any lines of code, i can explain

how to loop through objects and change the property keys in a data set

I have a set of data that needs to be reformatted according to a specific format that i desire.
Below is the format of data that I'm receiving.
const recieved = [
{
"name": "1PM Industries IncĀ ",
"series": [
{
"value": 0.0001,
"name": "2019-08-30"
},
{
"value": 0,
"name": "2019-08-28"
}
]
}
]
What i need to do is iterate through all object property keys "name", "series", "value" and change them to "id", "data" , "x" and "y" respectively.
Below is the format of data that i want the above data set to be changed.
I need the "name" to be replaced with "x" and "value" should be replaced with "y"
const columns = [
{
"id": "japan",
"data": [
{
"x": "plane",
"y": 45
},
{
"x": "helicopter",
"y": 253
}
]
}
]
I found out that we can access property keys of objects by Object.keys
function formatData(columns) {
columns.map(col => {
})
}
I find myself in really hard situations when it comes to formatting of data. Hope someone could help me with this. Thanks
This should work:
received.map(r => ({
id: r.name,
data: r.series.map(s => ({
x: s.name,
y: s.value
}))
}));
Map over each received object, return a new object. id of the new object is name of the received object. data of new object is a map of series of old objects converting name to x and value to y.
You could rename the properties (Assigning to new variable names) and generate new objects.
const
recieved = [{ name: "1PM Industries Inc ", series: [{ value: 0.0001, name: "2019-08-30" }, { value: 0, name: "2019-08-28" }] }],
result = recieved.map(({ name: id, series }) => ({
id,
data: series.map(({ value: x, name: y }) => ({ x, y }))
}));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
You can use map method for this.
const recieved = [
{
"name": "1PM Industries Inc ",
"series": [
{
"value": 0.0001,
"name": "2019-08-30"
},
{
"value": 0,
"name": "2019-08-28"
}
]
}
]
let output = recieved.map(o=>{
let data = o.series.map((i)=>{ return {x: i.value, y: i.name}});
return {id: o.name, data}
});
console.log(output)
you can use for..in loop in conjunction with hasOwnProperty() method
use recursion to have a better script

How can I filter a json and get the mean to create a line plot in js?

I have data in json format, so i want plot with plotly js, what i need is to create a plot of different states by semester, so i need to filter each state (example California), after that i need to get the mean of each semester and finally plot it.
So far i have this code, but i dont know how to filter im new in js
// Trace1
var trace1 = {
x: data.map(row => row.date),
y: data.map(row => row.snap_biannual_chan),
text: data.map(row => row.state_name),
name: "snap_biannual_chan",
type: "line"
};
// Combining both traces
var data = [trace1];
// Apply the group barmode to the layout
var layout = {
title: "Practice",
xaxis: {
categoryorder: "array",
}
};
// Render the plot to the div tag with id "plot"
Plotly.newPlot("plot", data, layout)
this is the json example:
"county_state_id": "06001",
"pop_hispan_prop": ".1176472187212034",
"pop_un_st": 3059000,
"state_name": "California",
"county_name": "Alameda County",
"pop_un_co": 109000,
"state_id": "06",
"county_id": "001",
"pop_co": 1605217,
"pop_st": 38654206,
"state_abbrev": "CA",
"semester": "0118",
"snap_beneficiaries": 102034,
"snap_biannual_chan": -2.02980374083036,
"sem": "Jan18",
"pop_un_co_per": 6.790359185082141,
"pop_un_st_per": 7.913757173022776,
"year": 2018,
"month": 1,
"date": "January2018"
You can use the array filter() and reduce() methods to calculate the mean without having to micromanage a bunch of loops and variables. Here's an example:
const data = [
{ state_id: "01", snap_biannual_chan: 5.5 },
{ state_id: "01", snap_biannual_chan: 3 },
{ state_id: "02", snap_biannual_chan: 5 }
];
const state01 = data.filter(x => x.state_id === "01");
const meanState01 = state01.reduce((acc, item) => {
acc.sum += item.snap_biannual_chan;
acc.mean = acc.sum / state01.length
return acc;
}, { sum: 0, mean: 0 });
console.log(meanState01);
console.log("the mean: ", meanState01.mean);

group by/formatting json data in Javascript

Sorry if this has been asked before. I have the JSON structure like:
{"data":[
{"Date":"03/04/2016","Key":"A","Values":"123"},
{"Date":"04/04/2016","Key":"A","Values":"456"},
{"Date":"03/04/2016","Key":"B","Values":"789"},
{"Date":"04/04/2016","Key":"B","Values":"012"}
]}
I want to change this to a different format which is basically grouped by Key and combines rest of the field in Values
{"Result":[
{
"Key":"A"
"Values":[["03/04/2016","123"], ["04/04/2016","456"]]
},
{"Key":"B"
"Values":[["03/04/2016","789"]},["04/04/2016","012"]]
}
]}
I want to do this javascript/html
You could iterate and build a new object if not exist.
var object = { "data": [{ "Date": "03/04/2016", "Key": "A", "Values": "123" }, { "Date": "04/04/2016", "Key": "A", "Values": "456" }, { "Date": "03/04/2016", "Key": "B", "Values": "789" }, { "Date": "04/04/2016", "Key": "B", "Values": "012" }], result: [] };
object.data.forEach(function (a) {
if (!this[a.Key]) {
this[a.Key] = { Key: a.Key, Values: [] };
object.result.push(this[a.Key]);
}
this[a.Key].Values.push([a.Date, a.Values]);
}, Object.create(null));
console.log(object);
I think this can be a better answer (but Nina's answer is the match for your problem terms) if items of data array have different properties and you don't want to change input data.
var raw = {"data":[
{"Date":"03/04/2016","Key":"A","Values":"123"},
{"Date":"04/04/2016","Key":"A","Values":"456"},
{"Date":"03/04/2016","Key":"B","Values":"789"},
{"Date":"04/04/2016","Key":"B","Values":"012"}
]};
var result = new Map;
raw.data.forEach(entry => {
var key = entry.Key;
if (this[key])
return this[key].push(getClonedData(entry));
this[key] = [getClonedData(entry)];
result.set(key, {
Key: key,
Values: this[key]
})
}, Object.create(null));
var filtered = {
result: [...result.values()]
}
console.log(filtered);
function getClonedData(entry) {
data = Object.assign({}, entry);
delete data.Key;
return data;
}

Categories

Resources