Google datatable sort columns as numbers - javascript

Using the google embed api and datatables to visualize my analytics. The problem is the columns don't resort correctly -- that is everything is treated as a string. I have this code:
gapi.client.analytics.data.ga.get(queryObj1).execute(function(results){
var myTable = new google.visualization.DataTable(results.dataTable);
....
This creates the myTable correctly and when I debug I see that the columns created have the correct type -- string or number. However when I check the values in results.dataTable (the object returned by the query) I notice that everything is a string -- as one might expect from an ajax call.
I found this thread about rewriting the sort function, but that seems a bit complex to me and if anything went wrong I'm not sure I'd be able to figure it out.
My approach is to iterate through the datatable and convert all the number columns to actual numbers.
function makeNumbers(results){
// make numbers actually numbers so they will sort properly
for(var c in results.cols){
// check if the column is a number type
if(results.cols[c].type === "number"){
// fix the values for that column is all the rows
for(var r in results.rows){
results.rows[r].c[c].v = +results.rows[r].c[c].v
}
}
}
return results;
}
This seems to work great and to my mind is much simpler than changing the sorting function.
Can anyone see a problem with this? Or a better way to do it?

Related

Google Scripts Simple Search

I want to search a sheet for a value in a sheet, and then return the row and the column where the value was found.
I am well-versed in VBA and have used the .Find function to accomplish this very easily. However, after searching for the last 30 minutes online, I have been stunned to discover that is is so hard to find the code for this extremely simple function. I feel like I am in the twilight zone. Does Javascript really not have anything analogous to .Find? If so, why is this language used so much when VBA appears to be able to accomplish the same tasks in a much more simple manner? Please advise.
I assume you are calling something like mysheet.getDataRange().getValues(), which returns the contents of a google sheet as an array of arrays, eg, [[row1A, row1B], [row2A, row2B]].
With JS, you can get the index of a value in an array using indexOf, which returns the index of the found item or -1 if the item is not in the array. I don't think you can directly search across the two nested arrays. Instead, you could try iterating over the outer array and searching the inner array. Something like this:
// get data from google sheet, doing something like this
var data = mysheet.getDataRange().getValues()
// define our own function
function findItem(data) {
// loop over outer array
for (var i=0; i < data.length; i++) {
var row = data[i]; // get the inner array
var idx = row.indexOf(searchValue); // search for value
// if the value is found, return [row, column]
if (idx > -1) {
return [i, idx];
}
}
// call the function
var res = findItem(data);
var row = res[0];
var col = res[1];
You're comparing apples and oranges. JavaScript and VBA are different languages with different goals. VBA was built to allow it to integrate seamlessly with the MSSQLServer. JavaScript in its native form has no relational-database functionality at all. It's meant more for manipulating web pages through the DOM. (It can do more than that, but that's its primary function.) While VBA can do some of the things Javascript can do, it's a rather clunky way (IMHO) of doing so and narrowly focused on a rather specific set of problems that are tied to very specific software and hardware infrastructures. While that functionality might be nice to have in some cases, most of the JavaScript you see on the web today isn't interested in databases at all.
It's not clear to me what source of data you're trying to connect to but if you are specifically looking for a JavaScript data solution you might want to look into something like MongoDB, and the code libraries that have been developed specifically for that. And there are tons of other JS libraries that are relational-data or database-specific, and you can search places like npm for those. Or you can combine JavaScript with languages that inherently include database functionality, and PHP is an excellent example of that.

Manipulating formatted numbers in a page

I'm working with numerical data I.e. adding, subtracting, present valuing, etc, numbers in a page. However, I format them and print them to the screen. Say I want to add a column of numbers, I have to parse for commas etc. Is there a paradigm to use the actual data, an not have to parse the DOM data? Or should I store both data in the page, but save the numbers as an attribute?
If I understand your question correctly, it sounds like you might be looking for Angular or some other form of two way data binding. Using that framework, you would be able to setup a template to reflect automatically to your "data model" (some javascript construct in memory) and have it update automatically to reflect changes in that model. You can also use "filters" when drawing it to the page to make the raw number display as currency.
create a template. and then pass variables to it, and it spits out html
--mustache (multi types, you want javascript)
--handlerbars.js
=================
MISC javascript code that might be worth while to you.
// would split things up on underscore _
// replace underscore with comma if wanted.
var something = your_something.split('_');
//some for loops
for( var i in something) {
var a = something[i];
}
for (var i = 0; i < something.length; i++) {
var a = something[i];
}
regex, .match, .replace
// are javascript string commands for....
// find(something) and replace with (something) doing.
// other words dealing with decimal points, dollar signs etc..
// and extracting numbers or like.
//dealing with objects and arrays and getting data from them.
something['name'] //= something.name = same thing in many situations.
something[i].name
something[i][x]
something.name.x
var a = '<table>';
a+= '<tr>';
a+= '<td>;
//a = <table><tr><td>
.innerhtml or .append
//used to add stuff to the dom / html stuff already in the something.html file.
json.parse() // may come up
there are way more better examples than i can do out there. but hopefully pickup some keywords that would reveal better internet searches for examples.
normally doing for me... google search "javascript .innerhtml" and open 4 to 10 results i get back and normally find enough to satisfy what i want.
jtables.com i want to say, or datatables.net i also want to say deal with sort spreadhsheet like columns and sorting data that the end user can do.
cookies, localstorage, indexeddb. localstorage most likely easier of the 3 with enough power for simple application and storing information.

How to find column max or min of a multidimensional javascript array using D3?

Is there a way to use d3.max or d3.min to find the maximum or minimum of a specific column in a multidimensional javascript array?
var arr = new Array();
for(var i=0;i<10;i++){
arr.push([i,Math.random()]);
}
From this code I'd like to do something like d3.max(arr[*][1]) (with a wildcard, or otherwise) to get the maximum value of the second column, but specifying an index seems to require designating a row first, and then a column, which seems to limit the d3.max routine to row operations only.
I know I can code a separate function to extract this information, but am wondering if there is something built into the D3 API or in Javascript that will do this.
I found one way to do this using the map method:
arr.map(function(x){return x[1];})
This will return an array of the items at index "1" in each mapped element. With this, applying the d3.max function works fine. I guess its the solution for now.

Web pivot table componet showing text in pivot table data area

I have found these great pivot table components on the web
nicolaskruchten - pivottable
ZKOSS - pivottable
RJackson - pivottable
My problem (or question) lies in the fact that pivot tables inherently "pivot" data around a numeric data-set; meaning the cell intersections can typically only be numeric in nature (SUM/COUNT/FIRST...)
Is there anything out there (or, if you know how to modify a current component) that will show non-numeric data within the pivot "Value" or intersection.
my question is illustrated below.
as can be seen the interaction data is actually the reports which each role has acess to (grouped by the class of report)... I know there are other ways to represent this data, however I really like the way the pivot viewers above can swap the data filters (columns)
thanks in advance.
I can't speak for all the different pivot table implementations out there, some might have a built-in "aggregator" that will allow you to concatenate string values with formatting (to add a cr/lf for example), but a quick look at the nicolaskruchten/pivottable source lets me think you could easily add your own aggregator.
Just look at file pivot.coffee, starting at line 22. You'll see different aggregator templates, so you could probably add your own right there.
EDIT
I just looked at the rjackson/pivot.js implementation, and by the looks of it, if you add your own defaultSummarizeFunction at pivot.js line 586+, and then also add it to the select at lines 651+, you could create your own "concat" SummarizeFunction
EDIT 2
Well, turns out to be even easier than I thought. Using the rjackson/pivot.js one, all you have to do is provide your own summarizeFunction when you define your concatenable field:
{name: 'billed_amount', type: 'string', rowLabelable: false, summarizable: 'string', summarizeFunction: function(rows, field){
var result = '',
i = -1;
m = rows.length;
while (++i < m) {
result = result + rows[i][field.dataSource] + '<br>';
}
return result;
}}
In this example, I turned a field that would normally be summed, and turned it into a concatenated one simply by providing my own summarizeFunction.
Look at an example here: http://mrlucmorin.github.io/pivot.js/
Cheers

Extra newline characters in JavaScript arrays

I am working on a program that parses a CSV files and then moves the respective data into different arrays that will make a spreadsheet out of them. However, my spreadsheet has extra blank rows with one cell each. Upon further inspection, I have found these extra cells contain a single newline character each. I have filtered my arrays so that they do not contain any newline characters, yet the problem still persists. I am doing this in conjunction with AngularJS, and while I doubt that is causing the problem, I did not have this issue before I implemented Angular.
Has anyone had anything like this before? With dynamic creation of newline characters where they shouldn't be.
Here is some of my code:
headers = breakText[0];
function isDefined(element, index, array){
return (element !== undefined || element !=='\n');
//I tried to stop the newlines here, but this did nothing
};
//new header file including ONLY desired titles; no undefines
$scope.clearHeaders = headers.filter(isDefined);
$scope.clearPatients = [];
for(var i=1; i<breakText.length; i++){
if breakText[0] {
$scope.clearPatients.push(breakText[i].filter(isDefined));
}
};
breakText was a 2D array containing undefined areas where I had deleted stuff. So the above code is creating a new header array and another, 2D array to hold an array of data for each person, all without undefined spaces. These arrays contain blanks "" as well as data, but nothing with \n or \r\n.
Here is part of the AngularJS implementation:
$scope.columns = $scope.clearHeaders;
$scope.cells = {};
$scope.values = $scope.clearPatients.map(function(c,row){
return c.map(function(data){
return {
content: data,
color: $scope.makeColors(data)
};
});
});
We have tried using a replace function to replace \n with '' and disallow it to return the data if it is '' but this causes issues since some of our initial data is also blank. It also does not stop the creation of the new cell.
We have also tried wrapping it in something such as if(data !== '\n') but that changed nothing.
Edit1:
You can see it working live here, yet it is designed to work with this small CSV file that can be downloaded here.
The text below the table after you upload a file shows what each cell is bound to, and if you click and edit the cells, you can see the content dynamically changing. By clicking on the extra cells between the rows, you can see that they contain a newline character.
I just tried creating a new filter function, where it would check for a newline in the clearPatients array, and then filter everything into a new array, sans-newline. This new array was then called to be in the table rather than the one with newlines. Yet this threw many errors that could not be determined of their source.
Edit2:
After Mike P's answer and some other input, it was determined that the best way to fix this problem would be to swap the line var allTextLines = $scope.csv.split(/\r\n|\n/);
with the regex /\r?\n/
Thanks for your help!
Your problem doesn't look like it has anything to do with AngularjS. You've got your text data in $scope.csv and you split off your regular expression, and that creates an array of strings in allTextLines.
This array of strings has some useless lines in it (at idx 1, 3, and 4). So you'll either want to modify your regex split expression or loop through this array and remove stuff you don't want.
You may want to check out this guy's CSV to Array JS code # Javascript code to parse CSV data
I can clearly see your spreadsheet code creating rows & cells for these portions of allTextLines. So remove those and you're in business.

Categories

Resources