Milimetric has uploaded a new change for review.
https://gerrit.wikimedia.org/r/156722
Change subject: Add visualizer to coordinate selectors and graphs
......................................................................
Add visualizer to coordinate selectors and graphs
Change-Id: I730fc02cece2d56ce165590d4cde777b2cb248be
---
M bower.json
M src/app/config.js
M src/app/data-converters/wikimetrics-timeseries.js
M src/app/require.config.js
M src/app/startup.js
D src/components/selection-visualizer/selection-visualizer.js
R src/components/wikimetrics-visualizer/wikimetrics-visualizer.html
A src/components/wikimetrics-visualizer/wikimetrics-visualizer.js
M test/SpecRunner.browser.js
A test/components/wikimetrics-visualizer.js
10 files changed, 140 insertions(+), 32 deletions(-)
git pull ssh://gerrit.wikimedia.org:29418/analytics/dashiki
refs/changes/22/156722/1
diff --git a/bower.json b/bower.json
index 2d77283..d13ff26 100644
--- a/bower.json
+++ b/bower.json
@@ -10,6 +10,7 @@
"topojson": "~1.6.18",
"jquery": "^2.1.1",
"moment": "^2.7.0",
- "URIjs": "~1.13.2"
+ "URIjs": "~1.13.2",
+ "knockout-projections": "~1.1.0-pre"
}
}
diff --git a/src/app/config.js b/src/app/config.js
index 2829edc..f56db4f 100644
--- a/src/app/config.js
+++ b/src/app/config.js
@@ -5,6 +5,12 @@
'use strict';
return {
- wikimetricsDomain : 'metrics-staging.wmflabs.org'
+ wikimetricsDomain : 'metrics-staging.wmflabs.org',
+ wikimetricsDefaultSubmetrics: {
+ NewlyRegistered: 'newly_registered',
+ RollingActiveEditor: 'rolling_active_editor',
+ PagesCreated: 'pages_created',
+ NamespaceEdits: 'edits'
+ },
};
});
diff --git a/src/app/data-converters/wikimetrics-timeseries.js
b/src/app/data-converters/wikimetrics-timeseries.js
index 126c2c3..9450263 100644
--- a/src/app/data-converters/wikimetrics-timeseries.js
+++ b/src/app/data-converters/wikimetrics-timeseries.js
@@ -2,7 +2,7 @@
* This module returns a method that knows how to translate json data from
* wikimetrics to the canonical timeseries format understood by dashiki
*/
-define(['moment'], function(moment) {
+define(['moment', 'config'], function(moment, config) {
/**
* Parameters
@@ -18,17 +18,11 @@
*/
return function (rawData){
var aggregate = 'Sum',
- submetrics = {
- NewlyRegistered: 'newly_registered',
- RollingActiveEditor: 'rolling_active_editor',
- PagesCreated: 'pages_created',
- NamespaceEdits: 'edits'
- },
normalized = [],
keys = Object.keys(rawData),
parameters = rawData.parameters,
metricName = parameters.Metric,
- submetric = submetrics[metricName],
+ submetric = config.wikimetricsDefaultSubmetrics[metricName],
i;
keys.splice(keys.indexOf('parameters'), 1);
diff --git a/src/app/require.config.js b/src/app/require.config.js
index c03253c..cf621b6 100644
--- a/src/app/require.config.js
+++ b/src/app/require.config.js
@@ -5,13 +5,14 @@
var require = {
baseUrl: '.',
paths: {
- 'jquery' : 'bower_modules/jquery/dist/jquery',
- 'knockout' : 'bower_modules/knockout/dist/knockout',
- 'text' : 'bower_modules/requirejs-text/text',
- 'd3' : 'bower_modules/d3/d3',
- 'vega' : 'bower_modules/vega/vega',
- 'topojson' : 'bower_modules/topojson/topojson',
- 'moment' : 'bower_modules/moment/moment',
+ 'jquery' : 'bower_modules/jquery/dist/jquery',
+ 'knockout' : 'bower_modules/knockout/dist/knockout',
+ 'knockout-projections' :
'bower_modules/knockout-projections/dist/knockout-projections',
+ 'text' : 'bower_modules/requirejs-text/text',
+ 'd3' : 'bower_modules/d3/d3',
+ 'vega' : 'bower_modules/vega/vega',
+ 'topojson' : 'bower_modules/topojson/topojson',
+ 'moment' : 'bower_modules/moment/moment',
// NOTE: if you want functions like uri.expand, you must include both
// URI and URITemplate like define(['uri/URI', 'uri/URITemplate'] ...
// because URITemplate modifies URI when it's parsed
diff --git a/src/app/startup.js b/src/app/startup.js
index 6a85bd7..5667d1e 100644
--- a/src/app/startup.js
+++ b/src/app/startup.js
@@ -4,10 +4,10 @@
// register components here like
ko.components.register('wikimetrics-layout', { require:
'components/wikimetrics-layout/wikimetrics-layout' });
+ ko.components.register('wikimetrics-visualizer', { require:
'components/wikimetrics-visualizer/wikimetrics-visualizer' });
ko.components.register('project-selector', { require:
'components/project-selector/project-selector' });
ko.components.register('metric-selector', { require:
'components/metric-selector/metric-selector' });
ko.components.register('time-selector', { require:
'components/time-selector/time-selector' });
- ko.components.register('selection-visualizer', { require:
'components/selection-visualizer/selection-visualizer' });
ko.components.register('vega-timeseries', { require:
'components/visualizers/vega-timeseries/vega-timeseries' });
// Start the application
diff --git a/src/components/selection-visualizer/selection-visualizer.js
b/src/components/selection-visualizer/selection-visualizer.js
deleted file mode 100644
index 3faa952..0000000
--- a/src/components/selection-visualizer/selection-visualizer.js
+++ /dev/null
@@ -1,14 +0,0 @@
-define(['knockout', 'text!./selection-visualizer.html'], function(ko,
templateMarkup) {
-
- 'use strict';
-
- function SelectionVisualizer() {
- var self = this;
- self.loading = ko.observable();
- }
-
- return {
- viewModel: SelectionVisualizer,
- template: templateMarkup
- };
-});
diff --git a/src/components/selection-visualizer/selection-visualizer.html
b/src/components/wikimetrics-visualizer/wikimetrics-visualizer.html
similarity index 100%
rename from src/components/selection-visualizer/selection-visualizer.html
rename to src/components/wikimetrics-visualizer/wikimetrics-visualizer.html
diff --git a/src/components/wikimetrics-visualizer/wikimetrics-visualizer.js
b/src/components/wikimetrics-visualizer/wikimetrics-visualizer.js
new file mode 100644
index 0000000..69984df
--- /dev/null
+++ b/src/components/wikimetrics-visualizer/wikimetrics-visualizer.js
@@ -0,0 +1,53 @@
+define(function(require) {
+ 'use strict';
+
+ var ko = require('knockout'),
+ $ = require('jquery'),
+ d3 = require('d3'),
+ templateMarkup = require('text!./wikimetrics-visualizer.html'),
+ api = require('app/apis/wikimetrics'),
+ converter =
require('app/data-converters/wikimetrics-timeseries');
+
+ require('knockout-projections');
+
+ function Dataset(metric, project) {
+ this.metric = metric;
+ this.project = project;
+ // this is an array but we don't need to react to single value changes
+ // NOTE: this could become an array to enable real-time refreshing
+ this.data = ko.observable([]);
+
+ this.load = ko.computed(function(){
+ var self = this,
+ m = self.metric(),
+ p = self.project;
+
+ // a change has triggered this to refresh, so first empty it out
+ self.data([]);
+ api.get(m, p).pipe(converter).done(function(converted) {
+ self.data(converted);
+ });
+ }, this);
+ }
+
+ function WikimetricsVisualizer(params) {
+ var self = this;
+ $.extend(self, params);
+ self.api = api;
+ self.converter = converter;
+
+ self.datasets = self.projects.map(function(project) {
+ return new Dataset(self.metric, project);
+ });
+ self.mergedData = ko.computed(function() {
+ return d3.merge(self.datasets.map(function(set) {
+ return set.data();
+ })());
+ }, self);
+ }
+
+ return {
+ viewModel: WikimetricsVisualizer,
+ template: templateMarkup
+ };
+});
diff --git a/test/SpecRunner.browser.js b/test/SpecRunner.browser.js
index 3faf2ee..c0e3a6c 100644
--- a/test/SpecRunner.browser.js
+++ b/test/SpecRunner.browser.js
@@ -2,6 +2,7 @@
// Reference your test modules here
var testModules = [
'components/wikimetrics-layout',
+ 'components/wikimetrics-visualizer',
'components/vega-timeseries',
'app/data-converters',
'app/apis',
diff --git a/test/components/wikimetrics-visualizer.js
b/test/components/wikimetrics-visualizer.js
new file mode 100644
index 0000000..08810d0
--- /dev/null
+++ b/test/components/wikimetrics-visualizer.js
@@ -0,0 +1,66 @@
+define(function (require){
+ var component =
require('components/wikimetrics-visualizer/wikimetrics-visualizer'),
+ $ = require('jquery'),
+ ko = require('knockout');
+
+ var WikimetricsVisualizer = component.viewModel;
+
+ describe('WikimetricsVisualizer view model', function() {
+
+ it('should transform selected projects and metrics into merged data',
function() {
+ var cohort = 'cohort',
+ v1 = 12,
+ v2 = 1,
+ metric = 'RollingActiveEditor',
+ selectedMetric = ko.observable(),
+ selectedProjects = ko.observableArray();
+
+ var visualizer = new WikimetricsVisualizer({
+ metric: selectedMetric,
+ projects: selectedProjects,
+ });
+
+ // make a mock promise and resolve it before making api.get return
it
+ var deferred = $.Deferred();
+ var response = {
+ 'result': {
+ 'Sum': {
+ 'rolling_active_editor': {
+ '2014-08-19 00:00:00': v2,
+ '2014-08-18 00:00:00': v1
+ }
+ }
+ },
+ 'parameters': {
+ 'Cohort': cohort,
+ 'Metric': metric
+ }
+ };
+ deferred.resolveWith(this, [response]);
+ sinon.stub(visualizer.api, 'get').returns(deferred.promise());
+
+ selectedMetric(metric);
+ selectedProjects.push(cohort);
+
+ expect(visualizer.mergedData().length).toEqual(2);
+ expect(visualizer.mergedData()[0].date).toEqual(new
Date('2014-08-18 00:00:00'));
+ expect(visualizer.mergedData()[0].label).toEqual(cohort);
+ expect(visualizer.mergedData()[0].value).toEqual(v1);
+ expect(visualizer.mergedData()[1].date).toEqual(new
Date('2014-08-19 00:00:00'));
+ expect(visualizer.mergedData()[1].label).toEqual(cohort);
+ expect(visualizer.mergedData()[1].value).toEqual(v2);
+
+ // change projects observable and make sure the merged data
reflects it
+ var anotherCohort = 'another-cohort';
+ response.parameters.Cohort = anotherCohort;
+ selectedProjects.push(anotherCohort);
+
+ expect(visualizer.mergedData()[2].date).toEqual(new
Date('2014-08-18 00:00:00'));
+ expect(visualizer.mergedData()[2].label).toEqual(anotherCohort);
+ expect(visualizer.mergedData()[2].value).toEqual(v1);
+ expect(visualizer.mergedData()[3].date).toEqual(new
Date('2014-08-19 00:00:00'));
+ expect(visualizer.mergedData()[3].label).toEqual(anotherCohort);
+ expect(visualizer.mergedData()[3].value).toEqual(v2);
+ });
+ });
+});
--
To view, visit https://gerrit.wikimedia.org/r/156722
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I730fc02cece2d56ce165590d4cde777b2cb248be
Gerrit-PatchSet: 1
Gerrit-Project: analytics/dashiki
Gerrit-Branch: master
Gerrit-Owner: Milimetric <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits