I would like to use chart.js for creating a couple of charts on my webpage, now the data that I receive from the controller is in the following format,
{
"dataset" : [
{
"name" : "Sarah",
"age" : "23",
"gender" : "female",
"country" : "australia",
"occupation" : "student"
},
{
"name" : "Randy",
"age" : "19",
"gender" : "male",
"country" : "america",
"occupation" : "student"
},
{
"name" : "Roger",
"age" : "32",
"gender" : "male",
"country" : "germany",
"occupation" : "software professional"
},
{
"name" : "Maverick",
"age" : "10",
"gender" : "male",
"country" : "america",
"occupation" : "student"
},
{
"name" : "Riya",
"age" : "25",
"gender" : "female",
"country" : "australia",
"occupation" : "software professional"
},
{
"name" : "Glade",
"age" : "30",
"gender" : "female",
"country" : "India",
"occupation" : "teacher"
}
]
}
Now, I would like to plot this information on 3 pie charts,
1) pie chart that shows the count of country of origin.
2) pie chart that shows the count of occupation.
3) pie chart that shows the count of people who have age less than 25.
So ideally the graph takes in information in the following format,
var pieData = {
graph-data:
[
{
name : country,
dataset : [
{
value: america,
count: 2,
color:"#878BB6"
},
{
value: india,
count : 1,
color : "#4ACAB4"
},
{
value: germany,
count : 1,
color : "#FF8153"
},
{
value: australia,
count : 2,
color : "#FFEA88"
}
]
},
{
name : occupation,
dataset : [
{
value: "student",
count: 3,
color:"#878BB6"
},
{
value: "software professional",
count : 2,
color : "#4ACAB4"
},
{
value: "teacher",
count : 1,
color : "#FF8153"
}
]
},
{
name : "age",
dataset : [
{
value: "23",
count: 1,
color:"#878BB6"
},
{
value: "19",
count : 1,
color : "#4ACAB4"
},
{
value: "10",
count : 1,
color : "#FF8153"
},
{
value: "25",
count : 1,
color : "#FF8423"
}
]
}
]
};
As you can see from the above json, the graph-data key has 3 array elements, each of which corresponds to a chart. How can I construct this data from the initial raw dataset and pass this to my chart.js for consumption? I am guessing I would be requiring to write converters, how can I achieve this in js/jquery, any information on this is highly appreciated. Thanks ahead!
Related
I have the following json object in javascript:
employeeRecords = [
{
"empID" : "7002",
"company" : "Google",
"group" : "Chrome",
"id" : "D-2005",
"city" : "New York",
"date" : "2018-05-01"
},
{
"empID" : "9002",
"company" : "Apple",
"group" : "iPhone",
"id" : "D-2014",
"city" : "Singapore"
"date": "2019-07-15"
},
{
"empID" : "7002",
"company" : "Google",
"group" : "Android",
"id" : "H-2007",
"city" : "London"
"date": "2018-05-01"
},
{
"empID" : "7002"
"company" : "Google",
"group" : "Android",
"id" : "K-2007",
"city" : "London"
"date": "2019-06-18"
},
{
"empID" : "9002",
"company" : "Apple",
"group" : "Laptop",
"id" : "N-2012",
"city" : "Japan"
"date": "2019-07-15"
}
]
The requirement is to group this json object, if the empID, company and the date is equal. If those key values are equal then the group field should be concatenated. I need to get this using JavaScript.
So the result should be like the following:
employeeRecords = [
{
"empID" : "7002",
"company" : "Google",
"group" : "Chrome-Android",
"id" : "D-2005",
"city" : "New York",
"date" : "2018-05-01"
},
{
"empID" : "9002",
"company" : "Apple",
"group" : "iPhone-Laptop",
"id" : "D-2014",
"city" : "Singapore"
"date": "2019-07-15"
},
{
"empID" : "7002"
"company" : "Google",
"group" : "Android",
"id" : "K-2007",
"city" : "London"
"date": "2019-06-18"
}
]
Any help to achieve this in JavaScript please?
Thanks in advance.
The first solution that comes to my mind is to add an element to a new list according to a control while traversing all the elements with the Array.prototype.forEach method.
const fixedRecords = [];
employeeRecords.forEach(record => {
let index = fixedRecords.findIndex(fr => fr.empID === record.empID && fr.date === record.date && fr.company === record.company)
if(index !== -1) {
fixedRecords[index] = {
...fixedRecords[index],
group: fixedRecords[index].group + '-' + record.group
}
}else {
fixedRecords.push(record);
}
})
This method will work. However, consider this; The findIndex function running for each list element means that this list will run for the number of elements for each element count (n * n). Therefore, if your list is large, it will not be very performant.
This uses reduce() and a JS object to compute the groups and will run in O(n) which is (at least for large arrays) considerably quicker than an implementation with includes(), find() or other nested loop approaches which take O(n²).
Just a note: I am not sure why you would want id and city in the output as this is meaningless information as this is the information for the first employee of a group and may or may not be true for all employees in that group, hence it's useless information that could potentially be confusing as it looks like a legitimate employee.
const employeeRecords = [
{
empID: "7002",
company: "Google",
group: "Chrome",
id: "D-2005",
city: "New York",
date: "2018-05-01",
},
{
empID: "9002",
company: "Apple",
group: "iPhone",
id: "D-2014",
city: "Singapore",
date: "2019-07-15",
},
{
empID: "7002",
company: "Google",
group: "Android",
id: "H-2007",
city: "London",
date: "2018-05-01",
},
{
empID: "7002",
company: "Google",
group: "Android",
id: "K-2007",
city: "London",
date: "2019-06-18",
},
{
empID: "9002",
company: "Apple",
group: "Laptop",
id: "N-2012",
city: "Japan",
date: "2019-07-15",
},
];
const resultObj = employeeRecords.reduce((acc, emp) => {
// concatenate the key (all criteria together build the key)
const key = `${emp.empID}-${emp.company}-${emp.date}`;
// if we already have a value with that key, add the group of the current employee
if(acc.hasOwnProperty(key)) acc[key].group += `-${emp.group}`;
// if we don't have a value with that key add that employee
else acc[key] = emp;
return acc;
}, {});
const result = Object.values(resultObj);
console.log(result);
This is my database collection:
{"productId" : 1,
"isVariant": 1,
"isComplete" : 1,
"variantId" : 1,
"attributeSet" : [
{
"name" : "Capacity",
"value" : "500 GB",
"id" : 3
},
{
"name" : "Form Factor",
"value" : "5 inch",
"id" : 4
},
{
"id" : 5,
"name" : "Memory Components",
"value" : "3D NAND",
"isVariation" : 0
}
]
},
{"productId" : 2,
"isVariant": 1,
"isComplete" : 1,
"variantId" : 1,
"attributeSet" : [
{
"name" : "Capacity",
"value" : "1 TB",
"id" : 3
},
{
"name" : "Form Factor",
"value" : "5 inch",
"id" : 4
},
{
"id" : 5,
"name" : "Memory Components",
"value" : "3D NAND",
"isVariation" : 0
}
]
},
{"productId" : 3,
"isVariant": 1,
"isComplete" : 0,
"variantId" : 1,
"attributeSet" : [
{
"name" : "Capacity",
"value" : "500 GB",
"id" : 3
},
{
"name" : "Form Factor",
"value" : "2.5 inch",
"id" : 4
},
{
"id" : 5,
"name" : "Memory Components",
"value" : "3D NAND",
"isVariation" : 0
}
]
},
{"productId" : 4,
"isVariant": 1,
"isComplete" : 0,
"variantId" : 1,
"attributeSet" : [
{
"name" : "Capacity",
"value" : "1 TB",
"id" : 3
},
{
"name" : "Form Factor",
"value" : "2.5 inch",
"id" : 4
},
{
"id" : 5,
"name" : "Memory Components",
"value" : "3D NAND",
"isVariation" : 0
}
]
}
Now I want to send the data of only the attribute where isVariation is not 0. Also I want to send the variant values of each attribute where isComplete =1. Hence the result should look like this
result : [{
"id": 3,
"name": "Capacity",
"value": [
"500 GB",
"1 TB"
]
}, {
"id": 4,
"name": "Form Factor",
"value": [
"5 inch"
]
}]
The above result does not have value of 2.5 inch as the isComplete is 0 for this document. Can anyone help me with the query
$match isComplete is 1
$project to show required fields
$unwind deconstruct attributeSet array
$match attributeSet.isVariation is not 0
$group by attributeSet.id and get first name and get unique value using $addToSet
db.collection.aggregate([
{ $match: { isComplete: 1 } },
{
$project: {
_id: 0,
attributeSet: 1
}
},
{ $unwind: "$attributeSet" },
{ $match: { "attributeSet.isVariation": { $ne: 0 } } },
{
$group: {
_id: "$attributeSet.id",
name: { $first: "$attributeSet.name" },
value: { $addToSet: "$attributeSet.value" }
}
}
])
Playground
The $project stage is not required in your query, i have added because this will optimize your query performance.
I have a sample JSON object below:
{
"product" : [ {
"description" : "This ball has air it.",
"id" : "product0",
"name" : "football",
"price" : 10
}, {
"description" : "Can kick upto long distance.",
"id" : "product1",
"name" : "soccer boots",
"price" : 5
}, {
"description" : "Long socks",
"id" : "product2",
"name" : "stockings",
"price" : 2
}, {
"description" : "This ball has air it.",
"id" : "product3",
"name" : "gloves",
"price" : 3
}, {
"description" : "Wear it pls.",
"id" : "product4",
"name" : "jersey",
"price" : 12
} ]
}
What can be the shortest way to find the number (count) of products in JavaScript? Does Firebase provide any query in JavaScript to find the count in an object?
Here is a simple solution. Just get the length of required array from the JSON Object.
var json = {
"product": [{
"description": "This ball has air it.",
"id": "product0",
"name": "football",
"price": 10
}, {
"description": "Can kick upto long distance.",
"id": "product1",
"name": "soccer boots",
"price": 5
}, {
"description": "Long socks",
"id": "product2",
"name": "stockings",
"price": 2
}, {
"description": "This ball has air it.",
"id": "product3",
"name": "gloves",
"price": 3
}, {
"description": "Wear it pls.",
"id": "product4",
"name": "jersey",
"price": 12
}]
};
console.log(json.product.length);
Incase of JSON string: Get the length like this
var json = '{ "product" : [ {"description" : "This ball has air it.","id" : "product0","name" : "football","price" : 10 }, {"description" : "Can kick upto long distance.","id" : "product1","name" : "soccer boots","price" : 5 }, {"description" : "Long socks","id" : "product2","name" : "stockings","price" : 2 }, {"description" : "This ball has air it.","id" : "product3","name" : "gloves","price" : 3 }, {"description" : "Wear it pls.","id" : "product4","name" : "jersey","price" : 12 } ]}';
var t = JSON.parse(json);
console.log(t.product.length);
You can save the object on JavaScript variable
var myData = {
"product" : [ {
"description" : "This ball has air it.",
"id" : "product0",
"name" : "football",
"price" : 10
}, {
"description" : "Can kick upto long distance.",
"id" : "product1",
"name" : "soccer boots",
"price" : 5
}, {
"description" : "Long socks",
"id" : "product2",
"name" : "stockings",
"price" : 2
}, {
"description" : "This ball has air it.",
"id" : "product3",
"name" : "gloves",
"price" : 3
}, {
"description" : "Wear it pls.",
"id" : "product4",
"name" : "jersey",
"price" : 12
} ]
}
Now you can get length
console.log(myData.product.length);
This question already has answers here:
Loading local JSON file
(26 answers)
Closed 7 years ago.
I have a JSON file with this as the content:
{
"residents": [
{
"name" : "Jacob",
"title" : "King",
"gender" : "Male",
},
{
"name" : "Luthor",
"title" : "Prince",
"gender" : "Male"
},
{
"name" : "Mileena",
"title" : "Princess",
"gender" : "Female"
},
]
}
I want to read the json in JavaScript, but certainly, I have no idea. How would I come about with this problem?
You can use JQuery for this.
$.ajax({
url: "\data.json", //name of your json file
success: function (data) {
var obj = JSON.parse(data);
}
});
Then you can get necessary property by the call of:
obj.residents[0].name
and so on.
It depends on environment that you use.
If you work with node.js you should read this file with API - fileRead
Then you should use JSON.parse for parsing it in {Object}
If you work in browser and some server has path to static with this file you can use ajax for getting this file
In both cases you should do such steps:
Get file as {String}
Parse to {Object}
Assuming this is for web because of your web tag, the easiest method is using jquery.
$.get('http://ip.jsontest.com', function(data) { console.log(data); });
If the server uses the correct MIME type in the response of the JSON then jquery will convert it to an object and "data" in the above example will be the evaluated JSON.
If the server does not use the correct MIME type you can wrap it in JSON.parse:
var json = JSON.parse(data);
Something like this?
$(function () {
$("#btnTest").click(function () {
var data = {
"residents": [{
"name": "Jacob",
"title": "King",
"gender": "Male",
}, {
"name": "Luthor",
"title": "Prince",
"gender": "Male"
}, {
"name": "Mileena",
"title": "Princess",
"gender": "Female"
}, ]
};
//If you're getting it somewhere from ajax call, than possibly it would be in string , in that case you need to `parse` it as data = JSON.parse(data);
$.each(data.residents, function (index, value) {
$("#data").append(value.name + " " + value.title + " " + value.gender + " </br>");
});
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="button" id="btnTest" value="Try Me!" />
<div id="data">
</div>
Try this..
var mymessage='{
"residents": [
{
"name" : "Jacob",
"title" : "King",
"gender" : "Male",
},
{
"name" : "Luthor",
"title" : "Prince",
"gender" : "Male"
},
{
"name" : "Mileena",
"title" : "Princess",
"gender" : "Female"
},
]
}';
var jsonData = JSON.parse(myMessage);
for (var i = 0; i < jsonData.residents.length; i++) {
var resident= jsonData.residents[i];
console.log(resident.name);
}
Using javascript you would just do...
obj = JSON.parse({
"residents": [
{
"name" : "Jacob",
"title" : "King",
"gender" : "Male",
},
{
"name" : "Luthor",
"title" : "Prince",
"gender" : "Male"
},
{
"name" : "Mileena",
"title" : "Princess",
"gender" : "Female"
},
]
});
You now have the JSON in an object that you can manage
console.log(obj);
You can fetch it like below
var text = '{
"residents":[
{
"name" : "Jacob",
"title" : "King",
"gender" : "Male",
},
{
"name" : "Luthor",
"title" : "Prince",
"gender" : "Male"
},
{
"name" : "Mileena",
"title" : "Princess",
"gender" : "Female"
},
]
}'; // That is your data from request
var obj = JSON.parse(text);
alert(obj.residents);
alert(obj.residents[0].name);
<script>
json_text = '{
"residents":[
{
"name" : "Jacob",
"title" : "King",
"gender" : "Male",
},
{
"name" : "Luthor",
"title" : "Prince",
"gender" : "Male"
},
{
"name" : "Mileena",
"title" : "Princess",
"gender" : "Female"
},
]}';
var obj = JSON.parse(json_text);
alert(obj.residents[2].name);
</script>
This code will bring up an alert dialog box in the browser with the value of name attribute of the second object in the array residents.
First and foremost your json string has error.
{
"residents": [
{
"name" : "Jacob",
"title" : "King",
"gender" : "Male",
},
{
"name" : "Luthor",
"title" : "Prince",
"gender" : "Male"
},
{
"name" : "Mileena",
"title" : "Princess",
"gender" : "Female"
},
]
}
There won't be comma after the third parenthesis from the end.
JSONString = '{ . . . . }';
JSONObject = JSON.parse(JSONString);
This way you can access the json data from JSONObject.
try this
<!docTpye html>
<html>
<head>
<script>
var data={
"residents": [
{
"name" : "Jacob",
"title" : "King",
"gender" : "Male",
},
{
"name" : "Luthor",
"title" : "Prince",
"gender" : "Male"
},
{
"name" : "Mileena",
"title" : "Princess",
"gender" : "Female"
},
]
}
for(var i=0;i<data.residents.length;i++){
console.log(data.residents[i].name);
alert(data.residents[i].name);
}
</script>
</head>
<body>
</body>
</html>
This is the JSON Array what Iam getting:
[
{
"Name" : "Sachin",
"Age" : "41",
"Team" : "Mumbai"
},
{
"Name" : "Dravid",
"Age" : "42",
"Team" : "Rajasthan"
},
{
"Name" : "Yuvraj",
"Age" : "31",
"Team" : "Bangalore"
}
]
But I need to sort this JSON array desc by the "Age" attribute.
My desired JSON Array should be like below:
[
{
"Name" : "Dravid",
"Age" : "42",
"Team" : "Rajasthan"
},
{
"Name" : "Sachin",
"Age" : "41",
"Team" : "Mumbai"
},
{
"Name" : "Yuvraj",
"Age" : "31",
"Team" : "Bangalore"
}
]
How to achieve this?
var a = [
{
"Name" : "Sachin",
"Age" : "41",
"Team" : "Mumbai"
},
{
"Name" : "Dravid",
"Age" : "42",
"Team" : "Rajasthan"
},
{
"Name" : "Yuvraj",
"Age" : "31",
"Team" : "Bangalore"
}
];
a.sort(function(x,y){return y["Age"]-x["Age"]});
console.log(a);
Use the following generic function predicateBy to sort your data by the desired field
var data=[
{
"Name" : "Sachin",
"Age" : "41",
"Team" : "Mumbai"
},
{
"Name" : "Dravid",
"Age" : "42",
"Team" : "Rajasthan"
},
{
"Name" : "Yuvraj",
"Age" : "31",
"Team" : "Bangalore"
}
]
function predicatBy(prop){
return function(a,b){
if( a[prop] > b[prop]){
return 1;
}else if( a[prop] < b[prop] ){
return -1;
}
return 0;
}
}
//Usage
data.sort( predicatBy("age") );
console.log(data);
var _ = require('underscore');
var data = ...your data...
console.log(_.sortBy(data, 'Age').reverse());
The naive answer would be to use Array.prototype.sort([compareFunction]). Something in the way of:
function compareAgeProperty(a,b) {
return (parseInt(a.Age) < parseInt(b.Age)) ? -1 : 1;
}
var arr = [/* your array's data here */];
arr.sort(compareAgeProperty);
I'd recommend you take a look at:
https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/sort
Your Age property is a string, and thus compared as a string, meaning '80'<'9'===true. Parsing the property should solve this issue.
Try this:
var arr = [
{
"Name" : "Sachin",
"Age" : "41",
"Team" : "Mumbai"
},
{
"Name" : "Dravid",
"Age" : "42",
"Team" : "Rajasthan"
},
{
"Name" : "Yuvraj",
"Age" : "31",
"Team" : "Bangalore"
}
]
var prop = "Age"
arr.sort(function(a,b){
var cmp = -1
if (a.hasOwnProperty(prop) && b.hasOwnProperty(prop)){
var a_prop_value = parseFloat(a[prop])
var b_prop_value = parseFloat(b[prop])
if (isNaN(a_prop_value) || isNaN(b_prop_value)){
//string comp
cmp = a[prop].localeCompare(b[prop])
}else{
cmp = a_prop_value - b_prop_value > 0? 1 : a_prop_value - b_prop_value ==0? 0:-1
}
}
return cmp;
});