From 3ff0bf1f282f38b4e4ec42cd5134eec8d6fca9e5 Mon Sep 17 00:00:00 2001 From: Rufus Pollock Date: Tue, 20 Mar 2012 10:34:20 +0000 Subject: [PATCH 1/4] [refactor][s]: remove costco-csv-worker (we are not using it). --- recline.js | 57 ---------------------------------------- src/costco-csv-worker.js | 57 ---------------------------------------- 2 files changed, 114 deletions(-) delete mode 100644 src/costco-csv-worker.js diff --git a/recline.js b/recline.js index ee6f6fa3..64e0bc33 100644 --- a/recline.js +++ b/recline.js @@ -1,60 +1,3 @@ -// importScripts('lib/underscore.js'); - -onmessage = function(message) { - - function parseCSV(rawCSV) { - var patterns = new RegExp(( - // Delimiters. - "(\\,|\\r?\\n|\\r|^)" + - // Quoted fields. - "(?:\"([^\"]*(?:\"\"[^\"]*)*)\"|" + - // Standard fields. - "([^\"\\,\\r\\n]*))" - ), "gi"); - - var rows = [[]], matches = null; - - while (matches = patterns.exec(rawCSV)) { - var delimiter = matches[1]; - - if (delimiter.length && (delimiter !== ",")) rows.push([]); - - if (matches[2]) { - var value = matches[2].replace(new RegExp("\"\"", "g"), "\""); - } else { - var value = matches[3]; - } - rows[rows.length - 1].push(value); - } - - if(_.isEqual(rows[rows.length -1], [""])) rows.pop(); - - var docs = []; - var headers = _.first(rows); - _.each(_.rest(rows), function(row, rowIDX) { - var doc = {}; - _.each(row, function(cell, idx) { - doc[headers[idx]] = cell; - }) - docs.push(doc); - }) - - return docs; - } - - var docs = parseCSV(message.data.data); - - var req = new XMLHttpRequest(); - - req.onprogress = req.upload.onprogress = function(e) { - if(e.lengthComputable) postMessage({ percent: (e.loaded / e.total) * 100 }); - }; - - req.onreadystatechange = function() { if (req.readyState == 4) postMessage({done: true, response: req.responseText}) }; - req.open('POST', message.data.url); - req.setRequestHeader('Content-Type', 'application/json'); - req.send(JSON.stringify({docs: docs})); -}; // adapted from https://github.com/harthur/costco. heather rules var costco = function() { diff --git a/src/costco-csv-worker.js b/src/costco-csv-worker.js deleted file mode 100644 index 720d2fda..00000000 --- a/src/costco-csv-worker.js +++ /dev/null @@ -1,57 +0,0 @@ -// importScripts('lib/underscore.js'); - -onmessage = function(message) { - - function parseCSV(rawCSV) { - var patterns = new RegExp(( - // Delimiters. - "(\\,|\\r?\\n|\\r|^)" + - // Quoted fields. - "(?:\"([^\"]*(?:\"\"[^\"]*)*)\"|" + - // Standard fields. - "([^\"\\,\\r\\n]*))" - ), "gi"); - - var rows = [[]], matches = null; - - while (matches = patterns.exec(rawCSV)) { - var delimiter = matches[1]; - - if (delimiter.length && (delimiter !== ",")) rows.push([]); - - if (matches[2]) { - var value = matches[2].replace(new RegExp("\"\"", "g"), "\""); - } else { - var value = matches[3]; - } - rows[rows.length - 1].push(value); - } - - if(_.isEqual(rows[rows.length -1], [""])) rows.pop(); - - var docs = []; - var headers = _.first(rows); - _.each(_.rest(rows), function(row, rowIDX) { - var doc = {}; - _.each(row, function(cell, idx) { - doc[headers[idx]] = cell; - }) - docs.push(doc); - }) - - return docs; - } - - var docs = parseCSV(message.data.data); - - var req = new XMLHttpRequest(); - - req.onprogress = req.upload.onprogress = function(e) { - if(e.lengthComputable) postMessage({ percent: (e.loaded / e.total) * 100 }); - }; - - req.onreadystatechange = function() { if (req.readyState == 4) postMessage({done: true, response: req.responseText}) }; - req.open('POST', message.data.url); - req.setRequestHeader('Content-Type', 'application/json'); - req.send(JSON.stringify({docs: docs})); -}; From 70ea2bd8639a5a63e26a30630649f0599cc0ef65 Mon Sep 17 00:00:00 2001 From: Rufus Pollock Date: Fri, 23 Mar 2012 02:41:53 +0000 Subject: [PATCH 2/4] [#34,bugfix,view][s]: fix issues with interaction of hash changes with view updating. * Problem was in e.g. default demo that with new hash we were not matching on grid view and hence only displaying that (so we displayed both grid and graph which was nasty ...) * Fix this by better match on route. Also improve by using router.navigate on query update --- src/view.js | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/src/view.js b/src/view.js index db7c1e5a..72b1c0d3 100644 --- a/src/view.js +++ b/src/view.js @@ -114,7 +114,8 @@ my.DataExplorer = Backbone.View.extend({ // update navigation var qs = my.parseHashQueryString(); qs['reclineQuery'] = JSON.stringify(self.model.queryState.toJSON()); - my.setHashQueryString(qs); + var out = my.getNewHashForQueryString(qs); + self.router.navigate(out); }); this.model.bind('query:fail', function(error) { my.clearNotifications(); @@ -172,8 +173,8 @@ my.DataExplorer = Backbone.View.extend({ setupRouting: function() { var self = this; // Default route - this.router.route('', this.pageViews[0].id, function() { - self.updateNav(self.pageViews[0].id); + this.router.route(/^(\?.*)?$/, this.pageViews[0].id, function(queryString) { + self.updateNav(self.pageViews[0].id, queryString); }); $.each(this.pageViews, function(idx, view) { self.router.route(/^([^?]+)(\?.*)?/, 'view', function(viewId, queryString) { @@ -331,8 +332,18 @@ my.composeQueryString = function(queryParams) { return queryString; } +my.getNewHashForQueryString = function(queryParams) { + var queryPart = my.composeQueryString(queryParams); + if (window.location.hash) { + // slice(1) to remove # at start + return window.location.hash.split('?')[0].slice(1) + queryPart; + } else { + return queryPart; + } +} + my.setHashQueryString = function(queryParams) { - window.location.hash = window.location.hash.split('?')[0] + my.composeQueryString(queryParams); + window.location.hash = my.getNewHashForQueryString(queryParams); } // ## notify From d1445ee12f031486081effbcbbd1ba284070db85 Mon Sep 17 00:00:00 2001 From: Rufus Pollock Date: Fri, 23 Mar 2012 03:53:49 +0000 Subject: [PATCH 3/4] [#58,flot-graph][s]: switch to horizontal bar chart as normal bar chart tick labels are borked without rotation when lots of bars (rotation not yet in flot core [1]). [1]: https://github.com/flot/flot/pull/15 --- src/view-flot-graph.js | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/view-flot-graph.js b/src/view-flot-graph.js index 5b6aee18..c96f9542 100644 --- a/src/view-flot-graph.js +++ b/src/view-flot-graph.js @@ -167,10 +167,11 @@ my.FlotGraph = Backbone.View.extend({ // needs to be function as can depend on state getGraphOptions: function(typeId) { var self = this; + // special tickformatter to show labels rather than numbers var tickFormatter = function (val) { if (self.model.currentDocuments.models[val]) { var out = self.model.currentDocuments.models[val].get(self.chartConfig.group); - // if the x-axis value was in fact a number we want that not the + // if the value was in fact a number we want that not the if (typeof(out) == 'number') { return val; } else { @@ -209,14 +210,17 @@ my.FlotGraph = Backbone.View.extend({ show: true, barWidth: 1, align: "center", - fill: true + fill: true, + horizontal: true } }, grid: { hoverable: true, clickable: true }, - xaxis: { + yaxis: { tickSize: 1, tickLength: 1, - tickFormatter: tickFormatter + tickFormatter: tickFormatter, + min: -0.5, + max: self.model.currentDocuments.length - 0.5 } } } @@ -283,7 +287,12 @@ my.FlotGraph = Backbone.View.extend({ if (typeof x === 'string') { x = index; } - points.push([x, y]); + // horizontal bar chart + if (self.chartConfig.graphType == 'bars') { + points.push([y, x]); + } else { + points.push([x, y]); + } }); series.push({data: points, label: field}); }); From 34a16b7c0375c64b71a6d64ca3acbc1f00b7096a Mon Sep 17 00:00:00 2001 From: Rufus Pollock Date: Fri, 23 Mar 2012 03:58:58 +0000 Subject: [PATCH 4/4] [build][xs]: build latest. --- recline.js | 38 +++++++++++++++++++++++++++++--------- 1 file changed, 29 insertions(+), 9 deletions(-) diff --git a/recline.js b/recline.js index 64e0bc33..ccf234d5 100644 --- a/recline.js +++ b/recline.js @@ -513,10 +513,11 @@ my.FlotGraph = Backbone.View.extend({ // needs to be function as can depend on state getGraphOptions: function(typeId) { var self = this; + // special tickformatter to show labels rather than numbers var tickFormatter = function (val) { if (self.model.currentDocuments.models[val]) { var out = self.model.currentDocuments.models[val].get(self.chartConfig.group); - // if the x-axis value was in fact a number we want that not the + // if the value was in fact a number we want that not the if (typeof(out) == 'number') { return val; } else { @@ -555,14 +556,17 @@ my.FlotGraph = Backbone.View.extend({ show: true, barWidth: 1, align: "center", - fill: true + fill: true, + horizontal: true } }, grid: { hoverable: true, clickable: true }, - xaxis: { + yaxis: { tickSize: 1, tickLength: 1, - tickFormatter: tickFormatter + tickFormatter: tickFormatter, + min: -0.5, + max: self.model.currentDocuments.length - 0.5 } } } @@ -629,7 +633,12 @@ my.FlotGraph = Backbone.View.extend({ if (typeof x === 'string') { x = index; } - points.push([x, y]); + // horizontal bar chart + if (self.chartConfig.graphType == 'bars') { + points.push([y, x]); + } else { + points.push([x, y]); + } }); series.push({data: points, label: field}); }); @@ -1357,7 +1366,8 @@ my.DataExplorer = Backbone.View.extend({ // update navigation var qs = my.parseHashQueryString(); qs['reclineQuery'] = JSON.stringify(self.model.queryState.toJSON()); - my.setHashQueryString(qs); + var out = my.getNewHashForQueryString(qs); + self.router.navigate(out); }); this.model.bind('query:fail', function(error) { my.clearNotifications(); @@ -1415,8 +1425,8 @@ my.DataExplorer = Backbone.View.extend({ setupRouting: function() { var self = this; // Default route - this.router.route('', this.pageViews[0].id, function() { - self.updateNav(self.pageViews[0].id); + this.router.route(/^(\?.*)?$/, this.pageViews[0].id, function(queryString) { + self.updateNav(self.pageViews[0].id, queryString); }); $.each(this.pageViews, function(idx, view) { self.router.route(/^([^?]+)(\?.*)?/, 'view', function(viewId, queryString) { @@ -1574,8 +1584,18 @@ my.composeQueryString = function(queryParams) { return queryString; } +my.getNewHashForQueryString = function(queryParams) { + var queryPart = my.composeQueryString(queryParams); + if (window.location.hash) { + // slice(1) to remove # at start + return window.location.hash.split('?')[0].slice(1) + queryPart; + } else { + return queryPart; + } +} + my.setHashQueryString = function(queryParams) { - window.location.hash = window.location.hash.split('?')[0] + my.composeQueryString(queryParams); + window.location.hash = my.getNewHashForQueryString(queryParams); } // ## notify