I am working on chart library,
I have json format, which will be coming from server, year and month format
{
"id": 1,
"name": "name1",
"present": "18",
"target": "18",
"status": "yellow"
}
Now I need to pass present and target values in a array format.
the data must be passed or parsed like below.
How to do I do this in javascript and jquery?
I tried all the available solutions, since I am new to the javascript world!
Expected result
var legendsText = [["present name1","target name1"]],
jsonFormat = [[18, 18],[15,18],[36, 18]];
FIDDLE
This is the fiddle our friend Eli Gassert has created, it is the closeset one
http://http://jsfiddle.net/Yq3DW/126/
but it is loading only present values of all 3 months
i want present and target values of each name.
For example
name1 link clicked, chart should load name1 present and target for all 3 months.
name2 link clicked, chart should load name2 present and target for all 3 months.
name3 link clicked, chart should load name3 present and target for all 3 months.
My JSON format which is coming dynamically from server
data={
"perspective": "something",
"year": "2014",
"measures": [
{
"id": 1,
"name": "some name",
"target": "200",
"responsiblePerson": null
},
{
"id": 2,
"name": "some name",
"target": "100",
"responsiblePerson": null
}
],
"values": {
"jan": [
{
"id": 1,
"name": "name1",
"present": "18",
"target": "18",
"status": "yellow"
},
{
"id": 2,
"name": "name2",
"present": "21",
"target": "22",
"status": "red"
},
{
"id": 3,
"name": "name3",
"present": "50",
"target": "50",
"status": "yellow"
}
],
"feb": [
{
"id": 1,
"name": "name1",
"present": "18",
"target": "18",
"status": "yellow"
},
{
"id": 2,
"name": "name2",
"present": "21",
"target": "22",
"status": "red"
},
{
"id": 3,
"name": "name3",
"present": "50",
"target": "50",
"status": "yellow"
}
],
"mar": [
{
"id": 1,
"name": "name1",
"present": "18",
"target": "18",
"status": "yellow"
},
{
"id": 2,
"name": "name2",
"present": "22",
"target": "22",
"status": "yellow"
},
{
"id": 3,
"name": "name3",
"present": "52",
"target": "50",
"status": "yellow"
}
]
}
}
HTML
<div id="chart"></div>
JS
var legendsText = [];
for(var i = 0; i != data.measures.length; ++i)
legendsText.push(data.measures[i].name);
legendsText = [legendsText];
var rows = [];
for(var i in data.values)
{
var row = []
for(var j = 0; j != data.values[i].length; ++j)
{
row.push(data.values[i][j].present);
}
rows.push(row);
}
rows = legendsText.concat(rows.sort(function (a, b) { }));
console.log(rows);
var chart = c3.generate({
bindto: '#chart',
data: {
rows: rows,
type: 'bar',
}
});
Any help is appreciated.
Here's an updated fiddle that transforms your data to the results: http://jsfiddle.net/Yq3DW/119/
Key aspects:
Your Legend Text can be gotten dynamically from your measures data. The format for the legendsText is an "array of arrays" so that's why I wrap it in [...] at the end of the loop.
var legendsText = [];
for(var i = 0; i != data.measures.length; ++i)
legendsText.push(data.measures[i].name);
legendsText = [legendsText];
Your rows can be gotten from your "values" data. But because it's not an array, like measures you need to use a for each loop instead of for loop:
var rows = [];
for(var i in data.values)
{
var row = []
for(var j = 0; j != data.values[i].length; ++j)
{
row.push(data.values[i][j].present);
}
rows.push(row);
}
EDIT: Updated question. To show just one label's worth of data but show both values for that data, and give nice labels: http://jsfiddle.net/Yq3DW/130/
The key here:
Switch to columns instead of rows, allowing one "row" of data to stand-in for the label indexer
Only add the data if the name in the value data matches the name you're searching for (had to update your data JSON so the names matched)
Had to use a 'tick' formatter to format the labels from 1-3 to jan, feb, mar. You can further customize it by using upper case/proper case conversions. That is outside the scope of this question and I'm not including it here. If you need further formatting, search for an answer first and if you can't find it, start a new Q.
Display a dynamic list of links to click that calls your loadData function to change the data in the chart between the various measure names
HTML:
<ul id="links"></ul>
<div id="chart"></div>
JS:
var $links = $('#links');
$links.html('');
for(var i = 0; i != data.measures.length; ++i)
{
(function()
{
var name = data.measures[i].name;
$('<li></li>')
.text(data.measures[i].name)
.click(function() { loadData(name); })
.appendTo($links);
})();
// legendsText.push(data.measures[i].name);
}
function loadData(name)
{
//var legendsText = [ ["present", "target"] ];
var columns = [ ["labels"], [ "present" ], [ "target" ]];
var labels = [];
for(var i in data.values)
{
var row = []
for(var j = 0; j != data.values[i].length; ++j)
{
if(data.values[i][j].name == name)
{
labels.push(i);
columns[0].push(labels.length);
columns[1].push(data.values[i][j].present);
columns[2].push(data.values[i][j].target);
}
}
//rows.push(row);
}
console.log(columns);
//rows = legendsText.concat(rows.sort(function (a, b) { }));
var chart = c3.generate({
bindto: '#chart',
data: {
x: 'labels',
columns: columns,
type: 'bar',
},
axis: {
x: {
tick: {
format: function(index) { return labels[index-1]; }
}
}
}
});
}
Related
I have a json file and I want to convert the data into a table with Javascript. I found some similar questions How to convert the following table to JSON with javascript? , loop through a json object, but they all use jQuery and show the table on html web. I just need a simple loop to insert row into the table. I tried 'append', 'insert' and 'insertRow', all not work. Could anyone give me a hint?
Json file:
{
"name": "lily",
"country": "china",
"age": 23
},
{
"name": "mike",
"country": "japan",
"age": 22
},
{
"name": "lucy",
"country": "korea",
"age": 25
}
My code:
var jdata = {};
jdata.cols = [
{
"id": "1",
"label": "name",
"type": "string"
},
{
"id": "2",
"label": "country",
"type":"string"
}
];
for(var i = 1; i < 3; i++){
row = [
{
"c": [
{
"v": json["hits"]["hits"][i]["_source"]["name"]
},
{
"v": json["hits"]["hits"][i]["_source"]["country"]
}
]
}
];
jdata.rows.insertRow(row);
}
Edit: Add expected output: change the json file to the following structure.
[
['lily', 'china'],
['mike', 'japan'],
['lucy', 'korea'],
]
I guess you need push (Or concat / push(...elements) if you want to add array of rows)
jdata.rows = [];
for(var i = 1; i < 3; i++){
row = [
{
"c": [
{
"v": json["hits"]["hits"][i]["_source"]["name"]
},
{
"v": json["hits"]["hits"][i]["_source"]["country"]
}
]
}
];
jdata.rows.push(row);
// for elements from row
// jdata.rows.push(...row)
}
There are a few errors in your code
The JSON needs to be an array so you can loop through each object to display.
insertRow() is a method from the Table object, jdata.rows is not a Table object but an array.
Since, you have used insertRow(), I have rewritten your code to display the table data using the Table Object methods. Here is a code snippet
Edit: You can use the push() method to create your required JSON structure. I have edited the code snippet to create your required JSON.
var jdata = {
cols: [{
"id": "1",
"label": "name",
"type": "string"
},
{
"id": "2",
"label": "country",
"type": "string"
}
],
rows: []
};
var persons = [{
"name": "lily",
"country": "china",
"age": 23
},
{
"name": "mike",
"country": "japan",
"age": 22
}, {
"name": "lucy",
"country": "korea",
"age": 25
}
];
var table = document.getElementById("table");
var header = table.createTHead();
var footer = table.createTFoot();
var rowHeader = header.insertRow(0);
jdata.cols.forEach((col, index) => {
var cell = rowHeader.insertCell(index);
cell.innerHTML = col.label;
});
persons.forEach((person, index) => {
var rowFooter = footer.insertRow(index);
rowFooter.insertCell(0).innerHTML = person.name;
rowFooter.insertCell(1).innerHTML = person.country;
jdata.rows.push([person.name, person.country]);
});
console.log(jdata.rows);
<table id="table">
</table>
I am trying to create a company hierarchy graph using D3..using the code from this example:
http://bl.ocks.org/mbostock/2949981
Is there a way to create that graph from this json:
links = [
{
"Source": "1",
"Target": "2",
},
{
"Source": "1",
"Target" : "3"
},
{
"Source": "2",
"Target": "4",
},
{
"Source": "2",
"Target": "5",
},
{
"Source" : "3",
"Target" " "6"
}
]
nodes = [
{
"Id": "1",
"Name": "TEST NODE ONE",
"Url": "http://www.google.com"
},
{
"Id": "2",
"Name": "TEST NODE TWO",
"Url": "http://www.yahoo.com"
},
{
"Id": "3",
"Name": "TEST NODE THREE",
"Url": "http://www.stackoverflow.com"
},
{
"Id": "4",
"Name": "TEST NODE FOUR",
"Url": "http://www.reddit.com"
}
{
"Id": "5",
"Name": "TEST NODE FIVE",
"Url": "http://www.stack.com"
}
{
"Id": "6",
"Name": "TEST NODE SIX",
"Url": "http://www.six.com"
}
]
I want to make each node a rectangle where I can put the employee name, which comes from the "nodes" json. But connect each node with the data in the "link" json. Feel free to alter the link json to have it make more sense to you.
I would also like to make the lines connecting the nodes straight and make it vertical as well but my main concern is displaying the graph on the page via the json above.
Thanks for the help.
You need to convert your links, which associates between ids of nodes, to an array that associates — via reference — between the actual objects in nodes. A simple loop does this:
var links = [ { "Source": "1", "Target": "2" }, ... ]
var nodes = [ { "Id": "1", "Name": "TEST NODE ONE", "Url": "http://www.google.com" }, ... ]
var cachedNodesById = {};
var linksBetweenNodeObjs = links.map(funciont(link) {
return {
source: nodeById(link.Source),
target: nodeById(link.Target)
};
});
function nodeById(id) {
// return the node if it's been found before, otherwise loop over the
// array to find it
if(cachedNodesById[id] != null) { return cachedNodesById[id]; }
else {
for(var i=0; i < nodes.length; i++) {
if(nodes[i].Id == id) { return cachedNodesById[id] = nodes[i]; }
}
}
}
I have below code using which am able to push new row into my json object, but couldn't add parent fieldname like (d0,d1,d2.. ) into the newly added row, how can i do it?
Code:
var d = [{
"id": 0,
"name": "Housing",
"value": 71
}, {
"id": 1,
"name": "Travel",
"value": 85
}, {
"id": 2,
"name": "Restaurant",
"value": 44
}, {
"id": 3,
"name": "Bank",
"value": 33
}];
var dataset = {};
d.forEach(function (e, i) {
dataset['d' + i] = e;
});
alert(JSON.stringify(dataset,null,2));
var input='Banking';
var dataset_final={};
d.forEach(function (e, i) {
counter=i;
});
alert(counter+1);
var input='Movies';
d.push({id:counter+1,name:input,value:"3"});
alert(JSON.stringify(d,null,2))
I would like to push data into 'dataset' variable directly. How can add parent field name like 'd4' for 4th row which will be newly added for the name: Movies ?
You can do something like this:
var counter = Object.keys(dataset).length;
dataset['d' + counter] = {name: 'Banking', value: 100};
Here is the my first JSON Array format...
[
{
"id": "1234",
"caption": "caption1"
},
{
"id": "2345",
"caption": "caption2"
},
{
"id": "3456",
"caption": "caption3"
}
]
and here is another JSON Array Format
[
[
{
"id": "1234",
"value": "value11"
},
{
"id": "2345",
"value": "value12"
},
{
"id": "3456",
"value": "value13"
}
],
[
{
"id": "1234",
"value": "value21"
},
{
"id": "2345",
"value": "value22"
},
{
"id": "3456",
"value": "value23"
}
]
]
The above mentioned Two JSON Arrays, i need to compare each one with Id and need to format a new JSON Array with caption and value using javascript.
[
[
{
"caption" : "caption1",
"value":"value11"
},
{
"caption" : "caption2",
"value":"value12"
},
{
"caption" : "caption3",
"value":"value13"
}
],
[
{
"caption" : "caption1",
"value":"value21"
},
{
"caption" : "caption2",
"value":"value22"
},
{
"caption" : "caption3",
"value":"value23"
}
]
]
Please help me out.
You can do it in many ways. Below I show two variants:
Option 1: Pure JavaScript
In this example the program preindex first array for faster access to it data, and then loops over second array with map() function to create new array of arrays:
// Create index version of first array
var aix = {};
for(var i=0;i<arr1.length;i++) {
aix[arr1[i].id] = arr1[i].caption;
}
// Loop over array of arrays
var res1 = arr2.map(function(arr22){
return arr22.map(function(a){
return {caption:aix[a.id], value:a.value};
}
});
Option 2: Using special SQL library (Alasql)
Here, you can JOIN to arrays automatically with special SQL statement:
var res2 = arr2.map(function(a){
return alasql('SELECT arr1.caption, a.[value] \
FROM ? a JOIN ? arr1 USING id',[a,arr1]);
});
You can try these variants in working snippet below or play with it in jsFiddle.
(Disclaimer: I am the author of Alasql)
var arr1 = [
{
"id": "1234",
"caption": "caption1"
},
{
"id": "2345",
"caption": "caption2"
},
{
"id": "3456",
"caption": "caption3"
}
];
var arr2 = [
[
{
"id": "1234",
"value": "value11"
},
{
"id": "2345",
"value": "value12"
},
{
"id": "3456",
"value": "value13"
}
],
[
{
"id": "1234",
"value": "value21"
},
{
"id": "2345",
"value": "value22"
},
{
"id": "3456",
"value": "value23"
}
]
];
// JavaScript version
var aix = {};
for(var i=0;i<arr1.length;i++) {
aix[arr1[i].id] = arr1[i].caption;
}
var res1 = arr2.map(function(arr22){
return arr22.map(function(a){
return {caption:aix[a.id], value:a.value};
});
});
document.getElementById("res1").textContent = JSON.stringify(res1);
// Alasql version
var res2 = arr2.map(function(a){
return alasql('SELECT arr1.caption, a.[value] FROM ? a JOIN ? arr1 USING id',[a,arr1]);
});
document.getElementById("res2").textContent = JSON.stringify(res2);
<script src="http://alasql.org/console/alasql.min.js"></script>
<p>Varian 1: JavaScript</p>
<div id="res1"></div>
<p>Variant 2: Alasql</p>
<div id="res2"></div>
From the below JSON, how can I retrieve title from the note and notes using a for loop and ajax to retrieve?
{
"infos": {
"info": [
{
"startYear": "1900",
"endYear": "1930",
"timeZoneDesc": "daweerrewereopreproewropewredfkfdufssfsfsfsfrerewrBlahhhhh..",
"timeZoneID": "1",
"note": {
"notes": [
{
"id": "1",
"title": "Mmm"
},
{
"id": "2",
"title": "Wmm"
},
{
"id": "3",
"title": "Smm"
}
]
},
"links": [
{ "id": "1", "title": "Red House", "url": "http://infopedia.nl.sg/articles/SIP_611_2004-12-24.html" },
{ "id": "2", "title": "Joo Chiat", "url": "http://www.the-inncrowd.com/joochiat.htm" },
{ "id": "3", "title": "Bake", "url": "https://thelongnwindingroad.wordpress.com/tag/red-house-bakery" }
]
}
I tried out the code below but it doesn't work - it either says:
is null
not an object
length is null
r not an object
var detail = eval(xmlhttprequest.responseText)
var rss = detail.infos.info
for(var i = 0; i<rss.length; i++)
startyear += rss[i].startyear
Use
for (i = 0; i < 3; i++) {
alert(JSON.infos.info[0].note.notes[i].title);
}
TRY IT HERE: JSFIDDLE WORKING EXAMPLE
BTW your JSON is not valid. Use this JSON:
var JSON = {
"infos": {
"info": [
{
"startYear": "1900",
"endYear": "1930",
"timeZoneDesc": "daweerrewereopreproewropewredfkfdufssfsfsfsfrerewrBlahhhhh..",
"timeZoneID": "1",
"note": {
"notes": [
{
"id": "1",
"title": "Mmm"
},
{
"id": "2",
"title": "Wmm"
},
{
"id": "3",
"title": "Smm"
}
]
},
"links": [
{
"id": "1",
"title": "Red House",
"url": "http://infopedia.nl.sg/articles/SIP_611_2004-12-24.html"
},
{
"id": "2",
"title": "Joo Chiat",
"url": "http://www.the-inncrowd.com/joochiat.htm"
},
{
"id": "3",
"title": "Bake",
"url": "https://thelongnwindingroad.wordpress.com/tag/red-house-bakery"
}
]
}
]
}
}
EDIT:
Here is what you want:
var infoLength= JSON.infos.info.length;
for (infoIndex = 0; infoIndex < infoLength; infoIndex++) {
var notesLength= JSON.infos.info[infoIndex].note.notes.length;
for (noteIndex = 0; noteIndex < notesLength; noteIndex++) {
alert(JSON.infos.info[infoIndex].note.notes[noteIndex].title);
}
}
Putting your json into an var called obj, use the following:
obj.infos.info[0].note.notes[0].title
http://jsfiddle.net/Znq34/
Well the "path" to the JSON notes array-like object is:
json.infos.info[0].note.notes;
So you could do something like:
var notes = json.infos.info[0].note.notes;
var titles = [];
for (var i = 0, len = notes.length; i < len; i++)
{
titles.push(notes[i].title);
}
alert('titles is: ' + titles.join(', '));
Fiddle: http://jsfiddle.net/garreh/uDxqD/
Are you using jQuery? ;-)
// Assuming your using "success" in ajax response
success: function(json)
{
var titles = $(json.infos.info[0].note.notes).map(function() {
return this.title;
}).get();
alert(titles.join(', '));
}
First count the length of notes
var len = jsonobject.infos.info.note.notes.length;
Then loops through and get
var title = jsonobject.infos.info.note.notes[i].title;