Highcharts with multiple series from JSON - javascript

After reading and testing since few days (And already post here but with a wrong question) I really need you because I fail again and again...
My goal : having many series on same charts (and many charts in the future)
My data source : a mysql and a json output :
"[{"name":"Station 1","data":"1360191600,398.625"},{"name":"Station 1","data":"1360192500,398.625"},{"name":"Station 1","data":"1360193400,398.25"},{"name":"Station 1","data":"1360194300,397.375"},{"name":"Station 1","data":"1360195200,397.5"},{"name":"Station 1","data":"1360196100,397.5"},{"name":"Station 1","data":"1360199700,396.75"},{"name":"Station 1","data":"1360200600,397"}...
These data are an example because in normal time I have many station and some with only the timestamp data.
My big fail at this moment is to send these information to the series:[] option.
I have try some loops like this :
data=JSON.parse(data) ;
var series = [];
series.data = [];
$.each(data,function(i,ligne) {
var string = JSON.stringify(ligne);
var obj = $.parseJSON(string);
//var index_serie = obj.name.slice(0,1) ;
console.log(obj) ;
points=(obj.data) ;
series.name=obj.name ;
series.data.push(points) ;
}) ;
options.series.push(series) ;
console.log(options.series) ;
var chart = new Highcharts.Chart(options);
The options of the chart are defined before the ajax call.
I have try with a other format of json like ["name":"station1","data":"[1321654,10],[5465... but I have difficulties to add the [] in my sql quesry and the GROUP_CONCAT have some limitation (2014 character)
So help me to create a nice loop in order to render multiple series with their name etc
Thanks for your help...

Can't you change that "almost" JSON to "another" JSON? Maybe something like this:
[{
"name":'station 1',
"data": [ [360191600,398.625], [360191600,398.625], [360191600,398.625] ... [360191600,398.625] ]
}, {
"name":'station 2',
"data": [ [360191600,398.625], [360191600,398.625], [360191600,398.625] ... [360191600,398.625] ]
}]
If not, you have to add some parsing for your values, example:
data = JSON.parse(data);
var names = [];
$.each(data, function (i, ligne) {
var ind = names.indexOf(ligne.name),
splited = ligne.data.split(','),
x = parseFloat(splited[0]),
y = parseFloat(splited[1]);
if (ind == -1) {
/*series name spotted first time need to add new series */
ind = names.push(ligne.name) - 1;
options.series.push({
data: [],
name: ligne.name
});
}
if(!isNaN(x) && !isNaN(y)){
options.series[ind].data.push([x,y]);
}
});
And working jsfiddle: http://jsfiddle.net/3bQne/40/

Related

Converting CSV to nested JSON in Javascript some data in multiple rows

I have a CSV file which needs to be converted into a Javascript object / JSON file. Doesn't really matter which since I'll be be handling the data in JS anyway and either is fine.
Data in csv:-
Name,Time,HeightOptions/WidthRange,HeightOptions/Options
EGBL,Today,12,12.13.14.15.16
,,26,12.13.14.15.16
Desired Output:-
{
Name:"EGBL",
Time:"Today",
HeightOptions : [
{WidthRange:"12",
Options:[12,13,14,15,16]},
{WidthRange:"26",
Options:[12,13,14,15,16]
}]
}
This is what I have came up with:
const CSV = (csv) => {
var attrs = csv.splice(0, 1);
console.log("attrsattrs", attrs);
var result = csv.map(function (row) {
var obj = {};
var rowData = row.split(",");
attrs[0].split(",").forEach(function (val, idx) {
obj = constructObj(val, obj, rowData[idx]);
});
return obj;
});
function constructObj(str, parentObj, data) {
if (str.split("/").length === 1) {
parentObj[str] = data;
return parentObj;
}
var curKey = str.split("/")[0];
if (!parentObj[curKey]) parentObj[curKey] = {};
parentObj[curKey] = constructObj(
str.split("/").slice(1).join("/"),
parentObj[curKey],
data
);
return parentObj;
}
console.log("resultresultresult", result);
};
But it returns like this:-
{
Name:"EGBL",
Time:"Today",
HeightOptions : [
{WidthRange:"12",
Options:"12.13.14.15.16"},
]
},{
Name:"",
Time:"",
HeightOptions : [
{WidthRange:"26",
Options:"12.13.14.15.16"
}]
}
So as you see code is reading through as rows and not combining in 1 object.
As far as possible I wish to have this done in vanilla JS without any other libraries.
Thanks folks.
Its the general way how the converter works. What you can do is, after getting the result in some JSON format, write another function that will convert to your final JSON format. Otherwise write your own CSV parser by reading it as raw text. Also you can play around by changing the csv format to different way so that you can get expected result (if possible).

how to insert dynamic data from sql into chartjs stacked bar chart javascript

I'm trying to create a dynamic stacked bar chart with chartJS. I know how to create the a regular bar chart but have a problem when I try to create the a stacked bar chart.
For a stacked bar chart the data structure is different and I know how to constract it dynamically using javascript in the form
var inchartdatasets = [];
for (var i = 0; i < leninchart; i++) {
var inlabel = 'label: ' + "'" + inchartlebals[i] + "'";
var indata = 'data: ' + '[' + inchart[i] + ']';
var indataset = '{' + inlabel + ',' + indata + ',backgroundColor: color,}'
inchartdatasets.push(indataset)
}
The code above create the result in the following format (this is a copy from the alert) :
{label: 'AAA',data: [76.86],backgroundColor: color,},{label: 'Rating Unknown',data: [11.38],backgroundColor: color,},{label: 'BBB',data: [5.91],backgroundColor: color,},{label: '(1) others',data: [3.51],backgroundColor: color,}
To create the chart I use:
var data = {
datasets :[
{inchartdatasets}
],
};
var chart = new Chart ( ctx, {
type : "horizontalBar",
data : data,
options : options,
});
this does not render the data on the chart even though the data in the alert is correct.
when I copy the alert message and hard code in in the data in the following code:
var data = {
datasets :[
{label: 'AAA',data: [76.86],backgroundColor: color,},{label: 'Rating Unknown',data: [11.38],backgroundColor: color,},{label: 'BBB',data: [5.91],backgroundColor: color,},{label: '(1) others',data: [3.51],backgroundColor: color,}
],
};
the chart render correctly.
what am I missing here? why it does not render dynamically? any help is appreciated.
Thanks,
The issue is that what you are constructing is a String, but the data you need to pass to chart.js should be a JavaScript object. See, by taking e.g. the string '{' and concatenating it with other values, what you get is another string, which chart.js can't work with.
Instead, what you need to do is construct your data as an object, something like this:
var inchartdatasets = [];
for (var i = 0; i < leninchart; i++) {
var data = {
label: inchartlebals[i],
data: inchart[i],
backgroundColor: color
};
inchartdatasets.push(data);
}
This MDN page might also be a helpful resource to get a better understanding of working with JavaScript objects.

Format CSV to JSON with JavaScript

My task: given a set of data in CSV format, display a sankey chart using D3.
Given data format: (I'm unable to change this)
Uses,Types,Feedback
Use1,Type1,Feedback1
Use2,Type1,Feedback1
Use2,Type2,Feedback1
...
Required format for D3 Sankey plugin:
{ "nodes": [
{"name": "Use1"},
{"name": "Use2"},
{"name": "Type1"},
...
], "links": [
{"source":"Use1", "target":"Type1", "value":1},
...
}
My problem: Convert CSV data into JSON needed for the Sankey chart. I can not change the initial data given to me, so I must build the JSON dynamically.
My research led me here, but the only example of massaging the CSV data (that does not already included values, only sources and targets) was through MySQL. As I do not have access to a database on my project, I have resorted to using Underscore.js to help me in the conversion (within a Backbone.js application)
Here is what I have so far, which works as intended.
// buildJSON is a method of a Backbone View that oversees the creation of the diagram
buildJSON: function( csv ) {
var json = {
nodes: [], // unique nodes found in data
links: [] // links between nodes
};
// get unique nodes!
var uniqueNodes = _.chain(csv).map(_.values).flatten().unique().value().sort();
uniqueNodes.forEach(function( node ) {
json.nodes.push({ name: node });
});
// map colors to nodes
this.color.domain(uniqueNodes);
// map links
var links = [];
var rMap = {};
var keys = _.keys(csv[0]);
for ( var i = 0; i < csv.length; i++ ) {
for ( var j = 0; j < keys.length - 1; j++ ) {
var relationship = csv[i][keys[j]] + '-' + csv[i][keys[j + 1]];
rMap[relationship] = ++rMap[relationship] || 1;
}
}
// create links from the linkmap
for ( var r in rMap ) {
if ( rMap.hasOwnProperty(r) ) {
var rel = r.split('-');
links.push({
source: rel[0],
target: rel[1],
value: rMap[r]
});
}
}
var nodeMap = {};
json.nodes.forEach(function( node ) { nodeMap[node.name] = node; });
json.links = links.map(function( link ) {
return {
source: nodeMap[link.source],
target: nodeMap[link.target],
value: link.value
};
});
return json;
}
This wouldn't be such an issue with a small data set, but the data may contain thousands of rows and possibly up to ~10 columns.
So, long story short, my question comes in two parts:
Are there any obvious performance gains I can achieve, and
Is there a better (more efficient) way of massaging data for a Sankey Chart in D3?
I realize this is a particularly narrow issue, so I appreciate any and all help with this!

Adding another data series in plot

I currently have a PHP file which returns:
[[38,38],[38,113],[38,188],[38,263],[38,338],[38,413],[38,488],[113,38],[113,113],[113,188],[113,263],[113,338],[113,413],[113,488],[188,38],[188,113],[188,188],[188,263],[188,338],[188,413],[188,488],[263,38],[263,113],[263,188],[263,263],[263,338],[263,413],[263,488],[338,38],[338,113],[338,188],[338,263],[338,338],[338,413],[338,488],[413,38],[413,113],[413,188],[413,263],[413,338],[413,413],[413,488],[488,38],[488,113],[488,188],[488,263],[488,338],[488,413],[488,488],[75,75],[75,150],[75,225],[75,300],[75,375],[75,450],[150,75],[150,150],[150,225],[150,300],[150,375],[150,450],[225,75],[225,150],[225,225],[225,300],[225,375],[225,450],[300,75],[300,150],[300,225],[300,300],[300,375],[300,450],[375,75],[375,150],[375,225],[375,300],[375,375],[375,450],[450,75],[450,150],[450,225],[450,300],[450,375],[450,450]]
I use this in an AJAX call like
$.ajax({
url:'fetcher/allseedpositions.php',
async: false,
success:function(datasets){
seedPos = jQuery.parseJSON(datasets);
allNodePos = $.plot($("#allnodepositions"),[ seedPos ],optionsSeed);
}
})
to plot but now I want another series to be plotted also along with this, with different symbol.
I am confused on using JSON and I cannot add more properties.
You should be able to create a new array and push the next data set for display. http://jsfiddle.net/fZbVL/
var dataSet1 = [
[1,5],[4,7]
];
var dataSet2 = [
[1,2],[3,4]
];
var dataSet3 = [
[1,4],[4,6]
]
var data = []
data.push(dataSet1);
data.push(dataSet2);
data.push(dataSet3);
$.plot($("#placeholder"),
data);

GoogleAPI/JSON: Retrieving data from spreadsheet?

It turns out that I came up with my own solution:
var data = {"version":"1.0","encoding":"UTF-8","feed":{"xmlns":"http://www.w3.org/2005/Atom","xmlns$openSearch":"http://a9.com/-/spec/opensearchrss/1.0/","xmlns$gs":"http://schemas.google.com/spreadsheets/2006","xmlns$batch":"http://schemas.google.com/gdata/batch","id":{"$t":"https://spreadsheets.google.com/feeds/cells/0ArzGbN1Jn061dFdJZ29VcWttZExoRXQ5TnZVX29xUlE/od6/public/basic"},"updated":{"$t":"2012-10-11T21:56:33.189Z"},"category":[{"scheme":"http://schemas.google.com/spreadsheets/2006","term":"http://schemas.google.com/spreadsheets/2006#cell"}],"title":{"type":"text","$t":"Sheet1"},"link":[{"rel":"alternate","type":"text/html","href":"https://spreadsheets.google.com/pub?key\u003d0ArzGbN1Jn061dFdJZ29VcWttZExoRXQ5TnZVX29xUlE"},{"rel":"http://schemas.google.com/g/2005#feed","type":"application/atom+xml","href":"http://spreadsheets.google.com/feeds/cells/0ArzGbN1Jn061dFdJZ29VcWttZExoRXQ5TnZVX29xUlE/od6/public/basic"},{"rel":"http://schemas.google.com/g/2005#batch","type":"application/atom+xml","href":"http://spreadsheets.google.com/feeds/cells/0ArzGbN1Jn061dFdJZ29VcWttZExoRXQ5TnZVX29xUlE/od6/public/basic/batch"},{"rel":"self","type":"application/atom+xml","href":"http://spreadsheets.google.com/feeds/cells/0ArzGbN1Jn061dFdJZ29VcWttZExoRXQ5TnZVX29xUlE/od6/public/basic?alt\u003djson-in-script"}],"author":[{"name":{"$t":"dhuanco"},"email":{"$t":"dhuanco#gmail.com"}}],"openSearch$totalResults":{"$t":"9"},"openSearch$startIndex":{"$t":"1"},"entry":[{"id":{"$t":"https://spreadsheets.google.com/feeds/cells/0ArzGbN1Jn061dFdJZ29VcWttZExoRXQ5TnZVX29xUlE/od6/public/basic/R1C1"},"updated":{"$t":"2012-10-11T21:56:33.189Z"},"category":[{"scheme":"http://schemas.google.com/spreadsheets/2006","term":"http://schemas.google.com/spreadsheets/2006#cell"}],"title":{"type":"text","$t":"A1"},"content":{"type":"text","$t":"Maria"},"link":[{"rel":"self","type":"application/atom+xml","href":"http://spreadsheets.google.com/feeds/cells/0ArzGbN1Jn061dFdJZ29VcWttZExoRXQ5TnZVX29xUlE/od6/public/basic/R1C1"}]},{"id":{"$t":"https://spreadsheets.google.com/feeds/cells/0ArzGbN1Jn061dFdJZ29VcWttZExoRXQ5TnZVX29xUlE/od6/public/basic/R1C2"},"updated":{"$t":"2012-10-11T21:56:33.189Z"},"category":[{"scheme":"http://schemas.google.com/spreadsheets/2006","term":"http://schemas.google.com/spreadsheets/2006#cell"}],"title":{"type":"text","$t":"B1"},"content":{"type":"text","$t":"30"},"link":[{"rel":"self","type":"application/atom+xml","href":"http://spreadsheets.google.com/feeds/cells/0ArzGbN1Jn061dFdJZ29VcWttZExoRXQ5TnZVX29xUlE/od6/public/basic/R1C2"}]},{"id":{"$t":"https://spreadsheets.google.com/feeds/cells/0ArzGbN1Jn061dFdJZ29VcWttZExoRXQ5TnZVX29xUlE/od6/public/basic/R1C3"},"updated":{"$t":"2012-10-11T21:56:33.189Z"},"category":[{"scheme":"http://schemas.google.com/spreadsheets/2006","term":"http://schemas.google.com/spreadsheets/2006#cell"}],"title":{"type":"text","$t":"C1"},"content":{"type":"text","$t":"USA"},"link":[{"rel":"self","type":"application/atom+xml","href":"http://spreadsheets.google.com/feeds/cells/0ArzGbN1Jn061dFdJZ29VcWttZExoRXQ5TnZVX29xUlE/od6/public/basic/R1C3"}]},{"id":{"$t":"https://spreadsheets.google.com/feeds/cells/0ArzGbN1Jn061dFdJZ29VcWttZExoRXQ5TnZVX29xUlE/od6/public/basic/R2C1"},"updated":{"$t":"2012-10-11T21:56:33.189Z"},"category":[{"scheme":"http://schemas.google.com/spreadsheets/2006","term":"http://schemas.google.com/spreadsheets/2006#cell"}],"title":{"type":"text","$t":"A2"},"content":{"type":"text","$t":"John"},"link":[{"rel":"self","type":"application/atom+xml","href":"http://spreadsheets.google.com/feeds/cells/0ArzGbN1Jn061dFdJZ29VcWttZExoRXQ5TnZVX29xUlE/od6/public/basic/R2C1"}]},{"id":{"$t":"https://spreadsheets.google.com/feeds/cells/0ArzGbN1Jn061dFdJZ29VcWttZExoRXQ5TnZVX29xUlE/od6/public/basic/R2C2"},"updated":{"$t":"2012-10-11T21:56:33.189Z"},"category":[{"scheme":"http://schemas.google.com/spreadsheets/2006","term":"http://schemas.google.com/spreadsheets/2006#cell"}],"title":{"type":"text","$t":"B2"},"content":{"type":"text","$t":"32"},"link":[{"rel":"self","type":"application/atom+xml","href":"http://spreadsheets.google.com/feeds/cells/0ArzGbN1Jn061dFdJZ29VcWttZExoRXQ5TnZVX29xUlE/od6/public/basic/R2C2"}]},{"id":{"$t":"https://spreadsheets.google.com/feeds/cells/0ArzGbN1Jn061dFdJZ29VcWttZExoRXQ5TnZVX29xUlE/od6/public/basic/R2C3"},"updated":{"$t":"2012-10-11T21:56:33.189Z"},"category":[{"scheme":"http://schemas.google.com/spreadsheets/2006","term":"http://schemas.google.com/spreadsheets/2006#cell"}],"title":{"type":"text","$t":"C2"},"content":{"type":"text","$t":"ENG"},"link":[{"rel":"self","type":"application/atom+xml","href":"http://spreadsheets.google.com/feeds/cells/0ArzGbN1Jn061dFdJZ29VcWttZExoRXQ5TnZVX29xUlE/od6/public/basic/R2C3"}]},{"id":{"$t":"https://spreadsheets.google.com/feeds/cells/0ArzGbN1Jn061dFdJZ29VcWttZExoRXQ5TnZVX29xUlE/od6/public/basic/R3C1"},"updated":{"$t":"2012-10-11T21:56:33.189Z"},"category":[{"scheme":"http://schemas.google.com/spreadsheets/2006","term":"http://schemas.google.com/spreadsheets/2006#cell"}],"title":{"type":"text","$t":"A3"},"content":{"type":"text","$t":"Susan"},"link":[{"rel":"self","type":"application/atom+xml","href":"http://spreadsheets.google.com/feeds/cells/0ArzGbN1Jn061dFdJZ29VcWttZExoRXQ5TnZVX29xUlE/od6/public/basic/R3C1"}]},{"id":{"$t":"https://spreadsheets.google.com/feeds/cells/0ArzGbN1Jn061dFdJZ29VcWttZExoRXQ5TnZVX29xUlE/od6/public/basic/R3C2"},"updated":{"$t":"2012-10-11T21:56:33.189Z"},"category":[{"scheme":"http://schemas.google.com/spreadsheets/2006","term":"http://schemas.google.com/spreadsheets/2006#cell"}],"title":{"type":"text","$t":"B3"},"content":{"type":"text","$t":"25"},"link":[{"rel":"self","type":"application/atom+xml","href":"http://spreadsheets.google.com/feeds/cells/0ArzGbN1Jn061dFdJZ29VcWttZExoRXQ5TnZVX29xUlE/od6/public/basic/R3C2"}]},{"id":{"$t":"https://spreadsheets.google.com/feeds/cells/0ArzGbN1Jn061dFdJZ29VcWttZExoRXQ5TnZVX29xUlE/od6/public/basic/R3C3"},"updated":{"$t":"2012-10-11T21:56:33.189Z"},"category":[{"scheme":"http://schemas.google.com/spreadsheets/2006","term":"http://schemas.google.com/spreadsheets/2006#cell"}],"title":{"type":"text","$t":"C3"},"content":{"type":"text","$t":"GER"},"link":[{"rel":"self","type":"application/atom+xml","href":"http://spreadsheets.google.com/feeds/cells/0ArzGbN1Jn061dFdJZ29VcWttZExoRXQ5TnZVX29xUlE/od6/public/basic/R3C3"}]}]}};
function format_ss(data){ // format spreadsheet
var table = new Array();
for(var k in data.feed.entry){
var id = data.feed.entry[k].id.$t;
var row = id.match(/R([0-9]*)C/)[1]-1;
var col = id.match(/C([0-9]*)/)[1]-1;
if(Object.prototype.toString.call(table[row]) != '[object Array]')
table[row] = new Array();
table[row][col] = data.feed.entry[k].content.$t;
}
return table;
}
var ss = format_ss(data);
It worked like a charm.
Original Question:
This is a public spreadsheet I created using google docs:
https://docs.google.com/spreadsheet/pub?key=0ArzGbN1Jn061dFdJZ29VcWttZExoRXQ5TnZVX29xUlE&output=html
My problem is, how can I properly get this data with JSON?
I tried
http://spreadsheets.google.com/feeds/cells/0ArzGbN1Jn061dFdJZ29VcWttZExoRXQ5TnZVX29xUlE/od6/public/basic?alt=json-in-script&callback=test
This is awful to work with. The json data doesn't come properly formatted, for example I can't exactly tell what cell belongs to which column/field.
Does anyone know a better way to fetch this spreadsheet data?
If you look under the "Entry" section you'll see:
"id": {
"$t": "https://spreadsheets.google.com/feeds/cells/0ArzGbN1Jn061dFdJZ29VcWttZExoRXQ5TnZVX29xUlE/od6/public/basic/R1C1"
}
The ID is basically the URL of Row 1, Column 1. Then under that you'll find the:
"content": {
"type": "text",
"$t": "Maria"
}
The $t value there should give you your data. I have to agree it's a bit verbose but that's the nature of something that has so many properties.

Categories

Resources