Google chart data from external source - charts

I am using C# webmethod to provide data to Google line chart. However I am stuck with the format of the data.
Currently I can only send data in list (object) format. But I want to send data in other format.
Is this possible? Please find my code snippet below:
ASP Page
//call to get data from ASP web method
$.ajax({
type: "POST",`enter code here`
contentType: 'application/json',
data: '{}',
url: 'AdminDashboard.aspx/GetChartData',
beforeSend: function () { alert("before send"); },
complete: function () { alert("complete"); },
success: function (data) {
var linedata1 = new google.visualization.arrayToDataTable(data.d);
linedata1.insertColumn(0, 'date', linedata1.getColumnLabel(0));
// copy values from column 1 (old column 0) to column 0, converted to Date
for (var i = 0; i < linedata1.getNumberOfRows() ; i++) {
var val = linedata1.getValue(i, 1);
if (val != '' && val != null) {
var dateArray = val.split('/');
var year = dateArray[2];
var month = dateArray[0] - 1; // convert to javascript's 0-indexed months
var day = dateArray[1];
linedata1.setValue(i, 0, new Date(year, month, day));
}
}
// remove column 1 (the old column 0)
linedata1.removeColumn(1);
dashboard.bind(programmaticSlider, programmaticChart);
dashboard.draw(linedata1);
}
ASP webmethod
[WebMethod]
public static List<object> GetChartData()
{
DataTable chartData = new DataTable();
DataTable tktData = new DataTable();
Array arrdata=null;
SPList configList, tktList;
SPQuery dataQuery;
SPListItemCollection configColl;
SPSecurity.RunWithElevatedPrivileges(delegate()
{
using (SPSite oSite = new SPSite("http://dsknomoe11:9696/"))
{
using (SPWeb oWeb = oSite.OpenWeb())
{
//Get Config list value for Ticket Priority and Ticket Status
configList = oWeb.Lists.TryGetList("SCMS_Configuration");
dataQuery = new SPQuery();
dataQuery.Query = "<Where><Or><Eq><FieldRef Name='Title' /><Value Type='Text'>Ticket Priority</Value></Eq><Eq><FieldRef Name='Title' /><Value Type='Text'>Ticket Status</Value></Eq></Or></Where>";
configColl = configList.GetItems(dataQuery);
//Ticket Priority and status
foreach(SPListItem oItem in configColl)
{
//Get Ticket Priority
if (oItem["Title"].ToString().Equals("Ticket Priority"))
{
tktPriority = oItem["value"].ToString().Split(';');
}
//Get Ticket Status
else if (oItem["Title"].ToString().Equals("Ticket Status"))
{
tktStatus = oItem["value"].ToString().Split(';');
}
}
//Add columns to DataTable ChartData
foreach (string s in tktStatus)
{
chartData.Columns.Add(s);
}
//Get Config list value for Ticket Priority and Ticket Status
tktList = oWeb.Lists.TryGetList("SCMS_Tickets");
dataQuery = new SPQuery();
dataQuery.Query = "<Where><Eq><FieldRef Name='isAct' /><Value Type='Choice'>Yes</Value></Eq></Where><OrderBy><FieldRef Name='Created' Ascending='True' /></OrderBy><GroupBy Collapse='True'><FieldRef Name='Created' /></GroupBy>";
dataQuery.ViewFields = "<FieldRef Name='Created' /><FieldRef Name='tckPrty' /><FieldRef Name='tckStat' />";
dataQuery.ViewFieldsOnly = true;
tktData = tktList.GetItems(dataQuery).GetDataTable();
var grpdata= tktData.AsEnumerable().Select(x => new { Date = Convert.ToDateTime(x[0]).Date.ToString("MM/dd/yyyy"), Status = x[2] }).ToArray();
arrdata = grpdata.GroupBy(l => l.Date).Select(g => new
{
Date = g.Key,
Open = g.Count(l => (string)l.Status == "Open"),
Closed = g.Count(l => (string)l.Status == "Closed"),
InProgress = g.Count(l => (string)l.Status == "In-Progress"),
Total = g.Count(l => ((string)l.Status == "Open") || ((string)l.Status == "Closed") || ((string)l.Status == "In-Progress"))
}).ToArray();
}
}
});
List<object> list = new List<object>();
list.Add(new object[] {"Date","Open","Closed","In-Progress","Total" });
string strDt, strOpen, strClosed, strInP, strTotal;
for (int i = 0; i < arrdata.Length; i++)
{
var spltData = arrdata.GetValue(i).ToString().Replace('{',' ').Replace('}',' ').Split(',');
strDt = spltData[0];
strOpen = spltData[1];
strClosed = spltData[2];
strInP = spltData[3];
strTotal = spltData[4].Trim();
list.Add(new object[] { Convert.ToDateTime(strDt.Split('=').Last()).Date.ToString("MM/dd/yyyy"),
Convert.ToInt32(strOpen.Split('=').Last()),
Convert.ToInt32(strClosed.Split('=').Last()),
Convert.ToInt32(strInP.Split('=').Last()),
Convert.ToInt32(strTotal.Split('=').Last())
});
}
return list;
}
Please help me with this.
1. My basic requirement is to create a datatable/or any other format with dynamic columns and then bind the data to google mutli-line chart.
For clarity, my current data format i.e list data is as
Date Open Closed InProgress
1/2/13 2 0 0
2/2/13 1 2 0
3/3/13 0 0 1
4/3/13 0 1 0

You can serve the data in many formats (JSON, CSV, TSV, HTML), I strongly recommend to you to use JSON, you can see the Google default structure here:

I got it working by using the JSON format.
i have posted the snippet, might help some one.
//for dynamic data binding
string jsonData = #"{ ""cols"" :[ { ""label"" : ""Type"" , ""type"" : ""string"" },{ ""label"" : ""Count"" , ""type"" : ""number"" }], ""rows"" :[{""c"":[{""v"":""Mushrooms""},{""v"":3}]}," +
#"{""c"":[{""v"":""Total""},{""v"":1}]}," +
#"{""c"":[{""v"":""Open""},{""v"":1}]}," +
#"{""c"":[{""v"":""Closed""},{""v"":1}]}," +
#"{""c"":[{""v"":""In-Progress""},{""v"":2}]}]}";
The catch was to use "double quotes" for every value. JSON recognizes "double quotes".
Thanks

Related

getting array from object from api and diplay iteratively

I am getting an array of object json encoded from an api and i would like to display an the each row of objects on a new line
var me3 = jsondata["message"];
for (var i = 1; i < me3.length; i++)
me3.forEach((element) => print(element));
Set<String> set = Set.from(me3);
set.forEach((element) => premiumList
..add(Property(propertyName:"Company : $element[1]", propertyLocation:"SSN : 3001245" )));
The aim is to display each record on a new property sheet and display the the tradename value in each row ..
Using StringBuffer we print
var responseFromAPI = ["test1", "test2", "test3", "test4"];
String _errorMessage = "";
StringBuffer sb = new StringBuffer();
for (String line in responseFromAPI) {
sb.write(line + "\n");
}
_errorMessage = sb.toString();
print(_errorMessage);

Deleting a row based on date - Date values

My query relates to this Google Form responses spreadsheet. I'm trying to adapt the script I got from here.
function cleanup() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Form responses 1');
var values = sheet.getDataRange().getValues();
var InAYear = (Date.now()/86400000 + 25569) + 365;
for (var i = values.length - 1; i >= 0; i--) {
if ( values[i][5] >= InAYear) {
sheet.deleteRow(i+1);
}
}
}
I'm trying to get this to compare the date in the Start Date column of the sheet with the date in a year from now and delete the row if the column entry is greater than this (ie. if the date on the sheet is more than a year in advance). However, I obviously don't understand how to get the two different dates in the same format because examining variable values when debugging shows wildly different values.
Try the following script code:
function cleanup() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('Form responses 1');
var values = sheet.getDataRange().getValues();
var today = Utilities.formatDate(new Date(), ss.getSpreadsheetTimeZone(), 'MM/dd/yyyy')
for (var i = values.length - 1; i >= 0; i--) {
if ( values[i][4] != '' && dateDiffInDays(values[i][4],today) > 365 ) {
sheet.deleteRow(i+1);
}
}
};
function dateDiffInDays(d1,d2) {
var date1 = new Date(d1);
var date2 = new Date(d2);
var timeDiff = date1.getTime() - date2.getTime();
return Math.ceil(timeDiff / (1000 * 3600 * 24));
};
It looks like I have it working, and sending me an email.
function cleanup(e) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('Form responses 1');
var values = sheet.getDataRange().getValues();
var today = new Date();
var InAYear = new Date();
InAYear.setFullYear( today.getFullYear()+1 );
var emailaddress = "****";
var subject = "Annual Leave Request";
var message = "Annual Leave has been requested as follows:" + "\n\n";
for (var i = values.length - 1; i >= 0; i--) {
if ( values[i][4] > InAYear ) {
sheet.deleteRow(i+1);
subject = "Annual Leave Request - Rejected";
message = "The following annual leave request was rejected due to being more than one year in advance:" + "\n\n";
}
}
for(var field in e.namedValues) {
message += field + ':'
+ "\n" + e.namedValues[field].toString() + "\n\n";
}
MailApp.sendEmail(emailaddress, subject, message);
}
Thank you to Kishan, without who's help I would not have been able to get to this stage.

