Skip to content

Commit

Permalink
Merge pull request #2195 from WikiWatershed/feature/jmt/compare-navig…
Browse files Browse the repository at this point in the history
…ation

Implement Compare View Navigation

Connects #2075
  • Loading branch information
rajadain committed Aug 30, 2017
2 parents fc39a91 + a77a473 commit a22aef0
Show file tree
Hide file tree
Showing 5 changed files with 156 additions and 13 deletions.
9 changes: 8 additions & 1 deletion src/mmw/js/src/compare/models.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ var _ = require('lodash'),
ControlsCollection = require('../modeling/models').ModelPackageControlsCollection;

var CHART = 'chart',
TABLE = 'table';
TABLE = 'table',
MIN_VISIBLE_SCENARIOS = 3,
CHART_AXIS_WIDTH = 82,
COMPARE_COLUMN_WIDTH = 134;

var ChartRowModel = Backbone.Model.extend({
defaults: {
Expand Down Expand Up @@ -204,6 +207,7 @@ var WindowModel = Backbone.Model.extend({
mode: CHART, // or TABLE
scenarios: null, // ScenariosCollection
tabs: null, // TabsCollection
visibleScenarioIndex: 0, // Index of the first visible scenario
},

addOrReplaceInput: function(input) {
Expand All @@ -225,5 +229,8 @@ module.exports = {
constants: {
CHART: CHART,
TABLE: TABLE,
MIN_VISIBLE_SCENARIOS: MIN_VISIBLE_SCENARIOS,
CHART_AXIS_WIDTH: CHART_AXIS_WIDTH,
COMPARE_COLUMN_WIDTH: COMPARE_COLUMN_WIDTH,
},
};
4 changes: 2 additions & 2 deletions src/mmw/js/src/compare/templates/compareWindow2.html
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ <h2>Scenarios</h2>
<div id="compare-title-row" class="compare-scenario-row-content-container">
</div>
<div class="compare-scenario-buttons">
<button class="visible">
<button class="visible btn-prev-scenario">
<i class="fa fa-arrow-left"></i>
</button>
<button class="visible active">
<button class="visible btn-next-scenario">
<i class="fa fa-arrow-right"></i>
</button>
</div>
Expand Down
133 changes: 130 additions & 3 deletions src/mmw/js/src/compare/views.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,19 @@ var CompareWindow2 = modalViews.ModalBaseView.extend({

ui: {
closeButton: '.compare-close > button',
nextButton: '.compare-scenario-buttons > .btn-next-scenario',
prevButton: '.compare-scenario-buttons > .btn-prev-scenario',
},

events: _.defaults({
'click @ui.closeButton': 'hide',
'click @ui.nextButton' : 'nextScenario',
'click @ui.prevButton' : 'prevScenario',
}, modalViews.ModalBaseView.prototype.events),

modelEvents: {
'change:mode': 'showSectionsView',
'change:visibleScenarioIndex': 'highlightButtons',
},

regions: {
Expand All @@ -52,6 +57,26 @@ var CompareWindow2 = modalViews.ModalBaseView.extend({
sectionsRegion: '.compare-sections',
},

highlightButtons: function() {
var i = this.model.get('visibleScenarioIndex'),
total = this.model.get('scenarios').length,
minScenarios = models.constants.MIN_VISIBLE_SCENARIOS,
prevButton = this.ui.prevButton,
nextButton = this.ui.nextButton;

if (i < 1) {
prevButton.removeClass('active');
} else {
prevButton.addClass('active');
}

if (i + minScenarios >= total) {
nextButton.removeClass('active');
} else {
nextButton.addClass('active');
}
},

onShow: function() {
var tabPanelsView = new TabPanelsView({
collection: this.model.get('tabs'),
Expand All @@ -65,21 +90,25 @@ var CompareWindow2 = modalViews.ModalBaseView.extend({
model: this.model,
}));
this.scenariosRegion.show(new ScenariosRowView({
model: this.model,
collection: this.model.get('scenarios'),
}));

showSectionsView();
this.highlightButtons();
},

showSectionsView: function() {
if (this.model.get('mode') === models.constants.CHART) {
this.sectionsRegion.show(new ChartView({
model: this.model,
collection: this.model.get('tabs')
.findWhere({ active: true })
.get('charts'),
}));
} else {
this.sectionsRegion.show(new TableView({
model: this.model,
collection: this.model.get('tabs')
.findWhere({ active: true })
.get('table'),
Expand All @@ -90,6 +119,24 @@ var CompareWindow2 = modalViews.ModalBaseView.extend({
onModalHidden: function() {
App.rootView.compareRegion.empty();
},

nextScenario: function() {
var visibleScenarioIndex = this.model.get('visibleScenarioIndex'),
last = Math.max(0, this.model.get('scenarios').length -
models.constants.MIN_VISIBLE_SCENARIOS);

this.model.set({
visibleScenarioIndex: Math.min(++visibleScenarioIndex, last)
});
},

prevScenario: function() {
var visibleScenarioIndex = this.model.get('visibleScenarioIndex');

this.model.set({
visibleScenarioIndex: Math.max(--visibleScenarioIndex, 0)
});
},
});

var TabPanelView = Marionette.ItemView.extend({
Expand Down Expand Up @@ -255,6 +302,20 @@ var ScenarioItemView = Marionette.ItemView.extend({
var ScenariosRowView = Marionette.CollectionView.extend({
className: 'compare-scenario-row-content',
childView: ScenarioItemView,

modelEvents: {
'change:visibleScenarioIndex': 'slide',
},

slide: function() {
var i = this.model.get('visibleScenarioIndex'),
width = models.constants.COMPARE_COLUMN_WIDTH,
marginLeft = -i * width;

this.$el.css({
'margin-left': marginLeft + 'px',
});
}
});

var ChartRowView = Marionette.ItemView.extend({
Expand All @@ -271,7 +332,8 @@ var ChartRowView = Marionette.ItemView.extend({
},

renderChart: function() {
var chartDiv = this.model.get('chartDiv'),
var self = this,
chartDiv = this.model.get('chartDiv'),
chartEl = document.getElementById(chartDiv),
name = this.model.get('name'),
label = this.model.get('unitLabel') +
Expand All @@ -298,15 +360,60 @@ var ChartRowView = Marionette.ItemView.extend({
y: value,
};
}),
}];
}],
onRenderComplete = function() {
self.triggerMethod('chart:rendered');
};

$(chartEl.parentNode).css({ 'width': ((_.size(this.model.get('values')) * models.constants.COMPARE_COLUMN_WIDTH + models.constants.CHART_AXIS_WIDTH) + 'px') });
chart.renderCompareMultibarChart(
chartEl, name, label, colors, stacked, yMax, data);
chartEl, name, label, colors, stacked, yMax, data,
models.constants.COMPARE_COLUMN_WIDTH, models.constants.CHART_AXIS_WIDTH, onRenderComplete);
},
});

var ChartView = Marionette.CollectionView.extend({
childView: ChartRowView,

modelEvents: {
'change:visibleScenarioIndex': 'slide',
},

onRender: function() {
// To initialize chart correctly when switching between tabs
this.slide();
},

onChildviewChartRendered: function() {
// Update chart status after it is rendered
this.slide();
},

slide: function() {
var i = this.model.get('visibleScenarioIndex'),
width = models.constants.COMPARE_COLUMN_WIDTH,
marginLeft = -i * width;

// Slide charts
this.$('.compare-scenario-row-content').css({
'margin-left': marginLeft + 'px',
});

// Slide axis
this.$('.nvd3.nv-wrap.nv-axis').css({
'transform': 'translate(' + (-marginLeft) + 'px)',
});

// Show charts from visibleScenarioIndex
this.$('.nv-group > rect:nth-child(n + ' + (i+1) + ')').css({
'opacity': 1,
});

// Hide charts up to visibleScenarioIndex
this.$('.nv-group > rect:nth-child(-n + ' + i + ')').css({
'opacity': 0,
});
},
});

var TableRowView = Marionette.ItemView.extend({
Expand All @@ -319,6 +426,26 @@ var TableView = Marionette.CollectionView.extend({
collectionEvents: {
'change': 'render',
},

modelEvents: {
'change:visibleScenarioIndex': 'slide',
},

onRender: function() {
// To initialize table correctly when switching between tabs,
// and when receiving new values from server
this.slide();
},

slide: function() {
var i = this.model.get('visibleScenarioIndex'),
width = models.constants.COMPARE_COLUMN_WIDTH,
marginLeft = -i * width;

this.$('.compare-scenario-row-content').css({
'margin-left': marginLeft + 'px',
});
}
});

var CompareWindow = Marionette.LayoutView.extend({
Expand Down
12 changes: 6 additions & 6 deletions src/mmw/js/src/core/chart.js
Original file line number Diff line number Diff line change
Expand Up @@ -314,25 +314,25 @@ function renderLineChart(chartEl, data, options) {
});
}

function renderCompareMultibarChart(chartEl, name, label, colors, stacked, yMax, data) {
function renderCompareMultibarChart(chartEl, name, label, colors, stacked, yMax, data, columnWidth, xAxisWidth, callback) {
var options = {
margin: {
top: 20,
bottom: 20,
left: 60,
},
minBarWidth: 120,
maxBarWidth: 150,
},
onRenderComplete = (callback) ? callback : _.noop,
yTickFormat = stacked ? '0.1f' : yFormat(),
chart = nv.models.multiBarChart(),
svg = makeSvg(chartEl),
$svg = $(svg);

function setChartWidth() {
var scenariosWidth = (document.getElementById('compare-title-row').offsetWidth + 100);
chartEl.style.width = scenariosWidth + "px";
var scenarioCount = _.size(_.head(data).values),
scenariosWidth = scenarioCount * columnWidth + xAxisWidth;

chartEl.style.width = scenariosWidth + "px";
chart.width(chartEl.offsetWidth);
}

Expand Down Expand Up @@ -384,7 +384,7 @@ function renderCompareMultibarChart(chartEl, name, label, colors, stacked, yMax,
.call(chart);

return chart;
});
}, onRenderComplete);
}

module.exports = {
Expand Down
11 changes: 10 additions & 1 deletion src/mmw/sass/pages/_compare.scss
Original file line number Diff line number Diff line change
Expand Up @@ -443,6 +443,14 @@ $compare-chart-table-height: calc(100vh - #{$height-lg} - #{$compare-footer-heig
.nv-x .tick line {
display: none;
}

.nvd3.nv-wrap.nv-axis {
transition: transform 0.3s ease-in-out;
}

rect {
transition: opacity 0.3s ease-in-out;
}
}

.compare-scenario-gradient {
Expand Down Expand Up @@ -493,7 +501,8 @@ $compare-chart-table-height: calc(100vh - #{$height-lg} - #{$compare-footer-heig
.compare-scenario-row-content {
flex: 1;
display: flex;
flex-wrap: nowrap;
flex-flow: row nowrap;
transition: margin 0.3s ease-in-out;
}

.compare-scenario-samplechartplaceholder {
Expand Down

0 comments on commit a22aef0

Please sign in to comment.