diff --git a/src/mmw/js/src/compare/controllers.js b/src/mmw/js/src/compare/controllers.js
index cecf93b01..19fbf00e2 100644
--- a/src/mmw/js/src/compare/controllers.js
+++ b/src/mmw/js/src/compare/controllers.js
@@ -5,15 +5,9 @@ var _ = require('lodash'),
router = require('../router').router,
views = require('./views'),
modelingModels = require('../modeling/models.js'),
- modelingControls = require('../modeling/controls'),
- coreUtils = require('../core/utils'),
- synchronizer = modelingControls.PrecipitationSynchronizer;
+ coreUtils = require('../core/utils');
var CompareController = {
- comparePrepare: function() {
- synchronizer.on();
- },
-
compare: function(projectId) {
var first = null,
aoi_census = null;
@@ -53,7 +47,6 @@ var CompareController = {
},
compareCleanUp: function() {
- synchronizer.off();
App.user.off('change:guest', saveAfterLogin);
App.origProject.off('change:id', updateUrl);
diff --git a/src/mmw/js/src/compare/models.js b/src/mmw/js/src/compare/models.js
index c8d675cc9..33ff1b47c 100644
--- a/src/mmw/js/src/compare/models.js
+++ b/src/mmw/js/src/compare/models.js
@@ -1,6 +1,7 @@
"use strict";
-var Backbone = require('../../shim/backbone');
+var Backbone = require('../../shim/backbone'),
+ ControlsCollection = require('../modeling/models').ModelPackageControlsCollection;
var CHART = 'chart',
TABLE = 'table';
@@ -39,7 +40,9 @@ var TabsCollection = Backbone.Collection.extend({
var WindowModel = Backbone.Model.extend({
defaults: {
+ controls: null, // ModelPackageControlsCollection
mode: TABLE, // or CHART
+ scenarios: null, // ScenariosCollection
tabs: null, // TabsCollection
},
@@ -47,8 +50,15 @@ var WindowModel = Backbone.Model.extend({
Backbone.Model.prototype.initialize.apply(this, arguments);
this.set({
+ controls: new ControlsCollection(attrs.controls),
tabs: new TabsCollection(attrs.tabs),
});
+ },
+
+ addOrReplaceInput: function(input) {
+ this.get('scenarios').each(function(scenario) {
+ scenario.addOrReplaceInput(input);
+ });
}
});
diff --git a/src/mmw/js/src/compare/templates/compareInputs.html b/src/mmw/js/src/compare/templates/compareInputs.html
index b5f802695..5d80f11a2 100644
--- a/src/mmw/js/src/compare/templates/compareInputs.html
+++ b/src/mmw/js/src/compare/templates/compareInputs.html
@@ -1,4 +1,4 @@
-
Precipitation -----|----
+
diff --git a/src/mmw/js/src/compare/views.js b/src/mmw/js/src/compare/views.js
index 54ce4ebf8..a21159630 100644
--- a/src/mmw/js/src/compare/views.js
+++ b/src/mmw/js/src/compare/views.js
@@ -9,7 +9,7 @@ var _ = require('lodash'),
models = require('./models'),
modelingModels = require('../modeling/models'),
modelingViews = require('../modeling/views'),
- modelingControls = require('../modeling/controls'),
+ PrecipitationView = require('../modeling/controls').PrecipitationView,
modConfigUtils = require('../modeling/modificationConfigUtils'),
compareWindowTmpl = require('./templates/compareWindow.html'),
compareWindow2Tmpl = require('./templates/compareWindow2.html'),
@@ -20,8 +20,7 @@ var _ = require('lodash'),
compareScenariosTmpl = require('./templates/compareScenarios.html'),
compareScenarioTmpl = require('./templates/compareScenario.html'),
compareModelingTmpl = require('./templates/compareModeling.html'),
- compareModificationsTmpl = require('./templates/compareModifications.html'),
- synchronizer = modelingControls.PrecipitationSynchronizer;
+ compareModificationsTmpl = require('./templates/compareModifications.html');
var CompareWindow2 = Marionette.LayoutView.extend({
template: compareWindow2Tmpl,
@@ -55,7 +54,7 @@ var CompareWindow2 = Marionette.LayoutView.extend({
model: this.model,
}));
this.scenariosRegion.show(new ScenariosRowView({
- collection: App.currentProject.get('scenarios'),
+ collection: this.model.get('scenarios'),
}));
this.showSectionsView();
@@ -112,7 +111,7 @@ var TabPanelsView = Marionette.CollectionView.extend({
childView: TabPanelView,
});
-var InputsView = Marionette.ItemView.extend({
+var InputsView = Marionette.LayoutView.extend({
template: compareInputsTmpl,
ui: {
@@ -125,6 +124,26 @@ var InputsView = Marionette.ItemView.extend({
'click @ui.tableButton': 'setTableView',
},
+ regions: {
+ precipitationRegion: '.compare-precipitation',
+ },
+
+ onShow: function() {
+ var addOrReplaceInput = _.bind(this.model.addOrReplaceInput, this.model),
+ controlModel = this.model.get('scenarios')
+ .findWhere({ active: true })
+ .get('inputs')
+ .findWhere({ name: 'precipitation' }),
+ precipitationModel = this.model.get('controls')
+ .findWhere({ name: 'precipitation' });
+
+ this.precipitationRegion.show(new PrecipitationView({
+ model: precipitationModel,
+ controlModel: controlModel,
+ addOrReplaceInput: addOrReplaceInput,
+ }));
+ },
+
setChartView: function() {
this.model.set({ mode: models.constants.CHART });
},
@@ -225,7 +244,6 @@ var CompareWindow = Marionette.LayoutView.extend({
model: this.model,
collection: this.model.get('scenarios')
}));
- synchronizer.sync();
}
});
@@ -502,15 +520,80 @@ function getGwlfeTabs(scenarios) {
];
}
+function copyScenario(scenario, aoi_census) {
+ var newScenario = new modelingModels.ScenarioModel({}),
+ fetchResults = _.bind(newScenario.fetchResults, newScenario),
+ debouncedFetchResults = _.debounce(fetchResults, 500);
+
+ newScenario.set({
+ name: scenario.get('name'),
+ is_current_conditions: scenario.get('is_current_conditions'),
+ aoi_census: aoi_census,
+ modifications: scenario.get('modifications'),
+ modification_hash: scenario.get('modification_hash'),
+ modification_censuses: scenario.get('modification_censuses'),
+ results: new modelingModels.ResultCollection(scenario.get('results').toJSON()),
+ inputs: new modelingModels.ModificationsCollection(scenario.get('inputs').toJSON()),
+ inputmod_hash: scenario.get('inputmod_hash'),
+ allow_save: false,
+ active: scenario.get('active'),
+ });
+
+ newScenario.get('inputs').on('add', debouncedFetchResults);
+
+ return newScenario;
+}
+
+
+// Makes a sandboxed copy of project scenarios which can be safely
+// edited and experimented in the Compare Window, and discarded on close.
+function getCompareScenarios(isTr55) {
+ var trueScenarios = App.currentProject.get('scenarios'),
+ tempScenarios = new modelingModels.ScenariosCollection(),
+ ccScenario = trueScenarios.findWhere({ is_current_conditions: true }),
+ aoi_census = ccScenario.get('aoi_census');
+
+ if (isTr55) {
+ // Add 100% Forest Cover scenario
+ var forestScenario = copyScenario(ccScenario, aoi_census);
+
+ forestScenario.set({
+ name: '100% Forest Cover',
+ is_current_conditions: false,
+ is_pre_columbian: true,
+ });
+
+ tempScenarios.add(forestScenario);
+ }
+
+ trueScenarios.forEach(function(scenario) {
+ tempScenarios.add(copyScenario(scenario, aoi_census));
+ });
+
+ return tempScenarios;
+}
+
function showCompare() {
var model_package = App.currentProject.get('model_package'),
- scenarios = App.currentProject.get('scenarios'),
- tabs = model_package === modelingModels.TR55_PACKAGE ?
- getTr55Tabs(scenarios) : getGwlfeTabs(scenarios),
+ isTr55 = model_package === modelingModels.TR55_PACKAGE,
+ scenarios = getCompareScenarios(isTr55),
+ tabs = isTr55 ? getTr55Tabs(scenarios) : getGwlfeTabs(scenarios),
+ controls = isTr55 ? [{ name: 'precipitation' }] : [],
compareModel = new models.WindowModel({
+ controls: controls,
tabs: tabs,
});
+ compareModel.set({ scenarios: scenarios });
+
+ if (isTr55) {
+ // Set compare model to have same precipitation as active scenario
+ compareModel.addOrReplaceInput(
+ scenarios.findWhere({ active: true })
+ .get('inputs')
+ .findWhere({ name: 'precipitation' }));
+ }
+
App.rootView.compareRegion.show(new CompareWindow2({
model: compareModel,
}));
diff --git a/src/mmw/js/src/modeling/controls.js b/src/mmw/js/src/modeling/controls.js
index c5a6817fa..a77dfc431 100644
--- a/src/mmw/js/src/modeling/controls.js
+++ b/src/mmw/js/src/modeling/controls.js
@@ -444,72 +444,6 @@ var GwlfeConservationPracticeView = ModificationsView.extend({
}
});
-var PrecipitationSynchronizer = (function() {
- var isEnabled = false,
- precipViews = [];
-
- // Add a view to the list of views to be kept syncrhonized
- function add(precipView) {
- if (isEnabled) {
- precipViews.push(precipView);
- }
- }
-
- // Remove a view from the list
- function remove(precipView) {
- if (isEnabled) {
- precipViews = _.without(precipViews, precipView);
- }
- }
-
- // Turn synchronization on
- function on() {
- precipViews = [];
- isEnabled = true;
- }
-
- // Turn synchronization off
- function off() {
- isEnabled = false;
- precipViews = [];
- }
-
- // Synchronize the group to the given slider
- function syncTo(precipView) {
- if (isEnabled) {
- var value = precipView.ui.slider.val();
-
- isEnabled = false;
-
- precipViews.forEach(function(otherPrecipView) {
- var otherValue = otherPrecipView.ui.slider.val();
- if (otherValue !== value) {
- otherPrecipView.ui.slider.val(value);
- otherPrecipView.onSliderChanged();
- }
- });
-
- isEnabled = true;
- }
- }
-
- // Synchronize the group to the first slider
- function sync() {
- if (precipViews.length > 0) {
- syncTo(precipViews[0]);
- }
- }
-
- return {
- add: add,
- remove: remove,
- on: on,
- off: off,
- sync: sync,
- syncTo: syncTo
- };
-})();
-
var PrecipitationView = ControlView.extend({
template: precipitationTmpl,
@@ -554,19 +488,9 @@ var PrecipitationView = ControlView.extend({
this.ui.slider.attr('value', value);
this.ui.displayValue.text(this.getDisplayValue(value));
- PrecipitationSynchronizer.syncTo(this);
-
this.addOrReplaceInput(modification);
},
- onAttach: function() {
- PrecipitationSynchronizer.add(this);
- },
-
- onBeforeDestroy: function() {
- PrecipitationSynchronizer.remove(this);
- },
-
onRender: function() {
var model = this.controlModel,
value = model && model.get('value') || 0;
@@ -600,5 +524,4 @@ module.exports = {
GwlfeConservationPracticeView: GwlfeConservationPracticeView,
PrecipitationView: PrecipitationView,
getControlView: getControlView,
- PrecipitationSynchronizer: PrecipitationSynchronizer
};
diff --git a/src/mmw/sass/pages/_compare.scss b/src/mmw/sass/pages/_compare.scss
index a47c96c6b..dde808274 100644
--- a/src/mmw/sass/pages/_compare.scss
+++ b/src/mmw/sass/pages/_compare.scss
@@ -537,6 +537,9 @@ $compare-chart-table-height: calc(100vh - #{$height-lg} - #{$compare-footer-heig
&.compare-precipitation {
margin-right: 20px;
+ label {
+ font-size: 12px;
+ }
}
}
}