When using NumericField, get absolutely nothing back every time

Been playing with Lucene.NET the last two days.
After reading up on Dates, I was led to believe that Dates are best converted to Milliseconds, and stored in NumericField, with Indexing=true, and Store=No.
But now nothing ever returns - it must be something basic, but I'm just not seeing it.
The saving code is as follows:
...
else if (type == typeof (DateTime?))
{
var typedValue = (DateTime?) value;
field = numericField = new NumericField(documentFieldName, 4, Field.Store.YES, true);
long milliseconds = typedValue.HasValue?(typedValue.Value.Date.Ticks/TimeSpan.TicksPerMillisecond):0;
numericField.SetLongValue(milliseconds);
doc.Add(numericField);
}
...
else
{
field = stringField = new Field(
documentFieldName,
(value != null)?value.ToString():string.Empty,
Store.YES,
Field.Index.ANALYZED) ;
doc.Add(stringField);
}
// Write the Document to the catalog
indexWriter.AddDocument(doc);
When I query for docs against the values saved in Field ... no problem.
When I query for documents by matching against the values in NumericFields, nothing returns.
Where did I go wrong?
Thanks for your help.
Lucene.Net.Analysis.Analyzer analyzer = new Lucene.Net.Analysis.Standard.StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_30);
var q2 = NumericRangeQuery.NewLongRange("Val", 3, 3, true, true);
var uxy2 = documentSearchManagementService.Search("Students", termQuery, "Id");
Using:
public ScoredDocumentResult[] Search(string indexName, Query query, params string[] hitFieldNamesToReturn)
{
if (_configuration.IndexRootDirectory.IsNullOrEmpty())
{
throw new Exception("Configuration.IndexRootDirectory has not been configued yet.");
}
indexName.ValidateIsNotNullOrEmpty("indexName");
hitFieldNamesToReturn.ValidateIsNotDefault("hitFieldNamesToReturn");
//Specify the index file location where the indexes are to be stored
string indexFileLocation = Path.Combine(_configuration.IndexRootDirectory, indexName);
Lucene.Net.Store.Directory luceneDirectory = Lucene.Net.Store.FSDirectory.Open(indexFileLocation);
IndexSearcher indexSearcher = new IndexSearcher(luceneDirectory);
TopScoreDocCollector topScoreDocCollector = TopScoreDocCollector.Create(10, true);
indexSearcher.Search(query, topScoreDocCollector);
List<ScoredDocumentResult> results = new List<ScoredDocumentResult>();
foreach (var scoreDoc in topScoreDocCollector.TopDocs(0, 10).ScoreDocs)
{
ScoredDocumentResult resultItem = new ScoredDocumentResult();
Lucene.Net.Documents.Document doc = indexSearcher.Doc(scoreDoc.Doc);
resultItem.Score = scoreDoc.Score;
List<ScoredDocumentFieldResult> fields = new List<ScoredDocumentFieldResult>();
foreach (string fieldName in hitFieldNamesToReturn)
{
string fieldValue = doc.Get(fieldName);
fields.Add(new ScoredDocumentFieldResult{Key= fieldName,Value=fieldValue});
}
resultItem.FieldValues = fields.ToArray();
results.Add(resultItem);
}
indexSearcher.Close();
return results.ToArray();
}

