Plot REST API response using Plotly and AngularJS - javascript

How to assign a and b values from the json {month,consumption}?
REST API response:
data= {
"_id": {
"$oid": "580b8f80c2ef1645d285c884"
},
"year": "2012",
"state": "Indiana",
"consumption": 3275,
"month": "january"
},
{
"_id": {
"$oid": "580b8f81bd966f4110af0111"
},
"year": "2012",
"state": "Indiana",
"consumption": 6348,
"month": "february"
}
app.js:
var graphPlotterDemoApp = angular.module('graphPlotterDemoApp', ['graphPlotter']);
graphPlotterDemoApp.controller('graphPlotterDemoCtrl', function($scope, $http) {
var a = ["jan", "feb", "mar", "apr"];
var b = [10, 15, 13, 17];
$scope.data={};
$scope.refresh = function(){
$http.get("https://api.mlab.com/api/1/databases/energyx/collections/energydata_2012?&apiKey=6JzRAzvdeqyLKAfQAqMOsLYLvvIdJG6A")
.success(function(response) {
$scope.data = response.data;
});
};
var trace1 = {
x: a,
y: b,
type: 'scatter'
};
$scope.refresh();
$scope.graphPlots = [trace1];
});

Use like to get data from json
var a=$scope.data.map(function(a) {return a.month;})
var b=$scope.data.map(function(a) {return a.consumption;})

Related

Filter JSON Obj

I'm getting a JSON object from a XMLHttpRequest and am looking for a solution to filter bt genre. I also need a way to return all results (unfiltered) if no filterable parameter is passed.
app.js (pseudo function)
function filterObject(json, filterBy) {
// filter through json
// return item that matches filterBy
}
data.json
[{
"date": {
"dayOfWeek": "Thursday",
"month": "Oct"
},
"location": "Bristol",
"genre": "rock"
}, {
"date": {
"dayOfWeek": "Cardiff",
"dayOfMonth": 13,
"month": "Oct"
},
"location": "Manchester",
"genre": "jazz"
}]
You can use array#filter to filter your json on genre value.
var json = [{"date": {"dayOfWeek": "Thursday","month": "Oct"},"location": "Bristol","genre": "rock"}, {"date": {"dayOfWeek": "Cardiff","dayOfMonth": 13,"month": "Oct"},"location": "Manchester", "genre": "jazz"}];
function filterObject(json, filterBy) {
return filterBy ? json.filter(o => o.genre === filterBy) : json;
}
console.log(filterObject(json,'jazz'));
console.log(filterObject(json));
.as-console-wrapper { max-height: 100% !important; top: 0; }
You can use Array#filter
Something like this:
(function() {
var json = [{
"date": {
"dayOfWeek": "Thursday",
"month": "Oct"
},
"location": "Bristol",
"genre": "rock"
}, {
"date": {
"dayOfWeek": "Cardiff",
"dayOfMonth": 13,
"month": "Oct"
},
"location": "Manchester",
"genre": "jazz"
}];
function filterObject(json, filterBy) {
if (filterBy !== undefined) {
return json.filter(function(x) {
return x.genre === filterBy;
});
} else {
return json;
}
}
var resultWithParameter = filterObject(json, "jazz");
console.log(resultWithParameter);
var resultWithoutParameter = filterObject(json);
console.log(resultWithoutParameter);
})();
You can use filterBy as object with key and value properties to find any property you like (not only genre key).
function filterObject(data, filterBy) {
if(typeof filterBy === 'undefined') return data;
return data.filter(function(item) {
return item[filterBy.key] === filterBy.value;
})
}
Test:
filterObject(arr, {key: 'genre', value: 'rock'}); // return rock band
filterObject(arr, {key: 'genre', value: 'jazz'}); // jazz band
filterObject(arr, {key: 'location', value: 'Bristol'}); // return band with location key
filterObject(arr); // return initial array

Grouping array of objects by multiple keys

