I'm attempting to create a stacked bar chart with Dimple.JS and D3. However, the JSON file I wish to use with this particular visualization involves nested JSON objects (below). The stacked bar chart I wish to create has the channel category as its x-axis, with the y axis to be the aggregate count of the different locations (with each location as a 'stack'). Here is the original data:
[{
"channel": "politics",
"locations":
[{
"name":"usa",
"count" : 1454
},
{
"name":"mexico",
"count":3543
},
{
"name":"antarctica",
"count":4352
}]
},
{
"channel": "economics",
"locations":
[{
"name":"usa",
"count" : 12431
},
{
"name":"mexico",
"count":314
},
{
"name":"china",
"count":2321
}]
}]
I've flattened the above into the JSON below, but I am having trouble using Dimple's .addSeries() method to create the stack.
[
{
"channel": "politics",
"locations[0].name": "usa",
"locations[0].count": 1454,
"locations[1].name": "mexico",
"locations[1].count": 3543,
"locations[2].name": "antarctica",
"locations[2].count": 4352
},
{
"channel": "economics",
"locations[0].name": "usa",
"locations[0].count": 12431,
"locations[1].name": "mexico",
"locations[1].count": 314,
"locations[2].name": "china",
"locations[2].count": 2321
}
]
My question is this: how can Dimple support either this data encoded in this particular JSON file? Most samples use CSV and TSV files, but I unfortunately have the limit of using only JSON files.
Dimple can't use nested data. You'll have to flatten it on the client side so there's a single JSON object for each intersection of channel/location. Here's an example of how to do that with Underscore.js :
var chartData = _.chain(data)
.map(function(row, index){
// for each original row, return a new row for each location
return _.map(row.locations, function(location){
return {
'channel' : row.channel,
'name' : location.name,
'count' : location.count
};
});
})
.flatten()
.value();
(For every row in the original data set, it will return three rows, one for each location. This will return an array of nested arrays, so it calls flatten to make the whole array 1 level deep.)
Here's a jsBin showing that in action : http://jsbin.com/nuvihu/edit?html,js,output
(output):
If this helps, here is what the data ended up looking like :
[{"channel":"politics","name":"usa","count":1454},{"channel":"politics","name":"mexico","count":3543},{"channel":"politics","name":"antarctica","count":4352},{"channel":"economics","name":"usa","count":12431},{"channel":"economics","name":"mexico","count":314},{"channel":"economics","name":"china","count":2321}]
Related
I Have a JSON Data which I fetched from the database using Mysql.
The JSON is given Below :
[
{
"Country":"Australia",
"persons":"5"
},
{
"Country":"Spain",
"persons":"2"
},
{
"Country":"India",
"persons":"8"
},
{
"Country":"Mexico",
"persons":"4"
},
{
"Country":"United States",
"persons":"4"
}
]
What I Want is that, How Can I Color the Specific region in the Jvector Map also showing the no. of Counts that I am having.
I have a data structure like this:
var fieldTmp= [{
"CountryDetails":[{
"countryName":"Kerala",
"JobDetails":[{
"RequisitionId":"00020447961",
"City":"KOCHI",
"PostedDate":"2016-12-18"
},{
"RequisitionId":"26103",
"City":"TRIVANDRUM",
"PostedDate":"2016-12-12"
},{
"RequisitionId":"26077",
"City":"ALAPPEY",
"PostedDate":"2016-10-09"
},{
"RequisitionId":"00020774701",
"City":"KOTTAYAM",
"PostedDate":"2016-06-12"
},{
"RequisitionId":"26078",
"City":"ADOOR",
"PostedDate":"2016-05-19"}]
},
"countryName":"MADRAS",
"JobDetails":[{
"RequisitionId":"0025456",
"City":"CHENNAI",
"PostedDate":"2017-06-05"
},{
"RequisitionId":"69847562",
"City":"ADYAR",
"PostedDate":"2016-10-14"}]
},
{"countryName":"Tamil Nadu",
"JobDetails":[{
"RequisitionId":"00020550501",
"City":"CHENNAI",
"PostedDate":"2016-12-18"
},{
"RequisitionId":"00020786022",
"City":"KOVAI",
"PostedDate":"2016-09-01"
},{
"RequisitionId":"00020786071",
"City":"TRICHY",
"PostedDate":"2016-04-10"}]
}] }]
My requirement is, I need to add Job Details under MADRAS to Tamil Nadu and I need to sort the data based on one property -PostedDate.
So my result should be something like,
var fieldTmp= [{
"CountryDetails":[{
"countryName":"Kerala",
"JobDetails":[{
"RequisitionId":"00020447961",
"City":"KOCHI",
"PostedDate":"2016-12-18"
},{
"RequisitionId":"26103",
"City":"TRIVANDRUM",
"PostedDate":"2016-12-12"
},{
"RequisitionId":"26077",
"City":"ALAPPEY",
"PostedDate":"2016-10-09"
},{
"RequisitionId":"00020774701",
"City":"KOTTAYAM",
"PostedDate":"2016-06-12"
},{
"RequisitionId":"26078",
"City":"ADOOR",
"PostedDate":"2016-05-19"}]
},
{"countryName":"Tamil Nadu",
"JobDetails":[{
"RequisitionId":"0025456",
"City":"CHENNAI",
"PostedDate":"2017-06-05"
},{
"RequisitionId":"00020550501",
"City":"CHENNAI",
"PostedDate":"2016-12-18"
},{
"RequisitionId":"69847562",
"City":"ADYAR",
"PostedDate":"2016-10-14"
},{
"RequisitionId":"00020786022",
"City":"KOVAI",
"PostedDate":"2016-09-01"
},{
"RequisitionId":"00020786071",
"City":"TRICHY",
"PostedDate":"2016-04-10"}]
}] }]
I tried to extract Madras data and add that to under Tamil Nadu. But nothing is working.
I know how to extract single or multiple value from JSON object. But I need to edit that JSON and sort it. That I am able to do it.
I got the solution.
When the countryName is "Tamil Nadu" and "MADRAS",I extracted all the data and saved it in a new array using below code.
function mergingBothStateDetails(jsonJobDetails){
for(var j=0;j<jsonJobDetails.length;j++)
{
newTmpRecord.push({"RequisitionId":jsonJobDetails[j].RequisitionId,
"PostedDate":jsonJobDetails[j].PostedDate,
"City":jsonJobDetails[j].City});
}
}
Here newTmpRecord is an Array and is like universal variable
For sorting I used below codes
function sortNewList(){
newTmpRecord.sort(function(a, b){ // sort object by retirement date
var dateA=new Date(a.PostedDate), dateB=new Date(b.PostedDate)
return dateB-dateA //sort by date descending
});
}
You can simply extract the object "Madras" from the array and add all of its Jobdetails to the object "Tamil Nadu" in a for loop. You can either look where to add them in the loop by checking the dates, or you can write a sort function, which is pretty easy in javascript and well explained here:
You might want to look up objects
And here the sorting is explained.
I'm having a radial graph showing two levels of nodes. On clicking a node it is possible to add a sub graph with calling the sum() function. Everything works fine except setting individual color for the newly added edges.
Does anybody have ever tried to load sub graphs with individual edge colors or have a hint what I'm doing wrong?
Here I'm getting and adding the sub graph:
subtree = getSubtree(node.id);
//perform animation.
subtree.success(function(data){
rg.op.sum(data, {
type: 'fade:seq',
fps: 40,
duration: 1000,
hideLabels: false,
});
});
I've checked also the loaded data but for me it seems to be totally equal. I've also loaded the same data into the initial graph instead of the sub graph and then it was colored correct. Nevertheless here is some test data which is the result of the function getSubtree (the id "placeholder" matches the id of the existing where the sub graph should be added):
{
"id": "placeholder1",
"name": "country",
"children": [{
"id": "2_3mSV~_scat_1",
"name": "hyponym",
"children": [{
"children": [],
"adjacencies": {
"nodeTo": "2_3mSV~_scat_1",
"data": {
"$color": "#29A22D"
}
},
"data": {
"$color": "#29A22D"
},
"id": "3_58z3q_sc_174_6",
"name": "location"
}],
"data": {
"$type": "star",
"$color": "#666666"
},
"adjacencies": [{
"nodeTo": "3_58z3q_sc_174_6",
"data": {
"$color": "#29A22D"
}
}]
}]
}
I finally found the problem in the framework itself...
When calling the construct function inside the call of sum() which is actually adding the subtree then the data object containing information about the adjacence's individual visualization is not used for adding the new adjacence. Therefore I changed the code manually (this for loop is the new version of the existing for loop inside the construct() function):
for(var i=0, ch = json.children; i<ch.length; i++) {
//CUSTOM CODE: GET DATA OF THIS ADJACENCE
data = null;
if(ch[i].adjacencies[0]==undefined){
data = ch[i].adjacencies.data;
}
else{
data = ch[i].adjacencies.data;
}
ans.addAdjacence(json, ch[i], data);
arguments.callee(ans, ch[i]);
//CUSTOM CODE END
}
I have a JSON object that I want to be able to visualize as a hierarchy of circles like this (you can zoom in and out of the hierarchy using mouse clicks).
I'm just trying to figure out how to use the d3.layout.pack to generate the hierarchy for the JSON object below and access the data that sits under Franchise. Any pointers would be much appreciated. Thanks.
{
"Consultant":
[
{
"ConsultantID": 1,
"ConsultantName": "Test Consultant",
"Account":
[
{
"AccountID": 1,
"AccountName": "Test Account",
"Site":
[
{
"SiteID": 1,
"SiteName": "Test Site",
"Franchise":
[
{
"FranchiseID": 1,
"FranchiseName": "Test Franchise",
"Data":
{
// Data goes here
}
}
]
}
]
}
]
}
]
}
For the layout, you can use the built in circle packing layout as you suggest.
For formating the data to use it in this layout, you can use the d3.nest() function. If you want some more insight on how nest works, then I suggest you to have a look at the following question: D3 JSON data conversion
I was fighting with HighCharts quite some hours for formatting the data input to the series option.
Finally I saw the link here solved my problem for data formatting and input.
The data format that would be recognized by HighCharts pie chart is like this (format 1) as indicated by the link above:
[["chrome",15],["firefox",20]]
I actually want dynamic data input from external URL and format the data so that HighCharts can recognized it. The data format I got from the URL is like this (format 2):
[
{
"status": "Stopped \/ Idle",
"val": 17.469444444444,
}, {
"status": "Working",
"val": 0,
}, {
"status": "Headland Turning",
"val": 0,
}, {
"status": "Transport",
"val": 0.15333333333333,
}
]
which is already in JSON format.
I just want to know that is that necessary for me to write a parser for the data from format 2 to format 1? Or Am I missing something that HighCharts can recognize the JSON format data and I don't actually need to write a parser?
I am new to HighCharts so feel free to point that out if some of my problem description does not make sense..Thank you!
EDIT: Thanks for all guys answering my question!
When a script expects data in specific format, you often have to map your data to fit format. This can be modified in server code or using javascript
Can use jQuery $.map to reconfigure an object or array to another array.
DEMO: http://jsfiddle.net/qpsSe/1
Note that trailing commas in sample JSON need removing to validate JSON
/* "json" is your response object, modify variable names to match */
var chartData=$.map( json, function( obj,i){
return [[ obj.status, obj.val]];
})
$.map API Docs
Alternate method in native javascript
var chartData=[];
for( i=0; i<json.length; i++){
chartData.push( [ json[i]['status'], json[i]['val'] ])
}
AFAIK that's just how Highcharts wants its data. That being said, the parser is pretty easy:
var data; // this is your received data
var highchartsData = []; // this is data for highcharts
$.each(data, function(i, e) {
highchartsData.push([e.status, e.val]);
});
One thing to note is that if the data you're receiving is in text (say, a response from an AJAX call) then you need to convert it to a javascript object like so:
var data = $.parseJSON(textData);
You need to make a parser when assigning options as stated in HighCharts preprocessing
Basically, you parse the data and include it in the options:
var serie1 = json.map( function(e) {
return [e.status, e.val];
});
options.series.push({data: serie1});
Here is a working example using $.map and options in Fiddle
Since Highcharts 3.0, categories can also be extracted by giving each point a name and setting axis type to "category".
For a column bar chart this would be:
xAxis: {
type: 'category',
},
series: [{
data: [{
name: 'Point 1',
color: '#00FF00',
y: 1
}, {
name: 'Point 2',
color: '#FF00FF',
y: 5
}]
}]
You can bind chart with JSON data, directly.
You just need to set the json property names as highchart standard.
'Y' for value and 'name' for label.
Your JSON should be as like follow:
[
{
name: "Stopped \/ Idle",
y: 17.469444444444
}, {
name: "Working",
y: 0
}, {
name: "Headland Turning",
y: 0
}, {
name: "Transport",
y: 0.15333333333333
}
]