Calling a function from onEdit() trigger doesn't work

I want to run a function that updates some values when I edit one cell of a column. This line of the trigger works well: dataCell0.setValue(today_date(new Date())[2]);. But this other line updatePercent(); doesn't. But if I call this updatePercent() function from a time based trigger (in Resources), it works well. What is going wrong with this updatePercent() call?
function onEdit(){
var s = SpreadsheetApp.getActiveSheet();
if( ( s.getName() == "mySheet1" ) || (s.getName() == "mySheet2") ) { //checks that we're on the correct sheet
var r = s.getActiveCell();
if( s.getRange(1, r.getColumn()).getValue() == "PORCENT_TIME") { // If you type a porcent, it adds its date.
var dataCell0 = r.offset(0, 1);
dataCell0.setValue(today_date(new Date())[2]);
updatePercent();
}
}
}
Here the updatePercent function code:
/**
* A function to update percent values accoding to input date.
**/
function updatePercent() {
var sheet = SpreadsheetApp.getActiveSheet();
var column = getColumnNrByName(sheet, "PORCENT_TIME");
var input = sheet.getRange(2, column+1, sheet.getLastRow(), 4).getValues();
var output = [];
for (var i = 0; i < input.length; i++) {
var fulfilledPercent = input[i][0];
Logger.log("fulfilledPercent = " + fulfilledPercent);
var finalDate = input[i][3];
Logger.log("finalDate = " + input[i][3]);
if ( (typeof fulfilledPercent == "number") && (finalDate instanceof Date) ) {
var inputDate = input[i][1]; // Date when input was added.
var restPorcentPen = 100 - fulfilledPercent;
var restantDays = dataDiff(inputDate, finalDate);
var percentDay = restPorcentPen/restantDays;
Logger.log("percentDay = " + percentDay);
var passedTime = dataDiff(inputDate, new Date());
Logger.log("passedTime = " + passedTime);
var passedPorcent = passedTime * percentDay; // How much percent this passed time is?
Logger.log("passedPorcent = " + passedPorcent);
var newPorcent = (fulfilledPercent + passedPorcent);
newPorcent = Math.round(newPorcent * 100) / 100;
Logger.log("newPorcent = " + newPorcent);
var newInputDate = hoje_data(new Date())[2]; // Now update the new input date
// newPorcent = newPorcent.toFixed(2);
output.push([newPorcent, newInputDate]);
sheet.getRange(2, column+1, output.length, 2).setValues(output);
Logger.log(" ");
var column25Dec = getColumnNrByName(sheet, "PORCENT_25DEZ");
var passedTimeSince25Dec = dataDiff(new Date(2013,11,25), new Date()); // Months: January is 0;
var decPercent = (newPorcent - (passedTimeSince25Dec * percentDay)); // .toFixed(2).replace(".", ",");
decPercent = Math.round(decPercent * 100) / 100;
// if (sheet.getRange(output.length+1, column25Dec+1).getValues() == ''){
sheet.getRange(output.length+1, column25Dec+1).setValue(decPercent );
// }
var remainingYears = dataDiffYears(new Date(), finalDate);
sheet.getRange(output.length+1, column).setValue(remainingYears);
}
else {
newPorcent = "Put a final date"
output.push([newPorcent, inputDate]);
sheet.getRange(2, column+1, output.length, 2).setValues(output);
}
if (finalDate instanceof Date){
var remainingYears = dataDiffYears(new Date(), finalDate);
// Logger.log("remainingYears = " + remainingYears);
}
else {
remainingYears = "insert a valid date";
}
sheet.getRange(output.length+1, column).setValue(remainingYears);
}
}
I will guess you're using the new gSheets. Check if it will work in the old-style sheets. The new sheets' onEdit trigger has problems, particularly with getActive.
My problem was in the updatePercent() funciton. Thank you, guys!

