Format data to be used in Highcharts series - javascript

Hi I am trying to make a stacked bar chart using Highcharts, but the way the data has to be formatted to be consumed as a a series is tripping me up.
series: [{
name: 'John',
data: [5]
}, {
name: 'ee',
data: [2]
}, {
name: 'aa',
data: [7]
},{
name: 'zz',
data: [4]
},{
name: 'Joe',
data: [3]
}]
That is how one of the examples is on their site for a stacked bar chart. I am using $http.get() to originally get data from a webservice, in JSON format like so :
{
"id": 13,
"name": "JohnSnow",
"totalScore": 5.239947894580996,
"models": [
{
"id": 0,
"name": "Grey",
"score": 75.5
},
{
"id": 1,
"name": "Black",
"score": 1.2355425046127677
},
{
"id": 2,
"name": "Purple",
"score": 24.0705126173457
},
{
"id": 3,
"name": "Teal",
"score": 28.981312850901684
},
{
"id": 4,
"name": "Yellow",
"score": 31.373482114014525
},
{
"id": 5,
"name": "Green",
"score": 22.02040979235661
},
{
"id": 6,
"name": "Red",
"score": 11.137161646416322
},
{
"id": 7,
"name": "Blue",
"score": 25.83014182677578
},
{
"id": 8,
"name": "Orange",
"score": 4.793888180490194
}
]
}
My original approach was to go through the returned data from the $http.get() call and add a JSON object to an array that I would then set series equal to but that isn't working out too well. What are some other options, or are there easier ways to get it in the format. The data has to stay in that format on the webservice, so changing is out of the question. I have a plunker I am trying to get working here.

interesting question, I normally use either angular.forEach or a library called underscore to handle data processing in angularJS. Here is the forEach version.
data = $http.get(); // suppose you have the data
result = [];
angular.forEach(data.models, function(item) {
// simple way is to take item as the original form
result.push(item);
// or do your own way
result.push({
name: item.name,
data: [item.score]
});
});
Now the result variable is the one you want now.

Related

Javascript array object creation with unique value as key

I have an array of objects, like this:
[{
"name": "xxx",
"order": 1,
"layerDtos": [{
"id": 1,
"dataType": 1
}, {
"id": 1,
"dataType": 2
}, {
"id": 1,
"dataType": 3
}]
},
{
"name": "yyy",
"order": 1,
"layerDtos": [{
"id": 1,
"dataType": 4
}, {
"id": 1,
"dataType": 5
}]
}
]
I want to create any object with key/value pairs as { 1: [ xxx, yyy ] }. I want to put all names in an array whose id inside layerDtos objects are the same.
Can someone explain how can I handle this? I tried using map() though it's not working and I am getting object like {1:xxx},{1:yyy} however, I need {1: [xxx,yyy]}

JS Mapping object picking nested array key-values to make them higher level key-values