I feel embarrassed for asking this question as I should know how to figure it out, but I'm spinning my wheels on grouping an array of objects by multiple keys.
Here's the data:
[
{
"car": "audi",
"type": "A6",
"style": "Avant",
"year": "1996"
},
{
"car": "audi",
"type": "A4",
"style": "2",
"year": "2006"
},
{
"car": "audi",
"type": "A4",
"style": "L W12",
"year": "2006"
},
{
"car": "audi",
"type": "80",
"style": "GLE",
"year": "1975"
},
{
"car": "audi",
"type": "A6",
"style": "Avant L",
"year": "1996"
},
{
"car": "audi",
"type": "A6",
"style": "3.2 Multitronic",
"year": "2006"
},
]
What I've been trying to generate with little success is the following:
[{
"audi": [{
"1996": {
"A6": ["Avant, Avant L"]
}
}, {
"2006": }
"A6": ["3.2 Multitronic"],
"A4": ["L W12", "2"]
}
}
....
}]
The schema is:
{
"car1": [{
"year1": {
"style1": ["trim1", "trim2"],
"style2": ["trim1", "trim2"]
},
"year1": {
"style1": ["trim1", "trim2"],
"style2": ["trim1", "trim2"]
}
}],
"car2": [{
"year1": {
"style1": ["trim1", "trim2"],
"style2": ["trim1", "trim2"]
},
"year2": {
"style1": ["trim1", "trim2"],
"style2": ["trim1", "trim2"]
}
}]
}
I've tried the following with lodash
let result = _.chain(carData)
.groupBy('car')
.toPairs()
.map(function(curr) {
return _.zipObject(['car', 'year'], curr);
})
.value();
This gets me part of the way, but I end up with incomplete data when it comes to the styles and types for each year of the car.
You could use a hash object and a nested approach for the given properties.
var data = [{ car: "audi", type: "A6", style: "Avant", year: 1996 }, { car: "audi", type: "A4", style: 2, year: 2006 }, { car: "audi", type: "A4", style: "L W12", year: 2006 }, { car: "audi", type: 80, style: "GLE", year: 1975 }, { car: "audi", type: "A6", style: "Avant L", year: 1996 }, { car: "audi", type: "A6", style: "3.2 Multitronic", year: 2006 }],
keys = ['car', 'year', 'type'],
result = [];
data.forEach(function (a) {
keys.reduce(function (r, k) {
var o = {};
if (!r[a[k]]) {
r[a[k]] = { _: [] };
o[a[k]] = r[a[k]]._;
r._.push(o);
}
return r[a[k]];
}, this)._.push(a.style);
}, { _: result });
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Here's a (slightly verbose) solution that generates exactly the JSON object shape you wanted and groups by unlimited keys:
var cars = [{
"car": "audi",
"type": "A6",
"style": "Avant",
"year": "1996"
}, {
"car": "audi",
"type": "A4",
"style": "2",
"year": "2006"
}, {
"car": "audi",
"type": "A4",
"style": "L W12",
"year": "2006"
}, {
"car": "audi",
"type": "80",
"style": "GLE",
"year": "1975"
}, {
"car": "audi",
"type": "A6",
"style": "Avant L",
"year": "1996"
}, {
"car": "audi",
"type": "A6",
"style": "3.2 Multitronic",
"year": "2006"
}, ];
function groupBy(list, prop) {
return list.reduce((groupped, item) => {
var key = item[prop];
delete item[prop];
if (groupped.hasOwnProperty(key)) {
groupped[key].push(item);
} else {
groupped[key] = [item];
}
return groupped
}, {});
}
function groupSubKeys(obj, properties, propIndex) {
var grouppedObj = groupBy(obj, properties[propIndex]);
Object.keys(grouppedObj).forEach((key) => {
if (propIndex < properties.length - 2) {
grouppedObj[key] = groupSubKeys(grouppedObj[key], properties, propIndex + 1);
} else {
grouppedObj[key] = grouppedObj[key].map(item => item[properties[propIndex + 1]])
}
});
return grouppedObj;
}
function groupByProperties(list, properties) {
return groupSubKeys(list, properties, 0);
}
console.log(groupByProperties(cars, ['car', 'year', 'type', 'style']));
Here's a running example:
http://codepen.io/rarmatei/pen/evmBOo
const groupBy = function groupBy(list, properties, propertyIndex) {
// current property index
let i = propertyIndex === undefined ? 0 : propertyIndex;
// group by
let grouppedObj = list.reduce((acc, obj) => {
let groupedValue = obj[properties[i]];
if (!groupedValue) {
return acc;
}
if (!acc[groupedValue]) {
acc[groupedValue] = [];
}
acc[groupedValue].push({ ...obj, groupBy: properties.join(",") });
return acc;
}, {});
// group by nested
const keys = Object.keys(grouppedObj);
if (i === properties.length - 1) {
return grouppedObj;
}
keys.forEach((key) => {
grouppedObj[key] = groupBy(grouppedObj[key], properties, i + 1);
});
return grouppedObj;
};
const data =[
{
"year": "2021",
"cabin": "1",
"months": ["1", "2"]
},
{
"year": "2021",
"cabin": "1",
"months": ["4"]
},
{
"year": "2021",
"cabin": "2",
"months": ["1", "2"]
},
{
"year": "2022",
"cabin": "1",
"months": ["1", "2"]
},
{
"year": "2022",
"cabin": "1",
"months": ["4"]
},
{
"year": "2022",
"cabin": "2",
"months": ["1", "2"]
}
];
const results=groupBy(data, ["year", "cabin"]);
console.log(results);

