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

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

Related

Nested array issue in JavaScript

I have the following array
Array["MyArray",
{
"isLoaded":true,
"items":
[{
"id":"4",
"name":"ProductA",
"manufacturer":"BrandA",
"quantity":1,
"price":"25"
},{
"id":"1",
"name":"ProductB",
"manufacturer":"BrandB",
"quantity":5,
"price":"20"
}],
"coupons":null
}
]
I need to load product names and their quantity from the array.
const result = [key, value].map((item) => `${item.name} x ${item.quantity}`);
Here's one possible way to achieve the desired result:
const getProductsAndQuantity = ([k , v] = arr) => (
v.items.map(it => `${it.name} x ${it.quantity}`)
);
How to use it within the context of the question?
localforage.iterate(function(value, key, iterationNumber) {
console.log([key, value]);
const val2 = JSON.parse(value);
if (val2 && val2.items && val2.items.length > 0) {
console.log(val2.items.map(it => `${it.name} x ${it.quantity}`).join(', '))
};
});
How it works?
Among the parameters listed in the question ie, value, key, iterationNumber, only value is required.
The above method accepts the key-value pair as an array (of 2 elements) closely matching the console.log([key, value]); in the question
It uses only v (which is an object). On v, it accesses the prop named items and this items is an Array.
Next, .map is used to iterate through the Array and return each product's name and quantity in the desired/expected format.
Test it out on code-snippet:
const arr = [
"MyArray",
{
"isLoaded": true,
"items": [{
"id": "4",
"name": "ProductA",
"manufacturer": "BrandA",
"quantity": 1,
"price": "25"
}, {
"id": "1",
"name": "ProductB",
"manufacturer": "BrandB",
"quantity": 5,
"price": "20"
}],
"coupons": null
}
];
const getProductsAndQuantity = ([k, v] = arr) => (
v.items.map(
it => `${it.name} x ${it.quantity}`
)
);
console.log(getProductsAndQuantity());
I understood. You should learn about array methods such as map, filter, reduce. Here you go...
const items = [{
"id":"4",
"name":"ProductA",
"manufacturer":"BrandA",
"quantity":1,
"price":"25"
},{
"id":"1",
"name":"ProductB",
"manufacturer":"BrandB",
"quantity":5,
"price":"20"
}];
const result = items.map((item) => `${item.name} x ${item.quantity}`);
console.log(result);
I think I understand the question to say that the input is an array of objects, each containing an array of items. The key is that a nested array requires a nested loop. So, we iterate the objects and their internal items (see the lines commented //outer loop and // inner loop below)
Also, half-guessing from the context, it looks like the that the OP aims to assemble a sort of invoice for each object. First a demo of that, (and see below for the version simplified to exactly what the OP asks)...
const addInvoice = obj => {
let total = 0;
// inner loop
obj.invoice = obj.items.map(i => {
let subtotal = i.quantity * i.price;
total += subtotal
return `name: ${i.name}, qty: ${i.quantity}, unit price: ${i.price}, subtotal: ${subtotal}`
});
obj.invoice.push(`invoice total: ${total}`);
}
const objects = [{
"isLoaded": true,
"items": [{
"id": "4",
"name": "ProductA",
"manufacturer": "BrandA",
"quantity": 1,
"price": "25"
}, {
"id": "1",
"name": "ProductB",
"manufacturer": "BrandB",
"quantity": 5,
"price": "20"
}],
"coupons": null
}]
// outer loop
objects.forEach(addInvoice);
console.log(objects);
If my guess about the goal went to far, just remove the unit price, subtotal and total lines from the invoice function...
const objects = [{
"isLoaded": true,
"items": [{
"id": "4",
"name": "ProductA",
"manufacturer": "BrandA",
"quantity": 1,
"price": "25"
}, {
"id": "1",
"name": "ProductB",
"manufacturer": "BrandB",
"quantity": 5,
"price": "20"
}],
"coupons": null
}]
const summaryString = obj => {
return obj.items.map(i => `${i.name}, ${i.quantity}`);
}
const strings = objects.map(summaryString);
console.log(strings);

How to update object based off objects specific value?

I have 2 objects and I want to 'transplant' values from one object into the other.
The first object I am drawing data from looks like:
var userData = {
Data: [
{
Amount: 430140.68,
Year: "2015",
AccountName: "Account 1"
},
{
Amount: 458997.32,
Year: "2016",
Name: "Account 2"
},
]
}
The 2nd object I am placing data into looks like:
[
{
"name": "Account 1",
"data": [
0,
0
],
},
{
"name": "Account 2",
"data": [
0,
0
],
}
]
My goal is to take the Amount form the first object and place it in the data array of the 2nd. Each year corresponds to a value in the 'data` array.
So, the resulting updated object should look like:
[
{
"name": "Account 1",
"data": [
430140.68,
0
],
},
{
"name": "Account 2",
"data": [
0,
458997.32
],
}
]
To try to achieve this I have the following code:
const yearArrLength = yearsArr.length;
const generatedObj = new Array(yearArrLength).fill(0);
// Push name and populate data array with 0s.
for (var key of Object.keys(userData.Data)) {
var accName = userData.Data[key].AccountName;
if (!generatedObj.find(key => key.name === accName)){
generatedObj.push({'name': accName, 'data': blankDataArr});
}
}
for (var key of Object.keys(userData.Data)) {
var accName = userData.Data[key].AccountName;
var accAmount = userData.Data[key].Amount;
var accYear = userData.Data[key].Year;
// Get location of years array value
var yearArrIndex = yearsArr.indexOf(accYear);
for (var key of Object.keys(generatedObj)) {
if (generatedObj[key].name == accName) {
generatedObj[key].data[yearArrIndex] = accAmount;
}
}
}
However, this seems to populate all of the data array values, eg:
[
{
"name": "Account 1",
"data": [
430140.68,
458997.32
],
},
{
"name": "Account 2",
"data": [
430140.68,
458997.32
],
}
]
I'm completely stumped as to why. The if statement should be checking if there is a matching account name, but it doesn't seem to fire.
Would anyone know what I've done wrong?
It looks like you're pushing the exact same blankDataArr each time - you're not pushing a new array, you're pushing the same array to all.
For a more minimal example:
const subarr = [];
const arr = [subarr, subarr];
arr[0].push('x');
console.log(JSON.stringify(arr));
// both items in `arr` have changed
// because both refer to the exact same subarr object
For what you're trying to do, it looks like it'd be a lot easier to make an object or Map indexed by AccountName first, that way you just have to access or create the AccountName property while iterating, and assign to the appropriate year.
const yearsArr = ['2015', '2016'];
const userData = {
Data: [
{
Amount: 430140.68,
Year: "2015",
AccountName: "Account 1"
},
{
Amount: 458997.32,
Year: "2016",
AccountName: "Account 2"
},
]
};
const dataByAccountName = new Map();
for (const { AccountName, Amount, Year } of userData.Data) {
if (!dataByAccountName.has(AccountName)) {
// Create an entirely new array:
dataByAccountName.set(AccountName, yearsArr.map(() => 0));
}
const index = yearsArr.indexOf(Year);
dataByAccountName.get(AccountName)[index] = Amount;
}
const result = [...dataByAccountName.entries()].map(([name, data]) => ({ name, data }));
console.log(result);

Map Json Data to new key-value pair Node.js

I want to map one json data to a new javascript object
Before:
{
"Germany": 1,
"France": 1
}
After
[
{
"name": "Germany",
"anzahl": 1
},
{
"name": "France",
"anzahl": 1
}
]
Here's the code:
const dataMap = Object.keys(s).map((filename, x) => {
Object.keys(s[filename]).map((n) => ({
anzahl: n
}))
return ({
name: filename,
anzahl: x
});
})
Which is giving following output:
[
{
"name": "Germany",
"anzahl": 0
},
{
"name": "France",
"anzahl": 1
}
]
Can anyone please help me out?
Array.prototype.map's callback's second parameter is the current index of the array, which is why x is a number beginning at 0 and incrementing. If, instead, you write it as follows:
const dataMap = Object.keys(s).map((filename) => {
return {
name: filename,
anzahl: s[filename]
}
});
This transforms each key of s into an object where name is said key, and anzahl is the result of accessing the key filename on object s.

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

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

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!

Categories

Resources