import private google fusion table to google docs spreadsheet

I want to build a chart to google fusion table. I know there is an option to do it with fusion table but I need to do that using google spreadsheet.
How do I import a private fusion table to a spreadsheet?
function getdata(authToken) {
query = encodeURIComponent("SELECT * FROM tableid");
var URL = "http://www.google.com/fusiontables/api/query?sql=" + query;
var response = UrlFetchApp.fetch(URL, {
method: "get",
headers: {
"Authorization": "GoogleLogin auth=" + authToken,
}
});
return response.getContentText();
}
The code above gives me the table headers only.
Don't set each cell individually as in the example below unless you need to process each bit of data. Using this is about 10x faster:
var rows = o.length;
var columns = o[0].length;
cell.offset(<startrow>, <startcolumn>, rows, columns).setValues(o);
After a deep research, finally i figured it out after a deep search and reading here.
This is how it looks for the code google docs spreadsheet app script:
function onOpen()
{
var tableID = '00000' // Add the table ID of the fusion table here
var email = UserProperties.getProperty('email');
var password = UserProperties.getProperty('password');
if (email === null || password === null) {
email = Browser.inputBox('Enter email');
password = Browser.inputBox('Enter password');
UserProperties.setProperty('email',email);
UserProperties.setProperty('password', password);
} else {
email = UserProperties.getProperty('email');
password = UserProperties.getProperty('password');
}
var authToken = getGAauthenticationToken(email,password);
query = encodeURIComponent("SELECT * FROM tableID");
var URL = "http://www.google.com/fusiontables/api/query?sql=" + query;
var response = UrlFetchApp.fetch(URL, {
method: "get",
headers: {
"Authorization": "GoogleLogin auth=" + authToken,
}
});
var tableData = response.getContentText();
var o = Utilities.parseCsv(response.getContentText());
var doc = SpreadsheetApp.getActiveSpreadsheet();
var cell = doc.getRange('a1');
var index = 0;
for (var i in o) {
var row = o[i];
var col = 0;
for (var j in row) {
cell.offset(index, col).setValue(row[j]);
col++;
}
index++;
}
}
function getGAauthenticationToken(email, password) {
password = encodeURIComponent(password);
var response = UrlFetchApp.fetch("https://www.google.com/accounts/ClientLogin", {
method: "post",
payload: "accountType=GOOGLE&Email=" + email + "&Passwd=" + password + "&service=fusiontables&Source=testing"
});
var responseStr = response.getContentText();
responseStr = responseStr.slice(responseStr.search("Auth=") + 5, responseStr.length);
responseStr = responseStr.replace(/\n/g, "");
return responseStr;
}
After that you can do whatever you want in the spreadsheet.
BTW, I still think there is a simple way to import a private table into a spreadsheet automaticly.