diff --git a/src/view-flot-graph.js b/src/view-flot-graph.js
index afb8f061..ed3142f9 100644
--- a/src/view-flot-graph.js
+++ b/src/view-flot-graph.js
@@ -7,10 +7,10 @@ this.recline.View = this.recline.View || {};
// ## Graph view for a Dataset using Flot graphing library.
//
-// Initialization arguments:
+// Initialization arguments (in a hash in first parameter):
//
// * model: recline.Model.Dataset
-// * config: (optional) graph configuration hash of form:
+// * state: (optional) configuration hash of form:
//
// {
// group: {column name for x-axis},
@@ -86,7 +86,7 @@ my.FlotGraph = Backbone.View.extend({
'click .action-toggle-help': 'toggleHelp'
},
- initialize: function(options, config) {
+ initialize: function(options) {
var self = this;
this.el = $(this.el);
_.bindAll(this, 'render', 'redraw');
@@ -96,18 +96,14 @@ my.FlotGraph = Backbone.View.extend({
this.model.fields.bind('add', this.render);
this.model.currentDocuments.bind('add', this.redraw);
this.model.currentDocuments.bind('reset', this.redraw);
- var configFromHash = my.parseHashQueryString().graph;
- if (configFromHash) {
- configFromHash = JSON.parse(configFromHash);
- }
- this.chartConfig = _.extend({
+ var stateData = _.extend({
group: null,
series: [],
graphType: 'lines-and-points'
},
- configFromHash,
- config
- );
+ options.state
+ );
+ this.state = new recline.Model.ObjectState(stateData);
this.render();
},
@@ -129,13 +125,12 @@ my.FlotGraph = Backbone.View.extend({
var series = this.$series.map(function () {
return $(this).val();
});
- this.chartConfig.series = $.makeArray(series);
- this.chartConfig.group = this.el.find('.editor-group select').val();
- this.chartConfig.graphType = this.el.find('.editor-type select').val();
- // update navigation
- var qs = my.parseHashQueryString();
- qs.graph = JSON.stringify(this.chartConfig);
- my.setHashQueryString(qs);
+ var updatedState = {
+ series: $.makeArray(series),
+ group: this.el.find('.editor-group select').val(),
+ graphType: this.el.find('.editor-type select').val()
+ };
+ this.state.set(updatedState);
this.redraw();
},
@@ -151,7 +146,7 @@ my.FlotGraph = Backbone.View.extend({
return;
}
var series = this.createSeries();
- var options = this.getGraphOptions(this.chartConfig.graphType);
+ var options = this.getGraphOptions(this.state.attributes.graphType);
this.plot = $.plot(this.$graph, series, options);
this.setupTooltips();
// create this.plot and cache it
@@ -172,7 +167,7 @@ my.FlotGraph = Backbone.View.extend({
// 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);
+ var out = self.model.currentDocuments.models[val].get(self.state.attributes.group);
// if the value was in fact a number we want that not the
if (typeof(out) == 'number') {
return val;
@@ -255,14 +250,14 @@ my.FlotGraph = Backbone.View.extend({
var y = item.datapoint[1];
// convert back from 'index' value on x-axis (e.g. in cases where non-number values)
if (self.model.currentDocuments.models[x]) {
- x = self.model.currentDocuments.models[x].get(self.chartConfig.group);
+ x = self.model.currentDocuments.models[x].get(self.state.attributes.group);
} else {
x = x.toFixed(2);
}
y = y.toFixed(2);
var content = _.template('<%= group %> = <%= x %>, <%= series %> = <%= y %>', {
- group: self.chartConfig.group,
+ group: self.state.attributes.group,
x: x,
series: item.series.label,
y: y
@@ -280,25 +275,23 @@ my.FlotGraph = Backbone.View.extend({
createSeries: function () {
var self = this;
var series = [];
- if (this.chartConfig) {
- $.each(this.chartConfig.series, function (seriesIndex, field) {
- var points = [];
- $.each(self.model.currentDocuments.models, function (index, doc) {
- var x = doc.get(self.chartConfig.group);
- var y = doc.get(field);
- if (typeof x === 'string') {
- x = index;
- }
- // horizontal bar chart
- if (self.chartConfig.graphType == 'bars') {
- points.push([y, x]);
- } else {
- points.push([x, y]);
- }
- });
- series.push({data: points, label: field});
+ $.each(this.state.attributes.series, function (seriesIndex, field) {
+ var points = [];
+ $.each(self.model.currentDocuments.models, function (index, doc) {
+ var x = doc.get(self.state.attributes.group);
+ var y = doc.get(field);
+ if (typeof x === 'string') {
+ x = index;
+ }
+ // horizontal bar chart
+ if (self.state.attributes.graphType == 'bars') {
+ points.push([y, x]);
+ } else {
+ points.push([x, y]);
+ }
});
- }
+ series.push({data: points, label: field});
+ });
return series;
},
diff --git a/src/view.js b/src/view.js
index 5648af28..53b7a859 100644
--- a/src/view.js
+++ b/src/view.js
@@ -155,11 +155,7 @@ my.DataExplorer = Backbone.View.extend({
// note this.model and dataset returned are the same
this.model.fetch()
.done(function(dataset) {
- var queryState = my.parseHashQueryString().reclineQuery;
- if (queryState) {
- queryState = JSON.parse(queryState);
- }
- self.model.query(queryState);
+ self.model.query(self.state.get('query'));
})
.fail(function(error) {
my.notify(error.message, {category: 'error', persist: true});
@@ -238,16 +234,33 @@ my.DataExplorer = Backbone.View.extend({
_setupState: function(initialState) {
var self = this;
+ var qs = my.parseHashQueryString();
+ var query = qs.reclineQuery;
+ query = query ? JSON.parse(query) : self.model.queryState.toJSON();
+ // backwards compatability (now named view-graph but was named graph)
+ var graphState = qs['view-graph'] || qs.graph;
+ graphState = graphState ? JSON.parse(graphState) : {};
var stateData = _.extend({
readOnly: false,
- query: self.model.queryState.toJSON(),
+ query: query,
+ 'view-graph': graphState,
currentView: null
},
initialState);
this.state.set(stateData);
+
+ // now do updates based on state
if (this.state.get('readOnly')) {
this.setReadOnly();
}
+ _.each(this.pageViews, function(pageView) {
+ var viewId = 'view-' + pageView.id;
+ if (viewId in self.state.attributes) {
+ pageView.view.state.set(self.state.get(viewId));
+ }
+ });
+
+ // bind for changes state in associated objects
this.model.queryState.bind('change', function() {
self.state.set({queryState: self.model.queryState.toJSON()});
});
diff --git a/test/base.js b/test/base.js
index 2d8df709..30b2960b 100644
--- a/test/base.js
+++ b/test/base.js
@@ -14,3 +14,14 @@ var Fixture = {
}
};
+function assertPresent(selector, el) {
+ var found = el ? $(el).find(selector) : $(selector);
+ ok(found.length > 0);
+}
+
+function assertNotPresent(selector, el) {
+ var found = el ? $(el).find(selector) : $(selector);
+ ok(found.length > 0);
+ equal(found.length, 0);
+}
+
diff --git a/test/index.html b/test/index.html
index 8131c65c..82751d57 100644
--- a/test/index.html
+++ b/test/index.html
@@ -32,7 +32,9 @@
+
+
diff --git a/test/view-graph.test.js b/test/view-graph.test.js
new file mode 100644
index 00000000..122937f9
--- /dev/null
+++ b/test/view-graph.test.js
@@ -0,0 +1,13 @@
+module("View - FlotGraph");
+
+test('basics', function () {
+ var dataset = Fixture.getDataset();
+ var view = new recline.View.FlotGraph({
+ model: dataset
+ });
+ $('.fixtures').append(view.el);
+ equal(view.state.get('graphType'), 'lines-and-points');
+ // view will auto render ...
+ assertPresent('.editor', view.el);
+ view.remove();
+});
diff --git a/test/view-grid.test.js b/test/view-grid.test.js
index 19031458..8a723c89 100644
--- a/test/view-grid.test.js
+++ b/test/view-grid.test.js
@@ -2,16 +2,6 @@
module("View - DataGrid");
-function assertPresent(selector) {
- var found = $(selector);
- ok(found.length > 0);
-}
-
-function assertNotPresent(selector) {
- var found = $(selector);
- equal(found.length, 0);
-}
-
test('menu - hideColumn', function () {
var dataset = Fixture.getDataset();
var view = new recline.View.DataGrid({
diff --git a/test/view.test.js b/test/view.test.js
index afa2f943..6a898989 100644
--- a/test/view.test.js
+++ b/test/view.test.js
@@ -36,7 +36,10 @@ test('initialize state', function () {
var explorer = new recline.View.DataExplorer({
model: dataset,
state: {
- readOnly: true
+ readOnly: true,
+ 'view-grid': {
+ hiddenFields: ['x']
+ }
}
});
var state = explorer.getState();