Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/site/app/webroot/js/stats/plots.js
diff options
context:
space:
mode:
Diffstat (limited to 'site/app/webroot/js/stats/plots.js')
-rwxr-xr-xsite/app/webroot/js/stats/plots.js195
1 files changed, 186 insertions, 9 deletions
diff --git a/site/app/webroot/js/stats/plots.js b/site/app/webroot/js/stats/plots.js
index 464b2c3..48f792e 100755
--- a/site/app/webroot/js/stats/plots.js
+++ b/site/app/webroot/js/stats/plots.js
@@ -7,11 +7,7 @@ var Plots = {
determinePlot: function() {
var selected = plotSelection.dropdowns['plot-selector'].selectedItem.value;
-
- // HACK: The group-by selector doesn't exist when the plot-selector is first
- // instantiated, but this method is called at that point.
- var group_by = (!plotSelection.dropdowns['group-by-selector']) ? null :
- plotSelection.dropdowns['group-by-selector'].selectedItem.value;
+ var group_by = plotSelection.getGroupByValue();
// Remove current plot selections
plotSelection.removeAll();
@@ -156,11 +152,13 @@ var Plots = {
var plotType = plotSelection.dropdowns['plot-selector'].selectedItem.value;
if (plotType == 'summary') {
+ $('#weeks-legend').hide();
$('#summary-legend').show();
$('#summary-options').show();
$('#group-by-selector').hide();
}
else {
+ $('#weeks-legend').hide();
$('#summary-legend').hide();
$('#summary-options').hide();
$('#group-by-selector').show();
@@ -231,9 +229,22 @@ var Plots = {
// If there's a value for the group-by selector, add it as a
// parameter to the CSV URL to invoke it server-side.
- var group_by = plotSelection.dropdowns['group-by-selector'].selectedItem.value;
+ var group_by = plotSelection.getGroupByValue();
+
+ if ('week_over_week' == group_by) {
+ if ('updatepings' == type || 'downloads' == type) {
+ $('#weeks-legend').show();
+ return this.plotWeekOverWeek();
+ } else {
+ // HACK: Until I can figure out how to disable the Compare
+ // by: Week option for views not supported for it
+ group_by = 'week';
+ }
+ }
+
+ $('#weeks-legend').hide();
if (group_by) Plots.currentCSV += '?group_by=' + group_by;
-
+
this.dataSources = {
'count': new Timeplot.DefaultEventSource(),
'events-firefox': new Timeplot.DefaultEventSource(),
@@ -304,7 +315,7 @@ var Plots = {
this.plot();
},
-
+
plot: function() {
var timeGeometry = new Timeplot.DefaultTimeGeometry(this.timeGeometry);
var valueGeometry = new Timeplot.DefaultValueGeometry(this.valueGeometry);
@@ -328,6 +339,172 @@ var Plots = {
Plots.timeplot.loadXML(statsURL + 'xml/events/firefox', this.dataSources['events-firefox']);
Plots.timeplot.loadXML(statsURL + 'xml/events/addon/' + addonID, this.dataSources['events-addon']);
},
+
+ /**
+ * Construct a plot consisting of 2 different weeks' data overlaid on
+ * the same graph.
+ */
+ plotWeekOverWeek: function() {
+
+ var type = plotSelection.dropdowns['plot-selector'].selectedItem.value;
+ Plots.currentCSV = statsURL + 'csv/' + addonID + '/' + type;
+
+ this.dataSources = {
+ 'count': new Timeplot.DefaultEventSource(),
+ };
+
+ PlotsTables.addListeners('week_over_week', this.dataSources);
+
+ var date_parser = Timeline.NativeDateUnit.getParser('iso8601');
+
+ // Collect Mondays from the set of available dates.
+ var available_dates = plotSelection
+ .summary[ (type=='downloads') ? 'downloads' : 'updatepings' ]
+ .availableDates;
+ var dates = [];
+ var DAY_MONDAY = 1;
+ for (idx in available_dates) {
+ // The available dates data is a little weird - it's an object
+ // with numerical properties, instead of an array.
+ if (available_dates.hasOwnProperty(idx)) {
+ var date = date_parser(available_dates[idx]);
+ if (date.getDay() == DAY_MONDAY)
+ dates.push(available_dates[idx]);
+ }
+ }
+
+ // Set up empty ranges set.
+ var ranges = {
+ week1: { min: '', max: '' },
+ week2: { min: '', max: '' }
+ };
+
+ var WEEK = ( 1000 * 60 * 60 * 24 * 7 );
+
+ if ( $('#weeks-legend .template').length ) {
+
+ // The date selection dropdowns still contain unpopulated
+ // templates, so set up the defaults and populate the dropdowns
+
+ ranges['week2']['min'] = date_parser(dates[dates.length - 1]);
+ ranges['week2']['max'] = new Date(ranges['week2']['min'].getTime() + WEEK);
+ ranges['week1']['min'] = date_parser(dates[dates.length - 2]);
+ ranges['week1']['max'] = new Date(ranges['week1']['min'].getTime() + WEEK);
+
+ var weeks = ['week1', 'week2'];
+ for (var i=0, week; week=weeks[i]; i++) {
+
+ // Convert the selection template into a concrete element
+ var tmpl = $('#'+week+'-selection select.template');
+ if (!tmpl.length) continue;
+ tmpl.remove().removeClass('template');
+
+ // Convert the current min date to string for comparison.
+ var min_str = ranges[week]['min'].strftime('%Y-%m-%d');
+
+ // Now populate the selection element with options cloned
+ // and populated from available dates.
+ var t_opt = tmpl.find('option').remove();
+ for (var j=0,date; date=dates[j]; j++) {
+ var opt = t_opt.clone();
+
+ var dp = date.split('-');
+ opt.text([dp[1], dp[2], dp[0]].join('/'))
+ .attr('value', date)
+ .appendTo(tmpl);
+
+ if (date == min_str)
+ opt.attr('selected', 'selected');
+ }
+
+ // Finally inject the populated selector into the DOM and
+ // wire up an onChange handler to reload the plot.
+ tmpl.appendTo('#'+week+'-selection')
+ .change(function() { Plots.determinePlot() });
+ }
+
+ } else {
+
+ // The date selection dropdowns are populated, so set ranges
+ // from the selected values.
+
+ var weeks = ['week1', 'week2'];
+ for (var i=0, week; week=weeks[i]; i++) {
+ var opt = $('#'+week+'-selection select')[0];
+ var date = opt.options[opt.selectedIndex].value;
+ ranges[week]['min'] = date_parser(date);
+ ranges[week]['max'] = new Date(ranges[week]['min'].getTime() + WEEK);
+ }
+
+ }
+
+ // Assemble the time geometries from the selected time ranges.
+ this.timeGeometries = {
+ 'week1': {
+ 'min': ranges['week1']['min'],
+ 'max': ranges['week1']['max'],
+ 'gridColor': '#CC6666',
+ 'axisLabelsPlacement': 'bottom'
+ },
+ 'week2': {
+ 'min': ranges['week2']['min'],
+ 'max': ranges['week2']['max'],
+ 'gridColor': '#6666CC',
+ 'axisLabelsPlacement': 'top'
+ }
+ };
+
+ // Both time ranges share the same value geometry
+ this.valueGeometry = {
+ 'gridColor': '#000000',
+ 'axisLabelsPlacement': 'left',
+ 'min': 0
+ };
+
+ // Construct the plot info structures for each of the overlaid sets.
+ Plots.newTimeplot();
+ Plots.timeplot = Timeplot.create(document.getElementById(Plots.timeplot_id), [
+ Timeplot.createPlotInfo({
+ 'id': 'week1-plot',
+ 'dataSource':
+ new Timeplot.ColumnSource(this.dataSources['count'], 1),
+ 'timeGeometry':
+ new Timeplot.DefaultTimeGeometry(this.timeGeometries['week1']),
+ 'valueGeometry':
+ new Timeplot.DefaultValueGeometry(this.valueGeometry),
+ 'showValues': true,
+ 'dotColor': '#CC6666',
+ 'dotRadius': 3.0,
+ 'lineColor': '#CC6666',
+ 'lineWidth': 3.0,
+ 'fillColor': false
+ }),
+ Timeplot.createPlotInfo({
+ 'id': 'week2-plot',
+ 'dataSource':
+ new Timeplot.ColumnSource(this.dataSources['count'], 1),
+ 'timeGeometry':
+ new Timeplot.DefaultTimeGeometry(this.timeGeometries['week2']),
+ 'valueGeometry':
+ new Timeplot.DefaultValueGeometry(this.valueGeometry),
+ 'showValues': true,
+ 'dotColor': '#6666CC',
+ 'dotRadius': 3.0,
+ 'lineColor': '#6666CC',
+ 'lineWidth': 3.0,
+ 'fillColor': false
+ })
+ ]);
+
+ // Finally, queue up a load for the plot data.
+ Plots.timeplot.loadText(
+ Plots.currentCSV,
+ ",",
+ this.dataSources['count'],
+ parseFields
+ );
+
+ },
addPlot: function(plotName, column, color) {
if (plotName in this.plotInfo)
@@ -397,4 +574,4 @@ function parseFields(data) {
}
return data;
-} \ No newline at end of file
+}