using google's data.join to interatively add data to a graph - javascript

I'm trying to build a set of data for a Google scatter graph using data.join as follows:
var tempData = newData();
var tempData2 = totalData;
dataArray[dataCount] = tempData;
var joinMark = countArray(dataCount);
totalData = google.visualization.data.join(tempData2,tempData,'full',[[0,0]],[joinMark],[1]);
dataCount = dataCount+1;
Where newData() generates a dataTable from a database, column 0 is always a date and column 1 is always a number. I have been able to get this to work once, to display 2 variables on the graph, but trying to add any more causes my code to fail.
BTW totalData is the variable passed to chart.draw()
The countArray function returns 1 if both arrays have 2 columns (works fine), but for further additions I am returning a comma separated string 1,2... 1,2,3.. etc. This is based on my assumption that that last two variables in data.join are the column numbers from dataTable 1 and 2 respectively to be combined. Am I right in this assumption, or do I need a different variable in that location?
Thanks
Tom

You are correct about the function of the last two parameters in the join call, but you do not want to pass a comma-separated string where joinMark is: that should be an array of column indices, not an array containing a string. You cannot add a comma-separated string to an array to get an array on integers:
var joinMark = '1,2,3';
[joinMark] == [1,2,3]; // false
Change your countArray function to return an array of integers instead, and then pass that array directly to the join function (that is, you shouldn't wrap it in brackets to create an array of arrays):
var joinMark = countArray(dataCount);
totalData = google.visualization.data.join(tempData2,tempData,'full',[[0,0]],joinMark,[1]);

Related

Copy a specific column from a csv file to an array using javascript

I have a little problem that is how to Copy a specific column from a csv file to an array using javascript
thank you :)
csv data is best represented in javascript using an array of arrays (a 2-dimension array) with primary indices representing rows (records in data-base terminology) and the inner indices representing column cells for that row (fields in data-base terminology).
Thus, this csv data:
"name","age","height"
"John",22,1.9
"Jane",21,1.9
"Joe",23,1.8
would be represented as:
[["name","age","height"],["John",22,1.9],["Jane",21,1.9],["Joe",23,1.8]];
in a javascript array.
If you have an array like that, you can extract a column (the first column, inner array index [0] in this case, easily with:
const columnArray = [];
for (let i=0; i<csvArray.length; i++){columnArray.push(array1[i][0])}
// columnArray now holds ["name","John","Jane","Jo"];
// use [1] instead of [0] for the second column, [2] for the third, etc.;
If you don't yet have the array, you will have to form one. Many frameworks may do this for you but it is easily achieved once you have the csv data inside a variable:
const csvFileData = // read from textarea or file;
const csvArray = csvFileData.split('\n')
// csvArray holds ['"name","age","height"', '"John",22,1.9', '"Jane",21,1.9', '"Joe",23,1.8'] at this stage;
// split the inner arrays to arrays of cell data;
for (let i=0; i<array1.lengthl; i++){array[i]=array[i].split(',')}
// We've replaced each element with an array holding the component cells of what was previously a row;
// csvArray now holds:
[["name","age","height"],["John",22,1.9],["Jane",21,1.9],["Joe",23,1.8]];
That final array can now be processed to extract the required column as shown above.
Finally, all this assumes you can get the csv data into a variable (remember it has line breaks). Fetch() is probably the standard way but a simple (if dirty) alternative I often use is to assign the value of an html textarea into which I have pasted the csv file contents into, directly to a variable:
const csvFileData = document.getElementById('textareaOnWebPage').value;

Compare two values in two array from two spreadsheet. why not?

I would like to compare two values getting from two cell in two different spreadsheet .....but it doesn't run. I don't understand....Logger.log give me same values ....
function aggiungiclienti(){
var fileid = PropertiesService.getScriptProperties().getProperty('FILEID')
var ss1 = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getRange('B1:B100').getValues()
var ss2 = SpreadsheetApp.openById(fileid).getRange('A1:A100').getValues()
Logger.log(ss1[3],ss2[3])
if(ss1[3] === ss2[3])
{
SpreadsheetApp.getUi().alert('Find!')
Logger.log(ss1[3],ss2[3])
}
}
Writing the answer for future viewers. As tanaike said, and according to the documentation:
(getValues) Returns a two-dimensional array of values, indexed by row, then by
column. The values may be of type Number, Boolean, Date, or String,
depending on the value of the cell. Empty cells are represented by an
empty string in the array. Remember that while a range index starts at
1, 1, the JavaScript array is indexed from [0][0].
So:
from if(ss1[3] === ss2[3]) to if(ss1[3][0] === ss2[3][0]) will get the right value of the array.

Google Sheet Script Editor - setValues for array

I`m trying to replace old values with new values using setValues in Google sheet script.
The data is in the below link...
https://docs.google.com/spreadsheets/d/1pSUVkxM9FhSNgizedHbY2MnYGTnC2iiYLfrWsoPmDks/edit?usp=sharing
I`m basically trying to remove first 14 characters and the last 12 characters under "Tracker" column
Below is the code I tried..
function URLReplacement() {
var ss = SpreadsheetApp.getActive().getSheetByName("transformer");
var rng = ss.getRange("G:G");
var data = rng.getValues();
for (var items in data)
{
var newer = data[items][0].substring(14)
// Turn these strings into an array
var newerr = newer.split(" ")
// Turn this into 2 dimensional array to use setValues
ss.getRange("G:G").setValues([newerr])
Logger.log([newer]);
}
}
But now, I get errors with the setValues statement
Saying the range I set there do not match the data
What am I doing wrong here..?
Can anyone please provide me with suggestions / advice?
You want to convert from IMAGE_SUFFIX_"http://google.com"<xxxnouse>" to http://google.com at the column "G".
The format of IMAGE_SUFFIX_"http://google.com"<xxxnouse>" is constant.
If my understanding is correct, how about this modification? The reason of your error is that [newer] is not 2 dimensional array for using setValues(). If this error was removed, the header is removed by overwriting the empty value. So I would like to modify as follows.
Modification points:
When getLastRow() is used, the data size retrieved by it can be reduced from that retrieved by "G:G". By this, the process cost can be reduced.
Header is not retrieved by getRange(2, 7, ss.getLastRow(), 1).
From the format of IMAGE_SUFFIX_"http://google.com"<xxxnouse>", split() was used for parsing this value.
The converted data was put by setValues(). By this, the process cost can be also reduced.
Modified script:
function URLReplacement() {
var ss = SpreadsheetApp.getActive().getSheetByName("transformer");
var rng = ss.getRange(2, 7, ss.getLastRow(), 1); // Modified
var data = rng.getValues();
var convertedData = data.map(function(e) {return e[0] ? [e[0].split('"')[1]] : e}); // Added
rng.setValues(convertedData); // Added
}
Note:
In your shared sample Spreadsheet, the sheet name is "Sheet1". But your script uses "transformer" as the sheet name. Please be careful this.
If the format of actual values in your Spreadsheet is different from your shared Spreadsheet, this might not be able to be used.
References:
split()
setValues()
If this was not the result you want, I apologize.

Creating a Javascript 2d String array without length limit

I'm trying to create a 2 dimensional string array in javascript that will allow an unlimited length in the first dimension, but a limited or unlimited length in the second dimension. The first dimension will need to be able to take in a string as a way to store and access the array. So let's say you have type and fieldNumber as the 2 dimensions. I would like to be able to store the array as such:
array[type][fieldNum] = value;
And type has to be able to be String.
I've been searching around, but all I found were either create a 1 dimension String array, create a 2 dimension array with row and col limits, and I couldn't find anywhere that allows me to do what I specified. Can anyone help out?
You can't declare a multi dimensional array in javascript. But you can put an array in an array.
var myArray = [];
myArray.push([]);
myArray[0][1] = 'test';
So in your case, you must handle when you try to reach an empty index in your array (and fill this index with an empty array).
I would like to be able to store the array as such:
array[type][fieldNum] = value;
What about this ? (using object)
var a ={};
a[type]= {};
a[type][fieldname]=someValue;
so :
var a ={};
a["john"]={};
a["john"]["age"]=40;
a["paul"]={};
a["paul"]["age"]=70;
this is no array, its an object when using strings as identifiers.
Objects/Arrays in Javascript are of unlimited length by default.
object = {};
//define 2nd dimension
object["name"] = {};
//enter stuff
object["name"]["id"] = 5;

indexOf returning -1 despite object being in the array - Javascript in Google Spreadsheet Scripts

I am writing a script for a Google Docs Spreadsheet to read a list of directors and add them to an array if they do not already appear within it.
However, I cannot seem to get indexOf to return anything other than -1 for elements that are contained within the array.
Can anyone tell me what I am doing wrong? Or point me to an easier way of doing this?
This is my script:
function readRows() {
var column = SpreadsheetApp.getActiveSpreadsheet().getRangeByName("Director");
var values = column.getValues();
var numRows = column.getNumRows();
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheets()[0];
var directors = new Array();
for (var i = 0; i <= numRows - 1; i++) {
var row = values[i];
if (directors.indexOf(row) == -1) {
directors.push(row);
} else {
directors.splice(directors.indexOf(row), 1, row);
}
}
for (var i = 2; i < directors.length; i++) {
var cell = sheet.getRange("F" + [i]);
cell.setValue(directors[i]);
}
};
When you retrieve values in Google Apps Script with getValues(), you will always be dealing with a 2D Javascript array (indexed by row then column), even if the range in question is one column wide. So in your particular case, and extending +RobG's example, your values array will actually look something like this:
[['fred'], ['sam'], ['sam'], ['fred']]
So you would need to change
var row = values[i];
to
var row = values[i][0];
As an aside, it might be worth noting that you can use a spreadsheet function native to Sheets to achieve this (typed directly into a spreadsheet cell):
=UNIQUE(Director)
This will update dynamically as the contents of the range named Director changes. That being said, there may well be a good reason that you wanted to use Google Apps Script for this.
It sounds like an issue with GAS and not the JS. I have always had trouble with getValues(). Even though the documentation says that it is a two dimensional array, you can't compare with it like you would expect to. Although if you use an indexing statement like values[0][1] you will get a basic data type. The solution (I hope there is a better way) is to force that object into a String() and then split() it back into an array that you can use.
Here is the code that I would use:
var column = SpreadsheetApp.getActiveSpreadsheet().getRangeByName("Director");
var values = column.getValues();
values = String(values).split(",");
var myIndex = values.indexOf(myDirector);
If myDirector is in values you will get a number != -1. However, commas in your data will cause problems. And this will only work with 1D arrays.
In your case: var row = values[i]; row is an object and not the string that you want to compare. Convert all of your values to an array like I have above and your comparison operators should work. (try printing row to the console to see what it says: Logger.log(row))
I ran into a similar problem with a spreadsheet function that took a range as an object. In my case, I was wanting to do a simple search for a fixed set of values (in another array).
The problem is, your "column" variable doesn't contain a column -- it contains a 2D array. Therefore, each value is it's own row (itself an array).
I know I could accomplish the following example using the existing function in the spreadsheet, but this is a decent demo of dealing with the 2D array to search for a value:
function flatten(range) {
var results = [];
var row, column;
for(row = 0; row < range.length; row++) {
for(column = 0; column < range[row].length; column++) {
results.push(range[row][column]);
}
}
return results;
}
function getIndex(range, value) {
return flatten(range).indexOf(value);
}
So, since I wanted to simply search the entire range for the existance of a value, I just flattened it into a single array. If you really are dealing with 2D ranges, then this type of flattening and grabbing the index may not be very useful. In my case, I was looking through a column to find the intersection of two sets.
Because we are working with a 2D array, 2dArray.indexOf("Search Term") must have a whole 1D array as the search term. If we want to search for a single cell value within that array, we must specify which row we want to look in.
This means we use 2dArray[0].indexOf("Search Term") if our search term is not an array. Doing this specifies that we want to look in the first "row" in the array.
If we were looking at a 3x3 cell range and we wanted to search the third row we would use 2dArray[2].indexOf("Search Term")
The script below gets the current row in the spreadsheet and turns it into an array. It then uses the indexOf() method to search that row for "Search Term"
//This function puts the specified row into an array.
//var getRowAsArray = function(theRow)
function getRowAsArray()
{
var ss = SpreadsheetApp.getActiveSpreadsheet(); // Get the current spreadsheet
var theSheet = ss.getActiveSheet(); // Get the current working sheet
var theRow = getCurrentRow(); // Get the row to be exported
var theLastColumn = theSheet.getLastColumn(); //Find the last column in the sheet.
var dataRange = theSheet.getRange(theRow, 1, 1, theLastColumn); //Select the range
var data = dataRange.getValues(); //Put the whole range into an array
Logger.log(data); //Put the data into the log for checking
Logger.log(data[0].indexOf("Search Term")); //2D array so it's necessary to specify which 1D array you want to search in.
//We are only working with one row so we specify the first array value,
//which contains all the data from our row
}
If someone comes across this post you may want to consider using the library below. It looks like it will work for me. I was getting '-1' return even when trying the examples provide (thanks for the suggestions!).
After adding the Array Lib (version 13), and using the find() function, I got the correct row!
This is the project key I used: MOHgh9lncF2UxY-NXF58v3eVJ5jnXUK_T
And the references:
https://sites.google.com/site/scriptsexamples/custom-methods/2d-arrays-library#TOC-Using
https://script.google.com/macros/library/d/MOHgh9lncF2UxY-NXF58v3eVJ5jnXUK_T/13
Hopefully this will help someone else also.
I had a similar issue. getValues() seems to be the issue. All other methods were giving me an indexOf = -1
I used the split method, and performed the indexOf on the new array created. It works!
var col_index = 1;
var indents_column = main_db.getRange(1,col_index,main_db.getLastRow(),1).getValues();
var values = String(indents_column).split(","); // flattening the getValues() result
var indent_row_in_main_db = values.indexOf(indent_to_edit) + 1; // this worked
I ran into the same thing when I was using
let foo = Sheet.getRange(firstRow, dataCol, maxRow).getValues();
as I was expecting foo to be a one dimensional array. On research for the cause of the apparently weird behavior of GAS I found this question and the explanation for the always two dimensional result. But I came up with a more simple solution to that, which works fine for me:
let foo = Sheet.getRange(firstRow, dataCol, maxRow).getValues().flat();

Categories

Resources