From 1df82c3c3d8f53518b9ca35c6b5f9d93a768a607 Mon Sep 17 00:00:00 2001 From: Rufus Pollock Date: Wed, 25 Apr 2012 23:23:13 +0100 Subject: [PATCH] [#75,view/graph][s]: if type of x-axis field is date make flot graph treat it as a datetime - fixes #75. * TODO / problems: have hard-coded ticks to be yyyy-MMM but that may not work well for all time series (may need to guess this from the resolution of the data or allow user to configure) --- src/view-graph.js | 45 +++++++++++++++++++++++++++++++---------- test/base.js | 14 +++++++------ test/view-graph.test.js | 15 ++++++++++++++ 3 files changed, 57 insertions(+), 17 deletions(-) diff --git a/src/view-graph.js b/src/view-graph.js index c3116c16..d9fe7873 100644 --- a/src/view-graph.js +++ b/src/view-graph.js @@ -198,10 +198,20 @@ my.Graph = Backbone.View.extend({ // } }, + // ### getGraphOptions + // + // Get options for Flot Graph + // // needs to be function as can depend on state + // + // @param typeId graphType id (lines, lines-and-points etc) getGraphOptions: function(typeId) { var self = this; // special tickformatter to show labels rather than numbers + // TODO: we should really use tickFormatter and 1 interval ticks if (and + // only if) x-axis values are non-numeric + // However, that is non-trivial to work out from a dataset (datasets may + // have no field type info). Thus at present we only do this for bars. var tickFormatter = function (val) { if (self.model.currentDocuments.models[val]) { var out = self.model.currentDocuments.models[val].get(self.state.attributes.group); @@ -214,20 +224,25 @@ my.Graph = Backbone.View.extend({ } return val; }; - // TODO: we should really use tickFormatter and 1 interval ticks if (and - // only if) x-axis values are non-numeric - // However, that is non-trivial to work out from a dataset (datasets may - // have no field type info). Thus at present we only do this for bars. - var options = { + + var xaxis = {}; + // check for time series on x-axis + if (this.model.fields.get(this.state.get('group')).get('type') === 'date') { + xaxis.mode = 'time'; + xaxis.timeformat = '%y-%b'; + } + var optionsPerGraphType = { lines: { - series: { - lines: { show: true } - } + series: { + lines: { show: true } + }, + xaxis: xaxis }, points: { series: { points: { show: true } }, + xaxis: xaxis, grid: { hoverable: true, clickable: true } }, 'lines-and-points': { @@ -235,6 +250,7 @@ my.Graph = Backbone.View.extend({ points: { show: true }, lines: { show: true } }, + xaxis: xaxis, grid: { hoverable: true, clickable: true } }, bars: { @@ -258,7 +274,7 @@ my.Graph = Backbone.View.extend({ } } }; - return options[typeId]; + return optionsPerGraphType[typeId]; }, setupTooltips: function() { @@ -315,8 +331,15 @@ my.Graph = Backbone.View.extend({ _.each(this.state.attributes.series, function(field) { var points = []; _.each(self.model.currentDocuments.models, function(doc, index) { - var x = doc.get(self.state.attributes.group); - var y = doc.get(field); + var xfield = self.model.fields.get(self.state.attributes.group); + var x = doc.getFieldValue(xfield); + // time series + var isDateTime = xfield.get('type') === 'date'; + if (isDateTime) { + x = new Date(x); + } + var yfield = self.model.fields.get(field); + var y = doc.getFieldValue(yfield); if (typeof x === 'string') { x = index; } diff --git a/test/base.js b/test/base.js index 729e1178..35985fdd 100644 --- a/test/base.js +++ b/test/base.js @@ -1,6 +1,8 @@ var Fixture = { getDataset: function() { var fields = [ + {id: 'id'}, + {id: 'date', type: 'date'}, {id: 'x'}, {id: 'y'}, {id: 'z'}, @@ -10,12 +12,12 @@ var Fixture = { {id: 'lon'} ]; var documents = [ - {id: 0, x: 1, y: 2, z: 3, country: 'DE', label: 'first', lat:52.56, lon:13.40}, - {id: 1, x: 2, y: 4, z: 6, country: 'UK', label: 'second', lat:54.97, lon:-1.60}, - {id: 2, x: 3, y: 6, z: 9, country: 'US', label: 'third', lat:40.00, lon:-75.5}, - {id: 3, x: 4, y: 8, z: 12, country: 'UK', label: 'fourth', lat:57.27, lon:-6.20}, - {id: 4, x: 5, y: 10, z: 15, country: 'UK', label: 'fifth', lat:51.58, lon:0}, - {id: 5, x: 6, y: 12, z: 18, country: 'DE', label: 'sixth', lat:51.04, lon:7.9} + {id: 0, date: '2011-01-01', x: 1, y: 2, z: 3, country: 'DE', label: 'first', lat:52.56, lon:13.40}, + {id: 1, date: '2011-02-02', x: 2, y: 4, z: 6, country: 'UK', label: 'second', lat:54.97, lon:-1.60}, + {id: 2, date: '2011-03-03', x: 3, y: 6, z: 9, country: 'US', label: 'third', lat:40.00, lon:-75.5}, + {id: 3, date: '2011-04-04', x: 4, y: 8, z: 12, country: 'UK', label: 'fourth', lat:57.27, lon:-6.20}, + {id: 4, date: '2011-05-04', x: 5, y: 10, z: 15, country: 'UK', label: 'fifth', lat:51.58, lon:0}, + {id: 5, date: '2011-06-02', x: 6, y: 12, z: 18, country: 'DE', label: 'sixth', lat:51.04, lon:7.9} ]; var dataset = recline.Backend.createDataset(documents, fields); return dataset; diff --git a/test/view-graph.test.js b/test/view-graph.test.js index 651dd157..3f65611a 100644 --- a/test/view-graph.test.js +++ b/test/view-graph.test.js @@ -34,5 +34,20 @@ test('initialize', function () { }); deepEqual(out, ['y', 'z']); + view.remove(); +}); + +test('dates in graph view', function () { + var dataset = Fixture.getDataset(); + var view = new recline.View.Graph({ + model: dataset, + state: { + 'graphType': 'lines', + 'group': 'date', + 'series': ['y', 'z'] + } + }); + $('.fixtures').append(view.el); + // view.remove(); });