');
$el.appendTo($('.data-explorer-here'));
- var dataset = demoDataset();
+ var views = standardViews(dataset);
+ window.dataExplorer = new recline.View.DataExplorer({
+ el: $el
+ , model: dataset
+ , views: views
+ });
+ // HACK (a bit). Issue is that Backbone will not trigger the route
+ // if you are already at that location so we have to make sure we genuinely switch
+ window.dataExplorer.router.navigate('graph');
+ window.dataExplorer.router.navigate('', true);
+}
+
+// convenience function
+function standardViews(dataset) {
var views = [
{
id: 'grid',
@@ -18,33 +65,11 @@ $(function() {
})
}
];
- window.dataExplorer = new recline.View.DataExplorer({
- el: $el
- , model: dataset
- , views: views
- });
- Backbone.history.start();
- setupLoadFromWebstore(function(dataset) {
- window.dataExplorer.remove();
- var $el = $('');
- $el.appendTo($('.data-explorer-here'));
- window.dataExplorer = null;
- window.dataExplorer = new recline.View.DataExplorer({
- el: $el
- , model: dataset
- });
- // HACK (a bit). Issue is that Backbone will not trigger the route
- // if you are already at that location so we have to make sure we genuinely switch
- window.dataExplorer.router.navigate('graph');
- window.dataExplorer.router.navigate('', true);
- });
- $('a.set-read-only').click(function() {
- window.dataExplorer.setReadOnly();
- alert('Read-only mode set');
- });
-})
+ return views;
+}
-function demoDataset() {
+// provide a demonstration in memory dataset
+function localDataset() {
var datasetId = 'test-dataset';
var inData = {
metadata: {
@@ -68,7 +93,8 @@ function demoDataset() {
return dataset;
}
-function setupLoadFromWebstore(callback) {
+// setup the loader menu in top bar
+function setupLoader(callback) {
// pre-populate webstore load form with an example url
var demoUrl = 'http://thedatahub.org/api/data/b9aae52b-b082-4159-b46f-7bb9c158d013';
$('form.webstore-load input[name="source"]').val(demoUrl);
diff --git a/demo/original.html b/demo/original.html
deleted file mode 100755
index 5768e297..00000000
--- a/demo/original.html
+++ /dev/null
@@ -1,248 +0,0 @@
-
-
-
-
- Data Explorer
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
zip the fields with the data rows to produce js objs
TODO: factor this out as a common method with other backends
varobjs=_.map(dataset._dataCache,function(d){varobj={};_.each(_.zip(fields,d),function(x){obj[x[0]]=x[1];})
@@ -59,11 +77,11 @@ TODO: factor this out as a common method with other backends var results={'field':[],'data':[]
- };
if(gdocsSpreadsheet.feed.entry.length>0){for(varkingdocsSpreadsheet.feed.entry[0]){if(k.substr(0,3)=='gsx'){varcol=k.substr(4)
@@ -71,13 +89,13 @@ TODO: factor this out as a common method with other backends }
}}
- }
\ No newline at end of file
diff --git a/docs/model.html b/docs/model.html
index 053d7577..ae7bcb5c 100644
--- a/docs/model.html
+++ b/docs/model.html
@@ -36,7 +36,7 @@ updated by queryObj (if provided).
also returned.
query:function(queryObj){this.trigger('query:start');varself=this;
- this.queryState.set(queryObj,{silent:true});
+ this.queryState.set(queryObj);vardfd=$.Deferred();this.backend.query(this,this.queryState.toJSON()).done(function(rows){vardocs=_.map(rows,function(row){
diff --git a/docs/view-flot-graph.html b/docs/view-flot-graph.html
index dac85e8a..cd3d6080 100644
--- a/docs/view-flot-graph.html
+++ b/docs/view-flot-graph.html
@@ -36,7 +36,10 @@ generate the element itself (you can then append view.el to the DOM.
<label>Graph Type</label> \ <div class="input editor-type"> \ <select> \
- <option value="line">Line</option> \
+ <option value="lines-and-points">Lines and Points</option> \
+ <option value="lines">Lines</option> \
+ <option value="points">Points</option> \
+ <option value="bars">Bars</option> \ </select> \ </div> \ <label>Group Column (x-axis)</label> \
@@ -95,7 +98,7 @@ generate the element itself (you can then append view.el to the DOM.
this.chartConfig=_.extend({group:null,series:[],
- graphType:'line'
+ graphType:'lines-and-points'},configFromHash,config
@@ -113,9 +116,14 @@ could be simpler just to have a common template!
varqs=my.parseHashQueryString();
+ qs['graph']=JSON.stringify(this.chartConfig);my.setHashQueryString(qs);this.redraw();},
@@ -128,25 +136,98 @@ TODO: make this less invasive (e.g. preserve other keys in query string)
this.router.route('',this.pageViews[0].id,function(){self.updateNav(self.pageViews[0].id);});$.each(this.pageViews,function(idx,view){
@@ -155,8 +173,10 @@ note this.model and dataset returned are the same
updateNav:function(pageName,queryString){this.el.find('.navigation li').removeClass('active');
+ this.el.find('.navigation li a').removeClass('disabled');var$el=this.el.find('.navigation li a[href=#'+pageName+']');
- $el.parent().addClass('active');
_.each(this.pageViews,function(view,idx){if(view.id===pageName){view.view.el.show();}else{
@@ -171,21 +191,31 @@ note this.model and dataset returned are the same
Parse the Hash section of a URL into path and query string
my.parseHashUrl=function(hashUrl){varparsed=urlPathRegex.exec(hashUrl);if(parsed==null){return{};
@@ -230,7 +272,10 @@ note this.model and dataset returned are the same
Parse a URL query string (?xyz=abc...) into a dictionary.
my.parseQueryString=function(q){
+ if(!q){
+ return{};
+ }varurlParams={},e,d=function(s){returnunescape(s.replace(/\+/g," "));
@@ -240,17 +285,17 @@ note this.model and dataset returned are the same
my.composeQueryString=function(queryParams){varqueryString='?';varitems=[];$.each(queryParams,function(key,value){
- items.push(key+'='+JSON.stringify(value));
+ items.push(key+'='+value);});queryString+=items.join('&');returnqueryString;
@@ -258,7 +303,7 @@ note this.model and dataset returned are the same
- Recline Data Explorer Powerful and extensible JS grid/spreadsheet
+ Recline Data Explorer Powerful, extensible JS grid/spreadsheet built on Backbone
Recline combines a data grid, Google Refine-style data transforms
and visualizations all in lightweight javascript and html.
Designed for standalone use or as a library to integrate into your own
- app. Recline utilizes the lightweight but powerful Backbone framework, and
- so is a cinch to extend or adapt.
+ app. Recline builds on the powerful but lightweight Backbone framework
+ making it extremely easy to extend and adapt.
Main Features
@@ -113,27 +113,7 @@
CSS: the demo utilizes bootstrap but you can integrate with your own HTML and CSS. Data Explorer specific CSS can be found here in the repo: https://github.com/okfn/recline/tree/master/css.
Documentation
-
Recline has a simple structure layered on top of the basic Model/View
- distinction inherent in Backbone. There are the following two main domain objects (all Backbone Models):
-
-
Dataset: represents the dataset. Holds dataset info and a pointer to list of data items (Documents in our terminology) which it can load from the relevant Backend.
-
Document: an individual data item (e.g. a row from a relational database or a spreadsheet, a document from from a document DB like CouchDB or MongoDB).
Backends (more info below) connect Dataset and Documents to data
- from a specific 'Backend' data source. They provide methods for loading and
- saving Datasets and individuals Documents as well as for bulk loading via a
- query API and doing bulk transforms on the backend.
-
-
Complementing the model are various Views (you can easily write your own). Each view holds a pointer to a Dataset:
-
-
DataExplorer: the parent view which manages the overall app and sets up sub views.
// Note: you should have included the relevant JS libraries (and CSS)
// See above for dependencies
@@ -158,6 +138,29 @@ Backbone.history.start();
href="demo/">Demo -- just hit view source (NB: the javascript for the
demo is in: app.js).
+
Architecture and Model
+
Recline has a simple structure layered on top of the basic Model/View
+ distinction inherent in Backbone. There are the following two main domain objects (both Backbone Models):
+
+
Dataset: represents the dataset. Holds dataset info and a pointer to list of data items (Documents in our terminology) which it can load from the relevant Backend.
+
Document: an individual data item (e.g. a row from a relational database or a spreadsheet, a document from from a document DB like CouchDB or MongoDB).
+
+
More detail of how these work can be found in the Model source docs.
+
+
Backends connect Dataset and Documents to data
+ from a specific 'Backend' data source. They provide methods for loading and
+ saving Datasets and individuals Documents as well as for bulk loading via a
+ query API and doing bulk transforms on the backend. More info on backends can be found below.
+
+
Complementing the model are various Views (you can easily write your own). Each view holds a pointer to a Dataset:
+
+
DataExplorer: the parent view which manages the overall app and sets up sub views.
Backends are connectors to backend data sources from which data can be retrieved.
@@ -197,10 +200,11 @@ used by the Dataset.query method to search the backend for documents,
retrieving the results in bulk. This method should also set the docCount
attribute on the dataset.
-
queryObj should be either a recline.Model.Query object or a
+
queryObj should be either a recline.Model.Query object or a
Hash. The structure of data in the Query object or Hash should follow that
-defined in issue 34. (That said, if you are writing your own backend and have
-control over the query object you can obviously use whatever structure you
+defined in issue 34. (Of
+course, if you are writing your own backend, and hence have control over the
+interpretation of the query object, you can use whatever structure you
like).