I am trying to use wordcloud2.js to generate some word clouds. It works fine using the example given:
var options =
{
list : [
["Pear", "9"],
["Grape", "3"],
["Pineapple", "8"],
["Apple", "5"]
],
gridSize: Math.round(16 * document.getElementById('canvas_cloud').offsetWidth / 1024),
weightFactor: function (size) {
return Math.pow(size, 1.9) * document.getElementById('canvas_cloud').offsetWidth / 1024;
}
}
WordCloud(document.getElementById('canvas_cloud'), options);
However, I am struggling with populating "list :" with the data from a JSON file with the following structure:
[
{
"wordCloud": "Manchester",
"Freq": 2321
},
{
"wordCloud": "Munich",
"Freq": 566
},
{
...
},
{
"wordCloud": "Madrid",
"Freq": 6
}
]
I know it is because my limited knowledges on pushing values to arrays. So far, my tries have been:
$.getJSON('json/wordCloudGWT-' + site + '.json', function (data) {
var wordCloudGWT = [];
for (var i=0;i<100;i++) {
wordCloudGWT.push([data[i].wordCloud, data[i].Freq]);
};
console.log(wordCloudGWT);
var options =
{
list : wordCloudGWT,
gridSize: Math.round(16 * document.getElementById('canvas_cloud').offsetWidth / 1024),
weightFactor: function (size) {
return Math.pow(size, 1.9) * document.getElementById('canvas_cloud').offsetWidth / 1024;
}
}
WordCloud(document.getElementById('canvas_cloud'), options);
console.log(wordCloudGWT); shows an array with 100 (objects?) with a length of 2 each, but the wordcloud doesn't show. I see in my browser's console an error which I assume is because wordcloud2.js is not interpreting list : wordCloudGWT as I (erroneously) think it should be.
If I bruteforce the creation of the list this way
list : [
[data[0].wordCloud, "9"],
[data[1].wordCloud, "3"],
[data[2].wordCloud, "8"],
[data[3].wordCloud, "5"]
],
the words are shown correctly, but this approach has two problems:
Real frequency of words (word's size) is not considered
There is surelly more elegant ways to generate the list as manually adding 100 lines of code
For the first point, I figured that I could solve the problem by also manually editing the list this way:
list : [
[data[0].wordCloud, data[0].Freq],
[data[1].wordCloud, data[1].Freq],
[data[2].wordCloud, data[2].Freq],
[data[3].wordCloud, data[3].Freq]
],
However, doing that ends with the same JS error from my first attempt.
Any hint that can help me to bypass my difficulties?
You can use Array.map to format the data:
var formattedList = responseData.map(function(item) {
return [item.wordCloud, item.Freq]
});
Demo: http://jsfiddle.net/64v75enq/
It seems like the wordcloud2.js library expects the frequency value to be a string, and that is not the case of your json data. So improving on your own example code; add a toString() at the end of the Freq variable when pushing the values. Like this:
list : [
[data[0].wordCloud, data[0].Freq.toString()],
[data[1].wordCloud, data[1].Freq.toString()],
...
]
Related
I'm super newbie in coding and I need help to achieve this code.
I'm trying to get a random item (in pairs) from an array and then remove it from this array until user gets to the last item or 60 days have gone from using the service (cookie?)... I have build a script with the help of other questions here in stackoverflow and here is my results so far.
`<script>
var randomizer = document.getElementById("getImgBut");
var dog1 = '/app/wp-content/mediaApp/yo-creo-mi-realidad/01F.jpg';
var dog2 = '/app/wp-content/mediaApp/yo-creo-mi-realidad/01B.jpg';
var dogpics=[dog1,dog2];
var yourPics = [
dogpics,
[ '/app/wp-content/mediaApp/yo-creo-mi-realidad/02F.jpg', '/app/wp-content/mediaApp/yo-creo-mi-realidad/02B.jpg' ],
[ '/app/wp-content/mediaApp/yo-creo-mi-realidad/03F.jpg', '/app/wp-content/mediaApp/yo-creo-mi-realidad/03B.jpg' ],
[ '/app/wp-content/mediaApp/yo-creo-mi-realidad/04F.jpg', '/app/wp-content/mediaApp/yo-creo-mi-realidad/04B.jpg' ],
[ '/app/wp-content/mediaApp/yo-creo-mi-realidad/05F.jpg', '/app/wp-content/mediaApp/yo-creo-mi-realidad/05B.jpg' ],
[ '/app/wp-content/mediaApp/yo-creo-mi-realidad/06F.jpg', '/app/wp-content/mediaApp/yo-creo-mi-realidad/06B.jpg' ] //This array has 52 cards but I cutted it for example purposes
];
function get_random_number(array){
return Math.floor(Math.random() * array.length |0);
} // here is where I have tried to modify with other scripts like the one in this page https://stackoverflow.com/questions/38882487/select-random-item-from-array-remove-it-restart-once-array-is-empty with no success
randomizer.addEventListener("click", function() {
var rand_number = get_random_number(yourPics);
console.log(rand_number);
document.getElementById('img1').src = yourPics[rand_number][0];
document.getElementById('img2').src = yourPics[rand_number][1];
});
var card = document.querySelector('.card');
card.addEventListener( 'click', function() {
card.classList.toggle('is-flipped');
});
</script>`
Thank you for your help!
I don't fully understand what you mean by "remove in pairs", but I'll answer presuming you mean you wish to remove the image ending in 02F.jpg at the same time as removing the image ending in 02B.jpg, and then 03F.jpg at the same time as 03B.jpg.
The solution to this that I will propose is that we will structure your data a bit differently to begin with. That is, if those images, the "B image" and "F image" are linked, we could keep them in the same `javascript object. This would look like:
var yourPics = [
{
bImage: '/app/wp-content/mediaApp/yo-creo-mi-realidad/02F.jpg',
fImage: '/app/wp-content/mediaApp/yo-creo-mi-realidad/02B.jpg'
},
{
bImage: '/app/wp-content/mediaApp/yo-creo-mi-realidad/03F.jpg',
fImage: '/app/wp-content/mediaApp/yo-creo-mi-realidad/03B.jpg'
}...]
This would then be an array of objects, rather than strings. We can access the bImage property of an object with just
myObject = yourPics[0]
myObject.bImage
We could delete one of those objects those at random via splice.
myRandomlyRemovedObject = yourPics.splice(myIndexToDeleteFrom, 1) would remove 1 object from yourPics at position of myIndexToDeleteFrom, which you presumably would choose randomly. myRandomlyRemovedObject would be assigned to the one object we removed.
I think this object based approach is safer since you will know for a fact that you will removed both matching strings at the same time.
I have made a JSON object and getting so many errors. I am new to JSON so kindly help. Posting here with the screenshots.
Any help would be appreciated.
[![var data\[\]= {"cars":
"Honda":\[
{"model":"Figo" },
{"model":"City"}
\],
"Audi": \[
{"model":"A6"},
{"model":"A8"}
\]
}
data.cars\['Honda'\]\[0\].model
data.cars\['Honda'\]\[1\].model
data.cars\['Audi'\]\[0\].model
ata.cars\['Audi'\]\[1\].model
for (var make in data.cars) {
for (var i = 0; i < data.cars\[make\].length; i++) {
var model = data.cars\[make\]\[i\].model;
alert(make + ', ' + model);
}
}][1]][1]
Using JSONformatter and validator site for checking my code.
Since you mentioned
I am totally novice for JSON
I would like to explain you this completely.
There are little bit of syntax errors in the way you are doing this. You are actually doing a for loop inside a javascript object which will obviously break. If your intention is to alert all the models of all the make, then here is how you do it..
initially you have this
var data = {
cars:{
"Honda":
[
{"model":"Figo" },
{"model":"City"}
],
"Audi":
[
{"model":"A6"},
{"model":"A8"}
]
}
}
You have a variable called data which is a object ({} refers to object) and this object has a property called cars and this property holds a object({} refers to object). Now this object has 2 properties Honda and Audi. Each of this properties are of type array ([] refers to array). And this each array further contains list of objects.
So once you are clear with the above point. Let manipulate the object you have.
Do a forloop to get all the properties of the cars object and when we have hold of each property lets loop its array and then extract the model property value.
for (var make in data.cars) {
for (var i = 0; i < data.cars[make].length; i++) {
var model = data.cars[make][i].model;
alert(make + ', ' + model);
}
}
Also dont get confused with Javascript Object and JSON....
In the above example the variable data is Javascript Object and when you do JSON.strinfigy(data) you are converting this Javascript object into string format and that string format is called JSON...
A Demo Fiddle to help you understand better.
Imho it's more like :
var cars = {
"Honda":
[
{"model":"Figo" },
{"model":"City"}
],
"Audi":
[
{"model":"A6"},
{"model":"A8"}
]
}
If you want a huge JSON object storing many cars attributes arrays.
Why do you use these "/" everywhere ?
(PS : if you wanna see some examples -> http://json.org/example.html)
I believe this is the structure your looking for:
cars={
make:{
honda:[
{
model:"accord",
color:"black",
cylinders: "6",
year:"2012"
},
{
model:"civic",
color:"white",
cylinders: "4",
year:"2015"
}
],
acura:[
{
model:"integra",
color:"red",
cylinders: "4",
year:"1992"
},
{
model:"RSX",
color:"Metallic Blue",
cylinders: "4",
year:"2016"
}
],
audi:[
{
model:"R8",
color:"white",
cylinders: "8",
year:"2015"
},
{
model:"A8",
color:"red",
cylinders: "8",
year:"2016"
}
]
}
};
document.addEventListener('DOMContentLoaded',()=>{
var models=[],colors=[],cylinder=[],year=[]; //INSTANTIATE ARRAYS
for(p in cars.make){ //LOOP THROUGH OBJECT PROPS (CARS.MAKE)
cars.make[p].forEach((o)=>{ //LOOP THROUGH (CARS.CARS.PROPS) PUSH OBJ INTO ARRAYS
models.push(o.model);
colors.push(o.color);
cylinders.push(o.cylinders);
year.push(o.year);
});
console.log(models);
console.log(colors);
console.log(cylinders);
console.log(year);
});
var jsonData = JSON.parse(pump_array);
var name_array = [];
var data_array = [];
for(var i=0;i<jsonData.pumps.length;i++)
{
data_array.push(data_array, pump_array.pumps[i].volume);
name_array.push(name_array, pump_array.pumps[i].iName);}
this is my javascript code. I am trying to parse out specific pieces of the following json array in order to place it into a graph using chart.js
var pump_array = {
"pumps":[
{
"id": 1,
"isPrimed":true,
"iName": "Whiskey",
"volume": 850,
"debug": "Test"
},
{
"id": 2,
"isPrimed":true,
"iName": "Vodka",
"volume": 900,
"debug": "Test"
}
]
}
There seem to be several things wrong here. First of all, you're calling JSON.parse on something that's not a string. It's a full-fledged Javascript object. There's no need to parse it; just use it.
Second of all, these two lines have an extra variable each:
data_array.push(data_array, pump_array.pumps[i].volume);
name_array.push(name_array, pump_array.pumps[i].iName);}
Presumably they should read:
data_array.push(pump_array.pumps[i].volume);
name_array.push(pump_array.pumps[i].iName);}
But even if you correct these problems, you still end up with a less-than-ideal data structure:
name_array; //=> ["Whiskey", "Vodka"]
data_array; //=> [850, 900]
Instead of a single, useful data structure, you end up with two different ones that are only useful via shared indices.
How about something like this instead?:
pump_array.pumps.reduce(function(soFar, pump) {
soFar[pump.iName] = pump.volume;
return soFar;
}, {});
//=> {Whiskey: 850, Vodka: 900}
To my eyes, that's a much more useful data structure.
As Iam new to javascript, I found handleBar.js can be used to template with dynamic data.
I worked on a sample which worked fine and the json structure was simple and straight forward.
(function()
{
var wtsource = $("#some-template").html();
var wtTemplate = Handlebars.compile(wtsource);
var data = { users: [
{url: "index.html", name: "Home" },
{url: "aboutus.html", name: "About Us"},
{url: "contact.html", name: "Contact"}
]};
Handlebars.registerHelper('iter', function(context, options) {
var fn = options.fn, inverse = options.inverse;
var ret = "";
if(context && context.length > 0) {
for(var i=0, j=context.length; i<j; i++) {
ret = ret + fn($.extend({}, context[i], { i: i, iPlus1: i + 1 }));
}
} else {
ret = inverse(this);
}
return ret;
});
var temp=wtTemplate(data);
$("#content").html(temp);
})();
<script id="some-template" type="text/x-handlebars-template">
{{#iter users}}
<li>
{{name}}
</li>
{{/iter}}
</script>
How to iterate a json with the below structure ? Please do suggest the possible way for iterating and creating the template for the below json structure
var newData = { "NEARBY_LIST": {
"100": {
"RestaurantID": 100,
"ParentRestaurantID": 0,
"RestaurantName": "Chennai Tiffin",
"listTime": [{
"startTime": "10:00",
"closeTime": "23:30"
} ]
},
"101": {
"RestaurantID": 101,
"ParentRestaurantID": 0,
"RestaurantName": "Biriyani Factory",
"listTime": [{
"startTime": "11:00",
"closeTime": "22:00"
}]
}
}
};
Accessing the properties of an object has nothing to do with Handlebars. If you dealing with JSON and you wish to access it in general bracket or dot notation, you must first parse the JSON into a JavaScript object using the JSON.parse() function.
After this is done, you may access the properties as follows.
var property = newData['NEARBY_LIST']['100'].RestaurantName; // "Chennai Tiffin"
Here is a fiddle to illustrate.
http://jsfiddle.net/qzm0cygu/2/
I'm not entirely sure what you mean, but if your question is how you can use/read the data in newData, try this:
newData = JSON.parse(newData); //parses the JSON into a JavaScript object
Then access the object like so:
newData.NEARBY_LIST //the object containing the array
newData.NEARBY_LIST[0] //the first item (key "100")
newData.NEARBY_LIST[1] //the second item (key "101")
newData.NEARBY_LIST[0][0] //the first field of the first item (key "RestaurantID", value "100")
newData.NEARBY_LIST[0][2] //the third field of the first item (key "RestaurantName", value "Chennai Tiffin")
newData.NEARBY_LIST[0][3][0] //the first field of the fourth field of the first item (key "startTime", value "11:00")
I hope this was what you were looking for.
EDIT: as Siddharth points out, the above structure does assume you have arrays. If you are not using arrays you can access the properties by using their names as if they're in an associative array (e.g. newData["NEARBY_LIST"]["100"]. The reason I say "properties" and "as if" is because technically JavaScript doesn't support associative arrays. Because they are technically properties you may also access them like newData.NEARBY_LIST (but I don't recommend that in this case as a property name may not start with a number, so you would have to use a mix of the different notations).
On that note, I would recommend using arrays because it makes so many things easier (length checks, for example), and there are practically no downsides.
EDIT2: also, I strongly recommend using the same camelcasing conventions throughout your code. The way you currently have it (with half your properties/variables starting with capitals (e.g. "RestaurantName", "RestaurantID") and the other half being in lowerCamelCase (e.g. "listTime", "startTime")) is just asking for people (you or colleagues) to make mistakes.
I am working with d3.js to visualise families of animals (organisms) (up to 4000 at a time) as a tree graph, though the data source could just as well be a directory listing, or list of namespaced objects. my data looks like:
json = {
organisms:[
{name: 'Hemiptera.Miridae.Kanakamiris'},
{name: 'Hemiptera.Miridae.Neophloeobia.incisa'},
{name: 'Lepidoptera.Nymphalidae.Ephinephile.rawnsleyi'},
... etc ...
]
}
my question is: I am trying to find the best way to convert the above data to the hierarchical parent / children data structure as is used by a number of the d3 visualisations such as treemap (for data example see flare.json in the d3/examples/data/ directory).
Here is an example of the desired data structure:
{"name": "ROOT",
"children": [
{"name": "Hemiptera",
"children": [
{"name": "Miridae",
"children": [
{"name": "Kanakamiris", "children":[]},
{"name": "Neophloeobia",
"children": [
{"name": "incisa", "children":[] }
]}
]}
]},
{"name": "Lepidoptera",
"children": [
{"name": "Nymphalidae",
"children": [
{"name": "Ephinephile",
"children": [
{"name": "rawnsleyi", "children":[] }
]}
]}
]}
]}
}
EDIT: enclosed all the original desired data structure inside a ROOT node, so as to conform with the structure of the d3 examples, which have only one master parent node.
I am looking to understand a general design pattern, and as a bonus I would love to see some solutions in either javascript, php, (or even python). javascript is my preference.
In regards to php: the data I am actually using comes from a call to a database by a php script that encodes the results as json.
database results in the php script is an ordered array (see below) if that is any use for php based answers.
Array
(
[0] => Array
(
['Rank_Order'] => 'Hemiptera'
['Rank_Family'] => 'Miridae'
['Rank_Genus'] => 'Kanakamiris'
['Rank_Species'] => ''
) ........
where:
'Rank_Order' isParentOf 'Rank_Family' isParentOf 'Rank_Genus' isParentOf 'Rank_Species'
I asked a similar question focussed on a php solution here, but the only answer is not working on my server, and I dont quite understand what is going on, so I want to ask this question from a design pattern perspective, and to include reference to my actual use which is in javascript and d3.js.
The following is specific to the structure you've provided, it could be made more generic fairly easily. I'm sure the addChild function can be simplified. Hopefully the comments are helpful.
function toHeirarchy(obj) {
// Get the organisms array
var orgName, orgNames = obj.organisms;
// Make root object
var root = {name:'ROOT', children:[]};
// For each organism, get the name parts
for (var i=0, iLen=orgNames.length; i<iLen; i++) {
orgName = orgNames[i].name.split('.');
// Start from root.children
children = root.children;
// For each part of name, get child if already have it
// or add new object and child if not
for (var j=0, jLen=orgName.length; j<jLen; j++) {
children = addChild(children, orgName[j]);
}
}
return root;
// Helper function, iterates over children looking for
// name. If found, returns its child array, otherwise adds a new
// child object and child array and returns it.
function addChild(children, name) {
// Look for name in children
for (var i=0, iLen=children.length; i<iLen; i++) {
// If find name, return its child array
if (children[i].name == name) {
return children[i].children;
}
}
// If didn't find name, add a new object and
// return its child array
children.push({'name': name, 'children':[]});
return children[children.length - 1].children;
}
}
Given your starting input I believe something like the following code will produce your desired output. I don't imagine this is the prettiest way to do it, but it's what came to mind at the time.
It seemed easiest to pre-process the data to first split up the initial array of strings into an array of arrays like this:
[
["Hemiptera","Miridae","Kanakamiris" ],
["Hemiptera","Miridae","Neophloeobia","incisa" ],
//etc
]
...and then process that to get a working object in a form something like this:
working = {
Hemiptera : {
Miridae : {
Kanakamiris : {},
Neophloeobia : {
incisa : {}
}
}
},
Lepidoptera : {
Nymphalidae : {
Ephinephile : {
rawnsleyi : {}
}
}
}
}
...because working with objects rather than arrays makes it easier to test whether child items already exist. Having created the above structure I then process it one last time to get your final desired output. So:
// start by remapping the data to an array of arrays
var organisms = data.organisms.map(function(v) {
return v.name.split(".");
});
// this function recursively processes the above array of arrays
// to create an object whose properties are also objects
function addToHeirarchy(val, level, heirarchy) {
if (val[level]) {
if (!heirarchy.hasOwnProperty(val[level]))
heirarchy[val[level]] = {};
addToHeirarchy(val, level + 1, heirarchy[val[level]]);
}
}
var working = {};
for (var i = 0; i < organisms.length; i++)
addToHeirarchy(organisms[i], 0, working);
// this function recursively processes the object created above
// to create the desired final structure
function remapHeirarchy(item) {
var children = [];
for (var k in item) {
children.push({
"name" : k,
"children" : remapHeirarchy(item[k])
});
}
return children;
}
var heirarchy = {
"name" : "ROOT",
"children" : remapHeirarchy(working)
};
Demo: http://jsfiddle.net/a669F/1/
An alternative answer to my own question....In the past day I have learn't a great deal more about d3.js and in relation to this question d3.nest() with .key() and .entries() is my friend (all d3 functions).
This answer involves changing the initial data, so it may not qualify as a good answer to the specific question i asked. However if someone has a similar question and can change things on the server then this is a pretty simple solution:
return the data from the database in this format:
json = {'Organisms': [
{ 'Rank_Order': 'Hemiptera',
'Rank_Family': 'Miridae',
'Rank_Genus': 'Kanakamiris',
'Rank_Species': '' },
{}, ...
]}
Then using d3.nest()
organismNest = d3.nest()
.key(function(d){return d.Rank_Order;})
.key(function(d){return d.Rank_Family;})
.key(function(d){return d.Rank_Genus;})
.key(function(d){return d.Rank_Species;})
.entries(json.Organism);
this returns:
{
key: "Hemiptera"
values: [
{
key: "Cicadidae"
values: [
{
key: "Pauropsalta "
values: [
{
key: "siccanus"
values: [
Rank_Family: "Cicadidae"
Rank_Genus: "Pauropsalta "
Rank_Order: "Hemiptera"
Rank_Species: "siccanus"
AnotherOriginalDataKey: "original data value"
etc etc, nested and lovely
This returns something very much similar to they array that I described as my desired format above in the question, with a few differences. In particular, There is no all enclosing ROOT element and also whereas they keys I originally wanted were "name" and "children" .nest() returns keys as "key" and "values" respectively.
These alternatives keys are easy enough to use in d3.js by just defining appropriate data accessor functions (basic d3 concept) ... but that is getting beyond the original scope of the question ... hope that helps someone too