AngularJS array split

I am relatively new to AngularJS. I am getting my data from java spring through $http.get request in the following format:
[
{
"obj1": 1039751,
"obj2": "ABC",
"obj3": "INDIA",
"obj4": 57,
"obj5": 16,
"obj6": 43
},
{
"obj1": 895321,
"obj2": "PQR",
"obj3": "AUSTRALIA",
"obj4": 86,
"obj5": 43,
"obj6": 24
},
{
"obj1": 926384,
"obj2": "MNO",
"obj3": "DUBAI",
"obj4": 16,
"obj5": 12,
"obj6": 76
},
{
"obj1": 837537,
"obj2": "LMN",
"obj3": "ENGLAND",
"obj4": 83,
"obj5": 15,
"obj6": 43
},
{
"obj1": 867152,
"obj2": "JKL",
"obj3": "JAPAN",
"obj4": 49,
"obj5": 76,
"obj6": 16
},
{
"obj1": 1003783,
"obj2": "XYZ",
"obj3": "BHUTAN",
"obj4": 16,
"obj5": 42,
"obj6": 94
},
{
"obj1": 864287,
"obj2": "DEF",
"obj3": "USA",
"obj4": 96,
"obj5": 16,
"obj6": 37
}
]
My app.js:
var app = angular.module("myApp", ['smart-table']);
app.controller("ctrl", function($scope, $rootScope, $timeout, $http) {
init();
function init() {
$scope.rowCollection = {};
$scope.isGlobalVisible = {};
$http.get('rest/obz/getAllObjects').success(function(obdata) {
console.log(obdata);
$scope.rowCollection = obdata;
console.log(rowCollection);
}).error(function() {
console.log("Error");
});
}
});
I want to split the above array as separate arrays of obj1, obj2, obj3, obj4, obj5 and obj6 in AngularJS.as
obj1 = [{1039751,895321,926384,837537,867152,1003783,864287}]
obj2 = [{"ABC","PQR","MNO","LMN","JKL","XYZ","DEF"}]
and so on.
How to split them separably in js?
Have you tried angular.forEach and push the values on the new objects?
Something like
$http.get('rest/obz/getAllObjects')
.success(function(obdata){
console.log(obdata);
$scope.rowCollection = obdata;
console.log(rowCollection);
angular.forEach($scope.rowCollection, function(value, key) {
if (this[key] == undefined) {
this[key] = [];
};
this[key].push(value);
});
}).error(function(){
console.log("Error");
});