HHello. I have a mapping issue. I have nested data and i need to manupulate it to pick some values from nested array and make them higher level key-values. Here is the data i have and the data i want.
Data i have;
[
{
"id": 1,
"sku": "24-MB01",
"name": "Joust Duffle Bag",
"price": 34,
"custom_attributes": [
{
"attribute_code": "image",
"value": "/m/b/mb01-blue-0.jpg"
},
{
"attribute_code": "small_image",
"value": "/m/b/mb01-blue-0.jpg"
},
{
"attribute_code": "thumbnail",
"value": "/m/b/mb01-blue-0.jpg"
}
]
},
{
"id": 2,
"sku": "24-MB04",
"name": "Strive Shoulder Pack",
"price": 32,
"custom_attributes": [
{
"attribute_code": "small_image",
"value": "/m/b/mb04-black-0.jpg"
},
{
"attribute_code": "image",
"value": "/m/b/mb04-black-0.jpg"
},
{
"attribute_code": "description",
"value": "<p>Convenience is next to nothing when your day is crammed with action. So whether you're heading to class, gym, or the unbeaten path, make sure you've got your Strive Shoulder Pack stuffed with all your essentials, and extras as well.</p>\n<ul>\n<li>Zippered main compartment.</li>\n<li>Front zippered pocket.</li>\n<li>Side mesh pocket.</li>\n<li>Cell phone pocket on strap.</li>\n<li>Adjustable shoulder strap and top carry handle.</li>\n</ul>"
},
{
"attribute_code": "activity",
"value": "5438,5448,5450,5445"
}
]
}
]
The Data I want;
[
{
"id": 1,
"sku": "24-MB01",
"name": "Joust Duffle Bag",
"price": 34,
"image":"/m/b/mb01-blue-0.jpg"
},
{
"id": 2,
"sku": "24-MB04",
"name": "Strive Shoulder Pack",
"price": 32,
"image":"/m/b/mb04-black-0.jpg"
}
]
What i have so far;
var items = products.items.map(item => {
const custom_attr = item.custom_attributes.find(attr => !!attr.image) || {};
delete item.custom_attributes;
return {
...item,
...custom_attr
};
});
So basically i dont need the nested array, i just need the image(or maybe another attribute) data. But in the array all keys are the same(code and value as u see). I've tryed some mapping but couldn't get there. So i could use some help. Thanks in advance :)
In order to extract the image custom attribute, you have to find() the entry whose attribute_code is image:
const items = data.map(({ custom_attributes, ...item }) => {
const image = custom_attributes.find(
({ attribute_code }) => attribute_code === 'image'
)?.value;
return {
...item,
image,
};
});
Your code was pretty close. Instead of checking for !!attr, I assume what you meant to do was find the custom attribute with attribute: "image":
.find((attr) => attr.attribute_code === "image")
Additionally, instead of using delete (which will mutate the original object), you can use object destructuring and spread (...) to omit the custom_attributes property from the output object:
const products = {
items: [
{
id: 1,
sku: "24-MB01",
name: "Joust Duffle Bag",
price: 34,
custom_attributes: [
{
attribute_code: "image",
value: "/m/b/mb01-blue-0.jpg",
},
{
attribute_code: "small_image",
value: "/m/b/mb01-blue-0.jpg",
},
{
attribute_code: "thumbnail",
value: "/m/b/mb01-blue-0.jpg",
},
],
},
{
id: 2,
sku: "24-MB04",
name: "Strive Shoulder Pack",
price: 32,
custom_attributes: [
{
attribute_code: "small_image",
value: "/m/b/mb04-black-0.jpg",
},
{
attribute_code: "image",
value: "/m/b/mb04-black-0.jpg",
},
{
attribute_code: "description",
value:
"<p>Convenience is next to nothing when your day is crammed with action. So whether you're heading to class, gym, or the unbeaten path, make sure you've got your Strive Shoulder Pack stuffed with all your essentials, and extras as well.</p>\n<ul>\n<li>Zippered main compartment.</li>\n<li>Front zippered pocket.</li>\n<li>Side mesh pocket.</li>\n<li>Cell phone pocket on strap.</li>\n<li>Adjustable shoulder strap and top carry handle.</li>\n</ul>",
},
{
attribute_code: "activity",
value: "5438,5448,5450,5445",
},
],
},
],
};
const items = products.items.map(({ custom_attributes, ...item }) => {
const custom_attr =
custom_attributes.find((attr) => attr.attribute_code === "image") || {};
return {
...item,
...custom_attr,
};
});
console.log(items);

Accessing nested array properties

This may be extremely simple but I've not been able to figure out how to iterate over and access the properties in the following mix (I think) of arrays and nested objects:
myFilters = {
"color_Filter": [{
"name": "BLUE",
"count": 1,
"dataId": "BLUE"
},
{
"name": "Black",
"count": 5,
"dataId": "Black"
},
{
"name": "Blue",
"count": 14,
"dataId": "Blue"
}
],
"size_Filter": [{
"name": "10",
"count": 16,
"dataId": "10"
},
{
"name": "12",
"count": 16,
"dataId": "12"
}
]
}
What would the correct looping structure be here to pull out name, count etc from the above? The desired output is to output a string from the above with color_Filter=BLUE,Black,Blue/size_Filter=10,12
I've tried a few different approaches and none of them have been successful so far.
You could map the entries of the object and create a string for each key. Get the name from the value array using map. Then join the array of strings with a /
const myFilters = {color_Filter:[{name:"BLUE",count:1,dataId:"BLUE"},{name:"Black",count:5,dataId:"Black"},{name:"Blue",count:14,dataId:"Blue"}],size_Filter:[{name:"10",count:16,dataId:"10"},{name:"12",count:16,dataId:"12"}]};
const output = Object.entries(myFilters)
.map(([k,arr]) => `${k}=${arr.map(a => a.name)}`)
.join("/")
console.log(output)

