I currently have a highchart that takes values from a csv file and displays them in a line chart, which works fine.
However, I'm looking to add drill down data for the points in my chart. The drill down values need to be taken from a file ( preferably the same csv file but can be another one as well). I'm unsure how to format my csv file and change my code to do this. Any help would be greatly appreciated.
Here is what I have so far https://jsfiddle.net/g8mdLLLp/
$.get('http://localhost/Pre/myfile.csv', function(data) {
// Split the lines
var lines = data.split('\n');
$.each(lines, function(lineNo, line) {
var items = line.split(',');
// header line containes categories
if (lineNo == 0) {
$.each(items, function(itemNo, item) {
if (itemNo > 0) options.xAxis.categories.push(item);
});
}
// the rest of the lines contain data with their name in the first position
else {
var series = {
data: []
};
$.each(items, function(itemNo, item) {
if (itemNo == 0) {
series.name = item;
} else {
series.data.push(parseFloat(item));
}
});
options.series.push(series);
}
});
var chart = new Highcharts.Chart(options);
});
My csv file looks like:
Results
ValueOne,11,22,16,10,11,33,03,19,13,02,15
ValueTwo,23,34,32,23,32,16,30,21,34,21,31
ValueThree,86,76,79,77,91,74,81,81,75,63,64
ValueFour,3,16,13,15,27,11,24,21,19,13,26
ValueFive 1,77,61,64,71,71,75,63,63,74,64,71
Thanks in advance
Related
I am using script.google.com to create a custom connector that can read CSV data from drive.google.com and send the data to Googles data studio.
When running the connector and inserting a simple table inside the data studio, I receive a simple that the request could not be processed because of an server error. The error id is changing every time I "re-publish" the script.
This is
function getData(request) {
var dataSchema = [];
request.fields.forEach(function(field) {
for (var i = 0; i < csvDataSchema.length; i++) {
if (csvDataSchema[i].name === field.name) {
dataSchema.push(csvDataSchema[i]);
break;
}
}
});
csvFile = UrlFetchApp.fetch("https://drive.google.com/uc?export=download&id=" + request.configParams.documentId);
var csvData = Utilities.parseCsv(csvFile);
var data = [];
csvData.forEach(function(row) {
data.push({
values: row
});
});
console.log( {
schema: dataSchema,
rows: data
} );
return {
schema: dataSchema,
rows: data
};
};
This is the csvDataSchema:
var csvDataSchema = [
{
name: 'date',
label: 'Date',
dataType: 'STRING',
semantics: {
conceptType: 'DIMENSION'
}
},
{
name: 'nanoseconds',
label: 'nanoseconds',
dataType: 'NUMBER',
semantics: {
"isReaggregatable": true,
conceptType: 'METRIC'
}
},{
name: 'size',
label: 'Size of Testfile in MByte',
dataType: 'STRING',
semantics: {
"isReaggregatable": false,
conceptType: 'DIMENSION'
}
}
];
And this is the result of the getData function, stringified:
{"schema":[{"name":"date","label":"Date","dataType":"STRING","semantics":{"conceptType":"DIMENSION"}},{"name":"size","label":"Size of Testfile in MByte","dataType":"STRING","semantics":{"isReaggregatable":false,"conceptType":"DIMENSION"}}],"rows":[{"values":["2017-05-23",123,"1"]},{"values":["2017-05-23",123,"1"]}]}
It perfectly fits to the reference. I am providing more information, but following the tutorial it should work, anyways.
Those are the fields provided in request:
And this is what getDate returns:
So, what I am wondering first is: Why is there a random error id? And what could be wrong with my script?
You should only return fields/columns included in request. Currently, data contains all fields that are in csvFile. Depending on your chart element in your dashboard, request will most likely contain only a subset of your full schema. See example implementation at the Data Studio Open Source repo.
If this does not solve the problem, you should setup error handing and check if the error is occurring at any specific line.
#Minhaz Kazi gave the missing hint:
As I did not "dynamically" filled the response object in getData, I always returned all three columns.
With my code above the only thing I had to do is adding the third column as a dimension or a metric.
So I changed my code to dynamically return the columns so it will fit to the response. For this I had to implement an function that will transform the CSV-data into an object.
This is the getData() function now:
function getData(request) {
var url = "https://drive.google.com/uc?export=download&id="
+ request.configParams.documentId;
var csvFile = UrlFetchApp.fetch(url);
var csvData = Utilities.parseCsv(csvFile);
var sourceData = csvToObject(csvData);
var data = [];
sourceData.forEach(function(row) {
var values = [];
dataSchema.forEach(function(field) {
switch(field.name) {
case 'date':
values.push(row.date);
break;
case 'nanoseconds':
values.push(row.nanoseconds);
break;
case 'size':
values.push(row.size);
break;
default:
values.push('');
}
});
data.push({
values: values
});
});
return {
schema: dataSchema,
rows: data
};
};}
And this is the function to convert the CSV data to an object:
function csvToObject(array) {
var headers = array[0];
var jsonData = [];
for ( var i = 1, length = array.length; i < length; i++ )
{
var row = array[i];
var data = {};
for ( var x = 0; x < row.length; x++ )
{
data[headers[x]] = row[x];
}
jsonData.push(data);
}
return jsonData;
}
(it's based on a so-solution from here, I modified it to fit my source CSV data)
I have an table in angular JS with filtering. I want to have only the selected data in the table in an array rows[] of arrays cell[]. This is why i cannot just export the table data.
I have tried the document.getSelection().toString() class and then .split but this failed as the elements in the table might consist of more than one word with blanks in between.
Is there a way to loop thru the object i get from document.getSelection() and distinguish between rows and cells?
With this i get the data as text, but i need an array:
var txt = '';
if (document.getSelection) {
txt = document.getSelection().toString();
} else if (document.selection) {
txt = document.selection.createRange().text;
}
Here i get the object:
if (document.getSelection) {
txt = document.getSelection();
} else if (document.selection) {
txt = document.selection.createRange();
}
console.log(txt)
Selection { anchorNode: , anchorOffset: 0, focusNode: , focusOffset: 3, isCollapsed: false, rangeCount: 1, caretBidiLevel: 0 }
Actually the answer was quite easy. I just had to use the document.getSelection().toString() function and use the split("/n") to get all the lines into an array, then i used split again to separate the elements by the tab that is added between column cells.
var tmp = [];
var rows = [];
var cells = [];
tmp = txt.split("\n");
for (var i=0; i<tmp.length; i++) {
cells.length = 0;
cells = tmp.split("\t");
rows.push(cells);
}
I have a JSON source that look like this... ( I checked it at jsonlint and it appears valid )
[{
"day": "06/19/2016",
"region": "Ohio",
"daily_er": "98.61"
}, {
"day": "06/19/2016",
"region": "Western NE",
"daily_ef": "98.63"
}, {.........
I'm trying to load the day as the y Axis with the region as X Axis
In my experimentation with loading from a local CSV, I DID manage to get the below to work....
(data.csv)
Categories,06/19/16,06/20/16,06/21/16,06/22/16,06/23/16,06/24/16,06/25/16
Ohio,98.61,97.75,97.19,97.21,97.97,93.66,98.3
Western NE,98.63,98.42,98.25,98.27,98.29,98.35,98.24
$.get('data.csv', function(data) {
// Split the lines
var lines = data.split('\n');
// Iterate over the lines and add categories or series
$.each(lines, function(lineNo, line) {
var items = line.split(',');
// header line containes categories
if (lineNo == 0) {
$.each(items, function(itemNo, item) {
if (itemNo > 0) options.xAxis.categories.push(item);
});
}
else {
var series = {
data: []
};
$.each(items, function(itemNo, item) {
if (itemNo == 0) {
series.name = item;
} else {
series.data.push(parseFloat(item));
}
});
options.series.push(series);
}
});
// Create the chart
var chart = new Highcharts.Chart(options);
});
I want to apologize up front because while in my mind I get how CSV gets parsed, I so rarely work with JSON that I am stumped as to how I parse the JSON above. In my brain I'm getting hung up on dupes for the day values and how that's handled. Has anyone had an experience with this they'd like to share, maybe get me pointed in the right direction?
Many thanks!
JW
im trying to stop empty csv files causing errors in my simple sampling program, just grab 2 values from each .csv file in folder,
i have null check, which now catches it, but im unsure how to re-structure my code so it skips file in array to next one, any assistance greatly welcomed,
foreach (string name in array1)
{
// sampling engine loop here, take first line only, first column DateTimeStamp and second is Voltage
Console.Write("\r Number of File currently being processed = {0,6}", i);
i++;
var reader = new StreamReader(File.OpenRead(name)); // Static for testing only, to be replaced by file filter code
var line = reader.ReadLine();
if (line == null)
{
Console.WriteLine("Null value detected");
Console.ReadKey();
break;
}
var values = line.Split(',');
reader.ReadLine();
if (values.Length == 89)
{
using (StreamWriter outfile = new StreamWriter(#"C:\\SampledFileResults.txt", true))
{
string content = "";
{
content = content + values[0] + ",";
content = content + values[9] + ",";
}
outfile.WriteLine(content);
Console.WriteLine(content);
}
}
}
Console.WriteLine("SAMPLING COMPLETED");
I would have said that it worked before. Now, I have updated meanwhile to latest Highcharts version. And, no idea why, it suddenly wants absolutely to display the first "column" of my CSV file. It looks like this:
,Switzerland,Europe,Global
1980,0.02854,0.01931,0.00547
1981,0.02898,0.01931,0.00549
Highcharts ("my code") wants to display this ""-column. And if I change it to "Years", or "Categories", it's all the same. I don't have three, but four entries in the legend.
The Highcharts-code looks like this:
// Split the lines
var lines = data.split('\n');
$.each(lines, function(lineNo, line)
{
var items = line.split(',');
// header line containes series name
if (lineNo === 0)
{
$.each(items, function(itemNo, item)
{
if (item!='')
{
if(item == 'Switzerland')
{
options.series.push(
{
name:item,
lineWidth: 5,
data:[]
});
}
else
{
options.series.push(
{
name:item,
data:[]
});
}
}
});
}
....
I tried to change the line
if (item!='')
to something like
if ((item!='') && (item!=' '))
or
if ((item!='') && (item!='Years'))
(when I added "Years" in the first place of the CSV file), but I only get than error messages...
Thanks for any hints!
I found similar example from the past and the problem is only with index, which is used during push points to series.
Parser:
var options = {
chart: {
renderTo: 'container',
zoomType:'xy'
},
xAxis:{
categories:[],
tickInterval:10,
tickmarkPlacement:'on'
},
title: {
text: 'Oviedo hoy'
},
series: []
};
$.get('data.csv', function(data) {
// Split the lines
var lines = data.split('\n');
$.each(lines, function(lineNo, line) {
var items = line.split(',');
// header line containes series name
if (lineNo === 0) {
$.each(items, function(itemNo, item) {
if(item!='')
{
options.series.push({
name:item,
data:[]
});
}
});
}
// the rest of the lines contain data with their name in the first position
else {
console.log(options.series);
$.each(items, function(itemNo, item) {
if(itemNo == 0)
options.xAxis.categories.push(item)
else
options.series[itemNo-1].data.push(parseFloat(item));
});
}
});
var chart = new Highcharts.Chart(options);
});
After some back and forth, here is how it works now:
$.get('data.csv', function(data)
{
// Split the lines
var lines = data.split('\n');
$.each(lines, function(lineNo, line)
{
var items = line.split(',');
// header line containes series name
if (lineNo === 0)
{
$.each(items, function(itemNo, item)
{
if (itemNo > 0)
{
if(item == 'Switzerland')
{
options.series.push(
{
name:item,
lineWidth: 5,
data:[]
});
}
else
{
options.series.push(
{
name:item,
data:[]
});
}
}
});
}
// the rest of the lines contain data with their name in the first position
else
{
$.each(items, function(itemNo, item)
{
if(itemNo == 0)
{
options.xAxis.categories.push(item);
}
else if (item == "null")
{
options.series[itemNo-1].data.push(null);
}
else
{
options.series[itemNo-1].data.push(parseFloat(item));
}
});
}
});
//console.log(options.series);
var chart = new Highcharts.Chart(options);
});
});