diff --git a/demo/js/app.js b/demo/js/app.js
index 49059d8d..470f7b34 100755
--- a/demo/js/app.js
+++ b/demo/js/app.js
@@ -4,9 +4,9 @@ $(function() {
window.$container = $('.data-explorer-here');
var dataset = demoDataset();
window.dataExplorer = new recline.View.DataExplorer({
- model: dataset
+ el: window.$container
+ , model: dataset
});
- window.$container.append(window.dataExplorer.el);
setupLoadFromWebstore(function(dataset) {
window.dataExplorer.remove();
window.dataExplorer = null;
diff --git a/src/view.js b/src/view.js
index 4c64a6db..f396329e 100644
--- a/src/view.js
+++ b/src/view.js
@@ -6,6 +6,10 @@ recline.View = function($) {
var my = {};
// The primary view for the entire application.
+//
+// It should be initialized with a recline.Model.Dataset object and an existing
+// dom element to attach to (the existing DOM element is important for
+// rendering of FlotGraph subview).
//
// To pass in configuration options use the config key in initialization hash
// e.g.
@@ -22,12 +26,11 @@ var my = {};
//
// All other views as contained in this one.
my.DataExplorer = Backbone.View.extend({
- tagName: 'div',
- className: 'data-explorer',
template: ' \
+
\
\
+
\
',
events: {
- 'click .navigation li a': 'navChange',
'submit form.display-count': 'onDisplayCountUpdate'
},
initialize: function(options) {
+ var self = this;
this.el = $(this.el);
this.config = options.config || {};
_.extend(this.config, {
@@ -65,35 +69,34 @@ my.DataExplorer = Backbone.View.extend({
if (this.config.readOnly) {
this.setReadOnly();
}
- this.draw();
+ // Hash of 'page' views (i.e. those for whole page) keyed by page name
+ this.pageViews = {
+ grid: new my.DataTable({
+ model: this.model
+ })
+ , graph: new my.FlotGraph({
+ model: this.model
+ })
+ };
+ // this must be called after pageViews are created
+ this.render();
+
+ this.router = new Backbone.Router();
+ this.setupRouting();
+ Backbone.history.start();
+
+ // retrieve basic data like headers etc
+ // note this.model and dataset returned are the same
+ this.model.fetch().then(function(dataset) {
+ // initialize of dataTable calls render
+ self.model.getDocuments(self.config.displayCount);
+ });
},
onDisplayCountUpdate: function(e) {
e.preventDefault();
this.config.displayCount = parseInt(this.el.find('input[name="displayCount"]').val());
- this.draw();
- },
-
- draw: function() {
- var self = this;
- this.el.empty();
- // retrieve basic data like headers etc
- // note this.model and dataset returned are the same
- this.model.fetch().then(function(dataset) {
- self.render();
- self.$dataViewContainer = self.el.find('.data-view-container');
- // initialize of dataTable calls render
- self.dataTable = new my.DataTable({
- model: dataset
- });
- self.flotGraph = new my.FlotGraph({
- model: dataset
- });
- self.flotGraph.el.hide();
- self.$dataViewContainer.append(self.dataTable.el)
- self.$dataViewContainer.append(self.flotGraph.el);
- self.model.getDocuments(self.config.displayCount);
- });
+ this.model.getDocuments(this.config.displayCount);
},
setReadOnly: function() {
@@ -105,25 +108,40 @@ my.DataExplorer = Backbone.View.extend({
tmplData.displayCount = this.config.displayCount;
var template = $.mustache(this.template, tmplData);
$(this.el).html(template);
+ var $dataViewContainer = this.el.find('.data-view-container');
+ _.each(this.pageViews, function(view, pageName) {
+ $dataViewContainer.append(view.el)
+ });
},
- navChange: function(e) {
- // TODO: really ugly and will not scale to more widgets ...
- var widgetToShow = $(e.target).attr('href').slice(1);
+ setupRouting: function() {
+ var self = this;
+ this.router.route('', 'grid', function() {
+ self.updateNav('grid');
+ });
+ this.router.route('grid', 'grid', function() {
+ self.updateNav('grid');
+ });
+ this.router.route('graph', 'graph', function() {
+ self.updateNav('graph');
+ // we have to call here due to fact plot cannot draw if hidden
+ // see comments in FlotGraph.redraw
+ self.pageViews['graph'].redraw();
+ });
+ },
+
+ updateNav: function(pageName) {
this.el.find('.navigation li').removeClass('active');
- $(e.target).parent().addClass('active');
- if (widgetToShow == 'datatable') {
- this.flotGraph.el.hide();
- this.dataTable.el.show();
- } else if (widgetToShow == 'graph') {
- this.flotGraph.el.show();
- this.dataTable.el.hide();
- // Have to call this here
- // If you attempt to render with flot when graph is hidden / invisible flot will complain with
- // Invalid dimensions for plot, width = 0, height = 0
- // (Could hack this by moving plot left -1000 or similar ...)
- this.flotGraph.createPlot();
- }
+ var $el = this.el.find('.navigation li a[href=#' + pageName + ']');
+ $el.parent().addClass('active');
+ // show the specific page
+ _.each(this.pageViews, function(view, pageViewName) {
+ if (pageViewName === pageName) {
+ view.el.show();
+ } else {
+ view.el.hide();
+ }
+ });
}
});
@@ -641,15 +659,18 @@ my.FlotGraph = Backbone.View.extend({
initialize: function(options, chart) {
var self = this;
this.el = $(this.el);
- _.bindAll(this, 'render');
- this.model.currentDocuments.bind('add', this.render);
- this.model.currentDocuments.bind('reset', this.render);
+ _.bindAll(this, 'render', 'redraw');
+ // we need the model.headers to render properly
+ this.model.bind('change', this.render);
+ this.model.currentDocuments.bind('add', this.redraw);
+ this.model.currentDocuments.bind('reset', this.redraw);
this.chart = chart;
this.chartConfig = {
group: null,
series: [],
graphType: 'line'
};
+ this.render();
},
toTemplateJSON: function() {
@@ -671,6 +692,29 @@ my.FlotGraph = Backbone.View.extend({
onEditorSubmit: function(e) {
var select = this.el.find('.editor-group select');
this._getEditorData();
+ this.redraw();
+ },
+
+ redraw: function() {
+ // There appear to be issues generating a Flot graph if either:
+
+ // * The relevant div that graph attaches to his hidden at the moment of creating the plot -- Flot will complain with
+ //
+ // Uncaught Invalid dimensions for plot, width = 0, height = 0
+ // * There is no data for the plot -- either same error or may have issues later with errors like 'non-existent node-value'
+ var areWeVisible = !jQuery.expr.filters.hidden(this.el[0]);
+ if (!this.plot && (!areWeVisible || this.model.currentDocuments.length == 0)) {
+ return
+ }
+ // create this.plot and cache it
+ if (!this.plot) {
+ // only lines for the present
+ options = {
+ id: 'line',
+ name: 'Line Chart'
+ };
+ this.plot = $.plot(this.$graph, this.createSeries(), options);
+ }
this.plot.setData(this.createSeries());
this.plot.resize();
this.plot.setupGrid();
@@ -686,16 +730,6 @@ my.FlotGraph = Backbone.View.extend({
this.chartConfig.group = this.el.find('.editor-group select').val();
},
- createPlot: function () {
- // only lines for the present
- options = {
- id: 'line',
- name: 'Line Chart'
- };
- this.plot = $.plot(this.$graph, this.createSeries(), options);
- return this;
- },
-
createSeries: function () {
var self = this;
var series = [];