d3 vertical bar chart

How can I draw chart like this?
I have data (for example):
{
"USA": {
"value": 10,
"companies": [ "Apple", "Google" ],
"color": "red"
},
"Germany": {
"value": 3,
"companies": [ "SAP" ],
"color": "green"
}
}
"value" is for the left side.
"companies" is for the right side.
"value" != "compnaies" length.
I can't figure out what kind of graph I must use.
I'll try hierarchy, but it must have only one root.
i made a small poc but i'm not sure what you want so i can't really got much further please take a look at this : https://jsfiddle.net/z9bcfdvk/
i used the dataser you provided and added one entry:
Let me know if you want more detail.
var data = [
{
country: "USA",
"value": 10,
companies: ["Apple", "Google"],
"color": "#123445"
},
{
country: "Germany",
"value":
3,
companies:
["SAP"],
"color":
"#987456"
}, {
country: "France",
"value":
1,
companies:
["RENAULT"],
"color":
"#8b9838"
}
]

Adding items to different objects in a double for loop - Javascript

It's confusing to try to explain, but I want to be able to add a list of skill sets to different people objects that are in their own list.
For example:
I have a Json object of people:
"people": [
{
"id": 1,
"name": "Tony Rogers",
},
{
"id": 2,
"name": "Steven Grant",
},
{
"id": 3,
"name": "Peter Wilson",
},
]
and then I have a list of skills that I want to match up with them:
"skills": [
{
"id": 1,
"name": "Engineering",
"personId": 1
},
{
"id": 2,
"name": "Painting",
"personId": 2
},
{
"id": 3,
"name": "Chemistry",
"personId": 3
},
{
"id": 4,
"name": "Physics",
"personId": 1
},
]
but I am unsure how to get the output I want by looping through both lists. I would preferably like to append a "skills" section onto each person that contains all of their skills.
I thought I could do something along the lines of
people.forEach(function(person){
skills.forEach(function(skill){
if(skill.personId == person.id){
person['skills'] = {"name" : skill.name};
}
});
});
but it repeats a person multiple times rather than adding to their own skill list.
You need an array type to store multiple skills, so instead of just assigning person['skills'] = {"name" : skill.name}; create an array and push the new skill object to it.
people.forEach(function(person){
skills.forEach(function(skill){
if(skill.personId == person.id){
//creates an array, if not yet created
person['skills'] = person['skills'] || [];
//push the skill object to the array
person['skills'].push(skill.name);
}
});
});
If you have 20 persons and 20 skills, then it will be 20 * 20 = 400 loops!
You can do it more efficiently using just 2 loops:
var skillsByPerson = {};
skills.forEach(function(skill) {
var personId = skill.personId;
var personSkills = skillsByPerson[personId] || (skillsByPerson[personId] = []);
personSkills.push({ name: skill.name });
});
people.forEach(function(person) {
person.skills = skillsByPerson[person.id] || [];
});
Here is the jsPerf test proof for performance check.
You're overwriting skills on each iteration (this part: person['skills'] = {"name" : skill.name};), instead you need to push a skill into an array of skills:
var people = [
{"id": 1, "name": "Tony Rogers",},
{"id": 2, "name": "Steven Grant",},
{"id": 3, "name": "Peter Wilson",}];
var skills = [{
"id": 1,
"name": "Engineering",
"personId": 1
}, {
"id": 2,
"name": "Painting",
"personId": 2
}, {
"id": 3,
"name": "Chemistry",
"personId": 3
}, {
"id": 4,
"name": "Physics",
"personId": 1
}, ]
people.forEach(function(person) {
person['skills'] = []; // create an empty skills array for each person
skills.forEach(function(skill) {
if (skill.personId == person.id) {
person['skills'].push({"name": skill.name}); // push the skill
}
});
});
console.log(people);

Categories