Since i am not familiar with C3.js library, i am bit confuse when i tried to split the Array data.
For instant i have some array value from a json.
var jsondata=[[123],[45],[56],[22]];
var jsondataName=[["apple"],["orange"],["banana"],["pear"]];
I tried to pass the first array jsondata into the chart but these values go into the same column which is not something i would like to see.
I want these array value become independent data and push the name into it
Please see the demo i made :
http://jsfiddle.net/q8h39/92/
And the result i want should looks like
Update the json data format :
"Name": apple,
"data": {
"value": 1434,
}
"Name": banana,
"data": {
"value": 342,
}
}
}
You can set the JSON object to data.json and then set data.keys.value to an array of values in that JSON:
var jsondata = [{
"Name": "apple",
"data": {
"value": 1434,
},
}, {
"Name": "banana",
"data": {
"value": 342,
}
}];
var chart = c3.generate({
data: {
json: jsondata,
keys: {
value: [
"name", "data.value"
]
},
type: "scatter"
//hide: true
}
});
http://jsfiddle.net/aendrew/mz9ccbrc/
n.b., You need C3 v0.4.11 for this (the dot syntax for keys.value was just added), and your JSON object needs to be an array (currently it's not valid).
If you want to convert the two arrays from your initial question to that format of JSON, try this:
d3.zip(jsondataName, jsondata)
.map((d) => Object({name: d[0][0], data: { value: d[1][0] } }));
Related
I want to use this data (below) as a data source for a d3.js program:
{
"component": {
"name1": {
"graphname": {
"title": "foo",
"data": [
{"data": "DATE IN ISOFORMAT", "value": 5},
{"data": "DATE IN ISOFORMAT", "value": 10}
]
}
},
"name2": {
"graphname": {
"title": "foo",
"data": [
{"data": "DATE IN ISOFORMAT", "value": 5},
{"data": "DATE IN ISOFORMAT", "value": 10}
]
}
}
}
"component2": {...
}
D3 accepts only array data? How i can manipulate it to work?
I want to graph for all component any "graphname" aggregated by "name"
Any tips?
D3 does not just accept arrays as data sources, but for looping purposes, arrays are much more convenient than JavaScript objects ("dicts"). There is a very easy way to convert objects to arrays, though. If your object above were called d, then its corresponding array can be created with:
var dlist = d3.entries(d);
Now dlist will be something like:
[ { key: 'component',
value: { name1: ..., name2: ... } },
{ key: 'component2',
value: { name1: ..., name2: ... } } ]
The original dict has been remapped into an array of "records," each with key and value pairs. This "array of records" pattern is very common in D3 work, and JavaScript in general. If you need to loop over the sub-structures (e.g. the name1, name2, ... values, d3.entries can be applied at multiple levels of the original structure, as those dict-to-list transforms are required.
Since this answer is called out in the comments as wrong, here's a working example of using an object ("dict") as a data source for a D3 program: first in a simple loop, then secondarily using the idiomatic d3 .data(...).enter() pipeline.
I decided it would be a fun project to see if i could take data from Google Analytics and display that in a custom dashboard, and hopefully learn a thing or two about using json, and javascript.
after a lot of debugging i now managed to pull the data from the Google Analytics server with their php api, and save the output into data.json on the server.
below the data.json, it's valid as per JSONLint.com:
{
"0": {
"date": "20160113",
"pageviews": "46",
"sessions": "21"
},
"1": {
"date": "20160114",
"pageviews": "66",
"sessions": "18"
},
"2": {
"date": "20160112",
"pageviews": "50",
"sessions": "14"
},
"3": {
"date": "20160116",
"pageviews": "19",
"sessions": "14"
},
"4": {
"date": "20160117",
"pageviews": "23",
"sessions": "14"
},
"5": {
"date": "20160115",
"pageviews": "38",
"sessions": "11"
},
"6": {
"date": "20160118",
"pageviews": "35",
"sessions": "9"
},
"7": {
"date": "20160119",
"pageviews": "15",
"sessions": "7"
}
}
Now i've tried to use the data from data.json and feed it into chartist's labels/series in order to draw a graph.
var labelArray = [];
var seriesArray = [];
var labelOutput = [];
$.getJSON("data.json", function(json) {
//var jsonObj = JSON.parse(json);
for (var i in json){
labelArray.push(json[i].date);
};
for (var i in json){
seriesArray.push(json[i].sessions);
};
// var myData = {
// labels:
// }
// labelOutput = labelArray.join(',')
// seriesOutput = serieArray.join(',')
console.log(labelArray);
console.log(seriesArray);
// this will show the info it in firebug console
});
new Chartist.Line('.ct-chart', {
labels: [labelArray],
series: [[seriesArray]]
});
However I'm currently out of ideas why this would not work, the labels on X and Y axis are correctly shown, but no graph shows up.
I've tried using .join to see if that makes a difference, but using labelOutput instead of labelArray also doesn't change anything.
In the console the array that is being fed into chartist seems all right to me, if I copy paste it from the console into the script everything works.
Current output for labelArray and seriesArray:
labelArray
Array [ "20160113", "20160114", "20160112", "20160116", "20160117", "20160115", "20160118", "20160119" ]
seriesArray
Array [ "21", "18", "14", "14", "14", "11", "9", "7" ]
Anyone knows why chartist.js does manage to add the correct labels along the axes but fails to read the same data and draw the chart?
Although the answer by #mnutsch works, there is an easier way to add dynamic content into the chart.
You can simply add the arrays directly as parameters, which I think is what the OP was trying to do.
response object would be the ajax data
var seriesVals = [];
var labelsVals = [];
for (var i = 0; i < response.length; i++) {
seriesVals.push(response[i].total);
labelsVals.push(response[i].response_code);
}
var pieData = {
series: seriesVals,
labels: labelsVals
};
In case anyone comes across this later, you can also do it like this:
//Create javascript arrays with the values and labels, replace this with code to read from the database/API/etc.
var array_1_values = [100, 120, 180, 200, 90]; //these are the values of the first line
var array_2_values = [20, 35, 65, 125, 245]; //these are the values of the second line
var array_labels = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri']; //these are the labels that will appear at the bottom of the chart
//create a prototype multi-dimensional array
var data_chart1 = {
labels: [],
series: [
[],
[]
]
};
//populate the multi-dimensional array
for (var i = 0; i < array_1_values.length; i += 1)
{
data_chart1.series[0].push(array_1_values[i])
data_chart1.series[1].push(array_2_values[i])
data_chart1.labels.push(array_labels[i])
}
//set the size of chart 1
var options_chart1 = {
width: '300px',
height: '200px'
};
//create chart 1
new Chartist.Line('#chart1', data_chart1, options_chart1);
In case anyone else stumbles upon the problem, below is what I came up with to get it to work.
After another day of trail and error i managed to pinpoint the problem.
The problem was:
In the original situation I tried to use a plain array as input for both labels and series. However, Chartist requires objects to render the labels/series as well as the graph.
The below works for me pulling the data from the data.json, adding it to an object and provide it to chartist.
var labelArray = {};
var seriesArray = {};
var labelOutput = [];
var Output
// $.getJSON("data.json", function(json) {
$.ajax({
url: 'data.json',
async: false,
dataType: 'text',
success: function(json) {
labelArray = JSON.parse(json);
data = {
labels:
[
labelArray[0].date,
labelArray[1].date,
labelArray[2].date,
labelArray[3].date,
labelArray[4].date,
labelArray[5].date,
labelArray[6].date
],
series: [[
labelArray[0].sessions,
labelArray[1].sessions,
labelArray[2].sessions,
labelArray[3].sessions,
labelArray[4].sessions,
labelArray[5].sessions,
labelArray[6].sessions
]]
}
}
});
new Chartist.Line('.ct-chart', data);
Decided to go with $.ajax to get the json file rather than getJSON as this allows me to disable asynchronous loading, ensuring the data is available when the graph is drawn.
Also, it is possible to set the dataType to Json rather than text, but this gives error in the JSON.parse line. Assuming that is because it tries to parse json as json, and fails to do so. But this is the only way i managed to get it to work, and add the json to an object.
Most likely the whole labelArray[0].date, labelArray[1].date is rather inefficient and should be improved but it works for now.
What is the best way to create an array that looks like the following:
[
{
"id":"1",
"value": true
},
{
"id":"3",
"value": false
},
{
"id":"5",
"value": true
},
{
"id":"6",
"value": false
},
{
"id":"9",
"value": true
},
]
My code:
//add to array
thing = {
"id" : 1,
"value" : "true"
};
thingArray.push(thing);
It does not seem to be properly formatted when I put the output in a JSON validator.
As I commented further up, make sure you're actually serializing it to JSON at some point. In your code example you're simply working with a JavaScript object, which isn't the same thing as JSON. Here's an example:
// start with a regular JavaScript array
var array = [];
// push some regular JavaScript objects to it
array.push({
id: 1,
value: true
});
array.push({
id: 2,
value: false
});
// serialize your JavaScript array into actual JSON
var json = JSON.stringify(array);
// do whatever you want with it...
console.log(json);
Here's a JSBin example.
Your code is fine. Here's some more code to get you started:
var arr = [];
arr.push({"id": 1, "value": "true"});
arr.push({"id": 2, "value": "false"});
console.dir(arr);
http://jsfiddle.net/gg014w0h/
You can run that fiddle and then check your console output. You'll see the contents of the array pretty clearly.
JSON validators will not like the trailing comma of the array. There is a difference between console.log(array) and console.log(JSON.stringify(array)). You may want to use the latter.
Also note that booleans are allowed in JSON:
"value": "true",
"value": true
Those are both valid and they mean different things.
I am using dojo's arrayUtil.forEach to loop through my JSON object but when I get to data.graphs.metrics it does not continue because metrics is not an array. What options do I have?
xhr("/esp/files/eclwatch/ganglia.json", {
handleAs: "json"
}).then(function(data){
arrayUtil.forEach(data.graphs, function (item, idx) {
//never gets here.
});
});
}
//json file
{
"graphs": [
{
"name": "Bar",
"metrics":{
"metric": ["metric1, metric3"],
"metric": ["metric1", "metric4", "metric5"]
},
"time": ["Hour", "Month", "Week"]
}
]
}
Making it an array instead of giving it duplicate keys would make the most sense.
"metrics": [
["metric1, metric3"],
["metric1", "metric4", "metric5"]
],
I have an JSON array like this
var filter_value_data = [{"Status":[{"name":"Open","id":"1"},{"name":"Pending","id":"2"},{"name":"Resolved","id":"3"},{"name":"Closed","id":"4"},{"name":"Evaluation","id":"5"}]},{"Payment Status":[{"name":"Paid","id":"10"},{"name":"UnPaid","id":"11"},{"name":"Part Paid","id":"12"}]},{"Priority":[{"name":"Low","id":"6"},{"name":"Medium","id":"7"},{"name":"High","id":"8"},{"name":"Urgent","id":"9"}]}]
I have tried filter_value_data["Status"] which is obviously wrong. How do I get the JSON elements for Status using the names like Status,Payment Status?
filter_value_data is an array (having []), so use filter_value_data[0].Status to get the first element-object with property "Status".
It is always good to format your code in order to see the hierarchy of the structures:
var filter_value_data = [
{
"Status": [
{
"name": "Open",
"id": "1"
}, {
"name": "Pending",
"id": "2"
}, ...
]
}, {
"Payment Status": [
{
"name": "Paid",
"id": "10"
}, ...
]
}, {
"Priority": [
{
"name": "Low",
"id": "6"
}, ...
]
}
];
With your current JSON you can't get the elements with the name alone.
You can get Status with filter_value_data[0]['Status'] and Payment status with filter_value_data[1]['Payment Status'].
This is because the keys are in seperate objects in the array.
In order to get them with filter_value_data['Status'] you need to change your JSON to
var filter_value_data = {
"Status":[
{"name":"Open","id":"1"},
{"name":"Pending","id":"2"},
{"name":"Resolved","id":"3"},
{"name":"Closed","id":"4"},
{"name":"Evaluation","id":"5"}
],
"Payment Status":[
{"name":"Paid","id":"10"},
{"name":"UnPaid","id":"11"},
{"name":"Part Paid","id":"12"}
],
"Priority":[
{"name":"Low","id":"6"},
{"name":"Medium","id":"7"},
{"name":"High","id":"8"},
{"name":"Urgent","id":"9"}
]
};
I wrote this on my phone so it's not as well-formatted as usual. I'll change it ASAP.
With your current JSON, created a result which might be helpful for you.
JS:
$.each(filter_value_data,function(ind,val){
var sta = val.Status; // Status Object get displayed
for(var i=0;i<sta.length;i++){
var idVal= sta[i].id;
var nameVal = sta[i].name;
Statusarray.push(idVal,nameVal);
console.log(Statusarray);
}
})
FiddleDemo
You can use below code, it will return status object
filter_value_data[0]['Status']
filter_value_data[0]['Payment Status']
to get Single value you use :
filter_value_data[0]['Status'][0]['name']