Change representation of JSON object to explicit key/value format

I have the following JSON:
{
"temperature": "22.2",
"power": "6",
"current": "156"
}
and I need to convert it to this explicit structure:
{
"key": "temperature",
"value": "22.2"
},
{
"key": "power",
"value": "6"
},
{
"key": "current",
"value": "156"
}
Is there an elegant, simple and quick way to do this?
Best, thx
var newStructure = Object.keys(obj).map(function(key){
return {'key':key, 'value':obj[key]}
})
Example
var obj = {
"temperature": "22.2",
"power": "6",
"current": "156"
}
var arr = Object.keys(obj).map(function(key){return {'key':key,'value':obj[key]}})
console.log(arr)
Object.hashToKeyValuePairs = function (hash) {
var ret = [];
for (var i in hash)
ret.push({ key: i, value: hash[i]});
return ret;
};
// example
document.body.innerHTML = JSON.stringify(
Object.hashToKeyValuePairs({ a: 1, b: 2, c: 3 })
);

Transforming JSON data from API into useful format?

I have an API that returns indicator data in this format:
[
{
"concept": "population",
"year": 2012,
"value": 9.5,
"country-name": "Sweden",
},
{
"concept": "education",
"year": 2012,
"value": 12,
"country-name": "Sweden",
},
{
"concept": "population",
"year": 2012,
"value": 5,
"country-name": "Norway",
},
{
"concept": "eduction",
"year": 2012,
"value": 12,
"country-name": "Norway",
}
]
Based on this, I typically need to group this by country and year to get something like:
var data = [
{id : Sweden, population : 9.5, education: 12},
{id : Norway, population : 5, education: 12},
]
Or just by country and year-values as an array:
var data = [
{id : Sweden, values : [ { year : 2012, population : 9.5, education: 12 }, {...} ]},
{id : Norway, values : [ { year : 2012, population : 5, education: 12 }, {...} ]},
]
What JS libraries can help manage these common data transformations?
Can you provide an example of doing the above (using a library or vanilla js)?
You can do it yourself, just iterate and create whatever you need, something like
var data = [];
json.forEach(function(item) {
var country = item['country-name'],
match = false,
obj = {}
data.forEach(function(dataItem, i) {
if (dataItem.id === country) {
match = true;
obj = data[i];
}
});
obj.id = country;
obj[item.concept] = item.value;
if (!match) data.push(obj)
});
FIDDLE
You might find an object easier to work with than an array:
var data = {};
indicatordata.forEach(function(item){
var country = item['country-name'];
var year = item.year;
data[country] = data[country] || {id: item['country-name'], values: {}};
var values = data[country].values;
values[year] = values[year] || {};
values[year][item.concept] = item.value;
});
You can do it with D3. d3.nest and Array.prototype.reduce specifically. The code is declarative and easy to maintain.
var rawData = [
{
"concept": "population",
"year": 2012,
"value": 9.5,
"country-name": "Sweden",
},
{
"concept": "education",
"year": 2012,
"value": 12,
"country-name": "Sweden",
},
{
"concept": "population",
"year": 2012,
"value": 5,
"country-name": "Norway",
},
{
"concept": "eduction",
"year": 2012,
"value": 12,
"country-name": "Norway",
}
];
var data = d3.nest()
.key(function(d)
{
return d['year'];
})
.key(function(d)
{
return d['country-name'];
})
.rollup(function(group)
{
return group.reduce(function(result, d)
{
result[d['concept']] = d['value'];
return result;
}, {});
})
.entries(rawData);
console.log(data);
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>

Categories