700 lines
20 KiB
JavaScript
700 lines
20 KiB
JavaScript
var _ = require('underscore');
|
|
var CoreView = require('backbone/core-view');
|
|
var formatter = require('../../formatter');
|
|
var HistogramTitleView = require('./histogram-title-view');
|
|
var HistogramChartView = require('./chart');
|
|
var placeholder = require('./placeholder.tpl');
|
|
var template = require('./content.tpl');
|
|
var DropdownView = require('../dropdown/widget-dropdown-view');
|
|
var TipsyTooltipView = require('../../../builder/components/tipsy-tooltip-view');
|
|
var AnimateValues = require('../animate-values.js');
|
|
var animationTemplate = require('./animation-template.tpl');
|
|
var layerColors = require('../../util/layer-colors');
|
|
var analyses = require('../../data/analyses');
|
|
var escapeHTML = require('../../util/escape-html');
|
|
|
|
var TABLET_VIEWPORT_BREAKPOINT = 1200;
|
|
|
|
/**
|
|
* Widget content view for a histogram
|
|
*/
|
|
module.exports = CoreView.extend({
|
|
className: 'CDB-Widget-body',
|
|
|
|
defaults: {
|
|
chartHeight: 48 + 20 + 4
|
|
},
|
|
|
|
events: {
|
|
'click .js-clear': '_resetWidget',
|
|
'click .js-zoom': '_zoom'
|
|
},
|
|
|
|
initialize: function () {
|
|
this._dataviewModel = this.model.dataviewModel;
|
|
this._layerModel = this.model.layerModel;
|
|
this._originalData = this._dataviewModel.getUnfilteredDataModel();
|
|
this.filter = this._dataviewModel.filter;
|
|
this.lockedByUser = false;
|
|
this._numberOfFilters = 0;
|
|
this._initStateApplied = false;
|
|
|
|
if (this._originalData.get('hasBeenFetched')) {
|
|
this._initBinds();
|
|
} else {
|
|
this.listenToOnce(this._originalData, 'change:hasBeenFetched', function () {
|
|
this._initBinds();
|
|
});
|
|
}
|
|
|
|
window.addEventListener('resize', this._onWindowResized.bind(this), { passive: true });
|
|
},
|
|
|
|
render: function () {
|
|
this.clearSubViews();
|
|
this._unbinds();
|
|
|
|
this.$el.toggleClass('is-collapsed', !!this.model.get('collapsed'));
|
|
|
|
var data = this._dataviewModel.getData();
|
|
var hasNulls = this._dataviewModel.hasNulls();
|
|
var originalData = this._originalData.getData();
|
|
var isDataEmpty = !_.size(data) && !_.size(originalData);
|
|
|
|
var sourceId = this._dataviewModel.get('source').id;
|
|
var letter = layerColors.letter(sourceId);
|
|
var sourceColor = layerColors.getColorForLetter(letter);
|
|
var sourceType = this._dataviewModel.getSourceType() || '';
|
|
var isSourceType = this._dataviewModel.isSourceType();
|
|
var layerName = isSourceType
|
|
? this.model.get('table_name')
|
|
: this._layerModel.get('layer_name');
|
|
|
|
this.$el.html(
|
|
template({
|
|
title: this.model.get('title'),
|
|
sourceId: sourceId,
|
|
sourceType: analyses.title(sourceType),
|
|
isSourceType: isSourceType,
|
|
showStats: this.model.get('show_stats'),
|
|
showNulls: hasNulls,
|
|
showSource: this.model.get('show_source') && letter !== '',
|
|
itemsCount: !isDataEmpty ? data.length : '-',
|
|
isCollapsed: !!this.model.get('collapsed'),
|
|
sourceColor: sourceColor,
|
|
layerName: escapeHTML(layerName)
|
|
})
|
|
);
|
|
|
|
if (isDataEmpty) {
|
|
this._addPlaceholder();
|
|
this._initTitleView();
|
|
} else {
|
|
this._setupBindings();
|
|
this._initViews();
|
|
}
|
|
|
|
return this;
|
|
},
|
|
|
|
_initViews: function () {
|
|
this._initTitleView();
|
|
this._initDropdownView();
|
|
this._renderMiniChart();
|
|
this._renderMainChart();
|
|
this._renderAllValues();
|
|
},
|
|
|
|
_onWindowResized: function () {
|
|
if (window.innerWidth < TABLET_VIEWPORT_BREAKPOINT) {
|
|
this.histogramChartView && this.histogramChartView.forceResize();
|
|
}
|
|
},
|
|
|
|
_initDropdownView: function () {
|
|
var dropdown = new DropdownView({
|
|
model: this.model,
|
|
target: '.js-actions',
|
|
container: this.$('.js-header'),
|
|
flags: {
|
|
normalizeHistogram: true
|
|
}
|
|
});
|
|
|
|
this.addView(dropdown);
|
|
},
|
|
|
|
_toggleTooltip: function (event) {
|
|
if (!event || !event.target) {
|
|
return this._clearTooltip();
|
|
}
|
|
|
|
this._showTooltip(event);
|
|
},
|
|
|
|
_showTooltip: function (event) {
|
|
if (this.tooltip && event && this.tooltip.getElement() === event.target) {
|
|
return;
|
|
}
|
|
|
|
this._clearTooltip();
|
|
|
|
this.tooltip = new TipsyTooltipView({
|
|
el: event.target,
|
|
title: 'data-tooltip',
|
|
trigger: 'manual'
|
|
});
|
|
|
|
this.tooltip.showTipsy();
|
|
this.addView(this.tooltip);
|
|
},
|
|
|
|
_clearTooltip: function () {
|
|
if (!this.tooltip) return;
|
|
|
|
this.tooltip.hideTipsy();
|
|
this.removeView(this.tooltip);
|
|
this.tooltip = undefined;
|
|
},
|
|
|
|
_initTitleView: function () {
|
|
var titleView = new HistogramTitleView({
|
|
widgetModel: this.model,
|
|
dataviewModel: this._dataviewModel,
|
|
layerModel: this._layerModel
|
|
});
|
|
|
|
this.$('.js-title').append(titleView.render().el);
|
|
this.addView(titleView);
|
|
},
|
|
|
|
_initBinds: function () {
|
|
this.listenTo(this.model, 'change:collapsed', this.render);
|
|
this.listenTo(this.model, 'change:normalized', this._onNormalizedChanged);
|
|
|
|
if (this.model.get('hasInitialState') === true) {
|
|
this._setInitialState();
|
|
} else {
|
|
this.listenTo(this.model, 'change:hasInitialState', this._setInitialState);
|
|
}
|
|
|
|
this.listenTo(this._layerModel, 'change:layer_name', this.render);
|
|
},
|
|
|
|
_setInitialState: function () {
|
|
var data = this._dataviewModel.getData();
|
|
if (data.length === 0) {
|
|
this._dataviewModel.once('change:data', this._onInitialState, this);
|
|
} else {
|
|
this._onInitialState();
|
|
}
|
|
},
|
|
|
|
_onNormalizedChanged: function () {
|
|
var normalized = this.model.get('normalized');
|
|
this.histogramChartView.setNormalized(normalized);
|
|
this.miniHistogramChartView.setNormalized(normalized);
|
|
},
|
|
|
|
_onInitialState: function () {
|
|
this.add_related_model(this._dataviewModel);
|
|
this.render();
|
|
|
|
if (this.model.get('autoStyle') === true) {
|
|
this.model.autoStyle();
|
|
}
|
|
|
|
if (this._hasRange()) {
|
|
this._numberOfFilters = 1;
|
|
}
|
|
|
|
// in order to calculate the stats right, we simulate the full zommmed range
|
|
if (this._isZoomed()) {
|
|
this._numberOfFilters = 2;
|
|
}
|
|
|
|
if (this._numberOfFilters !== 0) {
|
|
this._setInitialRange();
|
|
} else {
|
|
this._completeInitialState();
|
|
}
|
|
},
|
|
|
|
_setupRange: function (data, min, max, updateCallback) {
|
|
var lo = 0;
|
|
var hi = data.length;
|
|
var startMin;
|
|
var startMax;
|
|
|
|
if (_.isNumber(min)) {
|
|
startMin = _.findWhere(data, {start: min});
|
|
lo = startMin ? startMin.bin : 0;
|
|
}
|
|
|
|
if (_.isNumber(max)) {
|
|
startMax = _.findWhere(data, {end: max});
|
|
hi = startMax ? startMax.bin + 1 : data.length;
|
|
}
|
|
|
|
if ((lo && lo !== 0) || (hi && hi !== data.length)) {
|
|
this.filter.setRange(
|
|
data[lo].start,
|
|
data[hi - 1].end
|
|
);
|
|
this._onChangeFilterEnabled();
|
|
this.histogramChartView.selectRange(lo, hi);
|
|
}
|
|
|
|
updateCallback && updateCallback(lo, hi);
|
|
},
|
|
|
|
_setInitialRange: function () {
|
|
var data = this._dataviewModel.getData();
|
|
var min = this.model.get('min');
|
|
var max = this.model.get('max');
|
|
var filterEnabled = (min !== undefined || max !== undefined);
|
|
|
|
this._setupRange(data, min, max, function (lo, hi) {
|
|
this.model.set({ filter_enabled: filterEnabled, lo_index: lo, hi_index: hi });
|
|
this._dataviewModel.bind('change:data', this._onHistogramDataChanged, this);
|
|
this._initStateApplied = true;
|
|
|
|
// If zoomed, we open the zoom level. Internally it does a fetch, so a change:data is triggered
|
|
// and the _onHistogramDataChanged callback will do the _updateStats call.
|
|
if (this._isZoomed()) {
|
|
this._onChangeZoomEnabled();
|
|
this._onZoomIn();
|
|
} else {
|
|
this._updateStats();
|
|
}
|
|
}.bind(this));
|
|
},
|
|
|
|
_completeInitialState: function () {
|
|
this._dataviewModel.bind('change:data', this._onHistogramDataChanged, this);
|
|
this._initStateApplied = true;
|
|
this._updateStats();
|
|
},
|
|
|
|
_isZoomed: function () {
|
|
return this.model.get('zoomed');
|
|
},
|
|
|
|
_hasRange: function () {
|
|
var min = this.model.get('min');
|
|
var max = this.model.get('max');
|
|
|
|
return (min != null || max != null);
|
|
},
|
|
|
|
_onHistogramDataChanged: function () {
|
|
// When the histogram is zoomed, we don't need to rely
|
|
// on the change url to update the histogram
|
|
// TODO the widget should not know about the URL… could this state be got from the dataview model somehow?
|
|
if (this._dataviewModel.changed.url && this._isZoomed()) {
|
|
return;
|
|
}
|
|
|
|
// if the action was initiated by the user
|
|
// don't replace the stored data
|
|
if (this.lockedByUser) {
|
|
this.lockedByUser = false;
|
|
} else {
|
|
if (!this._isZoomed()) {
|
|
this.histogramChartView.showShadowBars();
|
|
this.miniHistogramChartView.replaceData(this._dataviewModel.getData());
|
|
} else {
|
|
this._filteredData = this._dataviewModel.getData();
|
|
}
|
|
this.histogramChartView.replaceData(this._dataviewModel.getData());
|
|
}
|
|
|
|
if (this.unsettingRange) {
|
|
this._unsetRange();
|
|
}
|
|
|
|
this._updateStats();
|
|
},
|
|
|
|
_unsetRange: function () {
|
|
this.unsettingRange = false;
|
|
this.histogramChartView.replaceData(this._dataviewModel.getData());
|
|
this.model.set({ lo_index: null, hi_index: null });
|
|
|
|
if (!this._isZoomed()) {
|
|
this.histogramChartView.showShadowBars();
|
|
}
|
|
},
|
|
|
|
_addPlaceholder: function () {
|
|
this.$('.js-content').append(placeholder());
|
|
},
|
|
|
|
_renderMainChart: function () {
|
|
this.histogramChartView = new HistogramChartView(({
|
|
type: 'histogram',
|
|
margin: { top: 4, right: 4, bottom: 4, left: 4 },
|
|
hasHandles: true,
|
|
hasAxisTip: true,
|
|
chartBarColor: this.model.getColor() || '#9DE0AD',
|
|
width: this.canvasWidth,
|
|
height: this.defaults.chartHeight,
|
|
data: this._dataviewModel.getData(),
|
|
dataviewModel: this._dataviewModel,
|
|
layerModel: this._layerModel,
|
|
originalData: this._originalData,
|
|
displayShadowBars: !this.model.get('normalized'),
|
|
normalized: this.model.get('normalized'),
|
|
widgetModel: this.model
|
|
}));
|
|
|
|
this.$('.js-chart').append(this.histogramChartView.el);
|
|
this.addView(this.histogramChartView);
|
|
|
|
this.histogramChartView.bind('on_brush_end', this._onBrushEnd, this);
|
|
this.histogramChartView.bind('hover', this._toggleTooltip, this);
|
|
this.histogramChartView.render().show();
|
|
|
|
this._updateStats();
|
|
},
|
|
|
|
_renderMiniChart: function () {
|
|
this.miniHistogramChartView = new HistogramChartView(({
|
|
type: 'histogram',
|
|
className: 'CDB-Chart--mini',
|
|
mini: true,
|
|
margin: { top: 0, right: 4, bottom: 4, left: 4 },
|
|
height: 40,
|
|
showOnWidthChange: false,
|
|
dataviewModel: this._dataviewModel,
|
|
layerModel: this._layerModel,
|
|
data: this._dataviewModel.getData(),
|
|
normalized: this.model.get('normalized'),
|
|
chartBarColor: this.model.getColor() || '#9DE0AD',
|
|
originalData: this._originalData,
|
|
widgetModel: this.model
|
|
}));
|
|
|
|
this.addView(this.miniHistogramChartView);
|
|
this.$('.js-mini-chart').append(this.miniHistogramChartView.el);
|
|
this.miniHistogramChartView.bind('on_brush_end', this._onMiniRangeUpdated, this);
|
|
this.miniHistogramChartView.render();
|
|
},
|
|
|
|
_setupBindings: function () {
|
|
this._dataviewModel.bind('change:bins', this._onChangeBins, this);
|
|
this.model.bind('change:zoomed', this._onChangeZoomed, this);
|
|
this.model.bind('change:zoom_enabled', this._onChangeZoomEnabled, this);
|
|
this.model.bind('change:filter_enabled', this._onChangeFilterEnabled, this);
|
|
this.model.bind('change:total', this._onChangeTotal, this);
|
|
this.model.bind('change:nulls', this._onChangeNulls, this);
|
|
this.model.bind('change:max', this._onChangeMax, this);
|
|
this.model.bind('change:min', this._onChangeMin, this);
|
|
this.model.bind('change:avg', this._onChangeAvg, this);
|
|
},
|
|
|
|
_unbinds: function () {
|
|
this._dataviewModel.off('change:bins', this._onChangeBins, this);
|
|
this.model.off('change:zoomed', this._onChangeZoomed, this);
|
|
this.model.off('change:zoom_enabled', this._onChangeZoomEnabled, this);
|
|
this.model.off('change:filter_enabled', this._onChangeFilterEnabled, this);
|
|
this.model.off('change:total', this._onChangeTotal, this);
|
|
this.model.off('change:nulls', this._onChangeNulls, this);
|
|
this.model.off('change:max', this._onChangeMax, this);
|
|
this.model.off('change:min', this._onChangeMin, this);
|
|
this.model.off('change:avg', this._onChangeAvg, this);
|
|
},
|
|
|
|
_onMiniRangeUpdated: function (loBarIndex, hiBarIndex) {
|
|
this.lockedByUser = false;
|
|
|
|
this._clearTooltip();
|
|
this.histogramChartView.removeSelection();
|
|
|
|
var data = this._originalData.getData();
|
|
|
|
this.model.set({lo_index: loBarIndex, hi_index: hiBarIndex, zlo_index: null, zhi_index: null});
|
|
this._applyBrushFilter(data, loBarIndex, hiBarIndex);
|
|
},
|
|
|
|
_onBrushEnd: function (loBarIndex, hiBarIndex) {
|
|
if (this._isZoomed()) {
|
|
this._onBrushEndFiltered(loBarIndex, hiBarIndex);
|
|
} else {
|
|
this._onBrushEndUnfiltered(loBarIndex, hiBarIndex);
|
|
}
|
|
},
|
|
|
|
_onBrushEndFiltered: function (loBarIndex, hiBarIndex) {
|
|
var data = this._filteredData;
|
|
if ((!data || !data.length) || (this.model.get('zlo_index') === loBarIndex && this.model.get('zhi_index') === hiBarIndex)) {
|
|
return;
|
|
}
|
|
|
|
this._numberOfFilters = 2;
|
|
this.lockedByUser = true;
|
|
this.model.set({filter_enabled: true, zlo_index: loBarIndex, zhi_index: hiBarIndex});
|
|
this._applyBrushFilter(data, loBarIndex, hiBarIndex);
|
|
},
|
|
|
|
_onBrushEndUnfiltered: function (loBarIndex, hiBarIndex) {
|
|
var data = this._dataviewModel.getData();
|
|
if ((!data || !data.length) || (this.model.get('lo_index') === loBarIndex && this.model.get('hi_index') === hiBarIndex)) {
|
|
return;
|
|
}
|
|
this._numberOfFilters = 1;
|
|
this.model.set({filter_enabled: true, zoom_enabled: true, lo_index: loBarIndex, hi_index: hiBarIndex});
|
|
this._applyBrushFilter(data, loBarIndex, hiBarIndex);
|
|
},
|
|
|
|
_applyBrushFilter: function (data, loBarIndex, hiBarIndex) {
|
|
if (loBarIndex !== hiBarIndex && loBarIndex >= 0 && loBarIndex < data.length && (hiBarIndex - 1) >= 0 && (hiBarIndex - 1) < data.length) {
|
|
this.filter.setRange(
|
|
data[loBarIndex].start,
|
|
data[hiBarIndex - 1].end
|
|
);
|
|
this._updateStats();
|
|
} else {
|
|
console.error('Error accessing array bounds', loBarIndex, hiBarIndex, data);
|
|
}
|
|
},
|
|
|
|
_onChangeFilterEnabled: function () {
|
|
this.$('.js-filter').toggleClass('is-hidden', !this.model.get('filter_enabled'));
|
|
},
|
|
|
|
_onChangeBins: function (mdl, bins) {
|
|
this._resetWidget();
|
|
},
|
|
|
|
_onChangeZoomEnabled: function () {
|
|
this.$('.js-zoom').toggleClass('is-hidden', !this.model.get('zoom_enabled'));
|
|
},
|
|
|
|
_renderAllValues: function () {
|
|
this._changeHeaderValue('.js-nulls', 'nulls', '');
|
|
this._changeHeaderValue('.js-val', 'total', 'SELECTED');
|
|
this._changeHeaderValue('.js-max', 'max', '');
|
|
this._changeHeaderValue('.js-min', 'min', '');
|
|
this._changeHeaderValue('.js-avg', 'avg', '');
|
|
},
|
|
|
|
_changeHeaderValue: function (className, what, suffix) {
|
|
if (this.model.get(what) == null) {
|
|
this.$(className).text('0 ' + suffix);
|
|
return;
|
|
}
|
|
|
|
this._addTitleForValue(className, what, suffix);
|
|
|
|
var animator = new AnimateValues({
|
|
el: this.$el
|
|
});
|
|
|
|
animator.animateValue(this.model, what, className, animationTemplate, {
|
|
formatter: formatter.formatNumber,
|
|
templateData: { suffix: ' ' + suffix }
|
|
});
|
|
},
|
|
|
|
_onChangeNulls: function () {
|
|
this._changeHeaderValue('.js-nulls', 'nulls', '');
|
|
},
|
|
|
|
_onChangeTotal: function () {
|
|
this._changeHeaderValue('.js-val', 'total', 'SELECTED');
|
|
},
|
|
|
|
_onChangeMax: function () {
|
|
this._changeHeaderValue('.js-max', 'max', '');
|
|
},
|
|
|
|
_onChangeMin: function () {
|
|
this._changeHeaderValue('.js-min', 'min', '');
|
|
},
|
|
|
|
_onChangeAvg: function () {
|
|
this._changeHeaderValue('.js-avg', 'avg', '');
|
|
},
|
|
|
|
_addTitleForValue: function (className, what, unit) {
|
|
this.$(className).attr('title', this._formatNumberWithCommas(this.model.get(what).toFixed(2)) + ' ' + unit);
|
|
},
|
|
|
|
_formatNumberWithCommas: function (x) {
|
|
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
|
|
},
|
|
|
|
_calculateBars: function (data) {
|
|
var min;
|
|
var max;
|
|
var loBarIndex;
|
|
var hiBarIndex;
|
|
var startMin;
|
|
var startMax;
|
|
|
|
if (this._isZoomed() && this._numberOfFilters === 2) {
|
|
min = this.model.get('zmin');
|
|
max = this.model.get('zmax');
|
|
loBarIndex = this.model.get('zlo_index');
|
|
hiBarIndex = this.model.get('zhi_index');
|
|
} else if (this._numberOfFilters === 1) {
|
|
min = this.model.get('min');
|
|
max = this.model.get('max');
|
|
loBarIndex = this.model.get('lo_index');
|
|
hiBarIndex = this.model.get('hi_index');
|
|
}
|
|
|
|
if (data.length > 0) {
|
|
if (!_.isNumber(min) && !_.isNumber(loBarIndex)) {
|
|
loBarIndex = 0;
|
|
} else if (_.isNumber(min) && !_.isNumber(loBarIndex)) {
|
|
startMin = _.findWhere(data, {start: min});
|
|
loBarIndex = (startMin && startMin.bin) || 0;
|
|
}
|
|
|
|
if (!_.isNumber(max) && !_.isNumber(hiBarIndex)) {
|
|
hiBarIndex = data.length;
|
|
} else if (_.isNumber(max) && !_.isNumber(hiBarIndex)) {
|
|
startMax = _.findWhere(data, {end: max});
|
|
hiBarIndex = (startMax && startMax.bin + 1) || data.length;
|
|
}
|
|
} else {
|
|
loBarIndex = 0;
|
|
hiBarIndex = data.length;
|
|
}
|
|
|
|
return {
|
|
loBarIndex: loBarIndex,
|
|
hiBarIndex: hiBarIndex
|
|
};
|
|
},
|
|
|
|
_updateStats: function () {
|
|
if (!this._initStateApplied) return;
|
|
var data;
|
|
|
|
if (!this._isZoomed() || (this._isZoomed() && this._numberOfFilters === 2)) {
|
|
data = this.histogramChartView.model.get('data');
|
|
} else {
|
|
data = this.miniHistogramChartView.model.get('data');
|
|
}
|
|
|
|
if (data == null) {
|
|
return;
|
|
}
|
|
|
|
var nulls = this._dataviewModel.get('nulls');
|
|
var bars = this._calculateBars(data);
|
|
var loBarIndex = bars.loBarIndex;
|
|
var hiBarIndex = bars.hiBarIndex;
|
|
var sum, avg, min, max;
|
|
var attrs;
|
|
|
|
if (data && data.length) {
|
|
sum = this._calcSum(data, loBarIndex, hiBarIndex);
|
|
avg = this._calcAvg(data, loBarIndex, hiBarIndex);
|
|
|
|
if (loBarIndex >= 0 && loBarIndex < data.length) {
|
|
min = data[loBarIndex].start;
|
|
}
|
|
|
|
if (hiBarIndex >= 0 && hiBarIndex - 1 < data.length) {
|
|
max = data[Math.max(0, hiBarIndex - 1)].end;
|
|
}
|
|
|
|
if (this._isZoomed() && this._numberOfFilters === 2) {
|
|
attrs = {zmin: min, zmax: max, zlo_index: loBarIndex, zhi_index: hiBarIndex};
|
|
} else if (!this._isZoomed() && this._numberOfFilters === 1) {
|
|
attrs = {min: min, max: max, lo_index: loBarIndex, hi_index: hiBarIndex};
|
|
}
|
|
|
|
attrs = _.extend(
|
|
{ total: sum, nulls: nulls, avg: avg },
|
|
attrs);
|
|
|
|
this.model.set(attrs);
|
|
}
|
|
},
|
|
|
|
_calcAvg: function (data, start, end) {
|
|
var selectedData = data.slice(start, end);
|
|
|
|
var total = this._calcSum(data, start, end);
|
|
|
|
if (!total) {
|
|
return 0;
|
|
}
|
|
|
|
var area = _.reduce(selectedData, function (memo, d) {
|
|
return (d.avg && d.freq) ? (d.avg * d.freq) + memo : memo;
|
|
}, 0);
|
|
|
|
return area / total;
|
|
},
|
|
|
|
_calcSum: function (data, start, end) {
|
|
return _.reduce(data.slice(start, end), function (memo, d) {
|
|
return d.freq + memo;
|
|
}, 0);
|
|
},
|
|
|
|
_onChangeZoomed: function () {
|
|
if (this.model.get('zoomed')) {
|
|
this._onZoomIn();
|
|
} else {
|
|
this._resetWidget();
|
|
this._dataviewModel.fetch();
|
|
}
|
|
},
|
|
|
|
_showMiniRange: function () {
|
|
var loBarIndex = this.model.get('lo_index');
|
|
var hiBarIndex = this.model.get('hi_index');
|
|
|
|
this.miniHistogramChartView.selectRange(loBarIndex, hiBarIndex);
|
|
this.miniHistogramChartView.show();
|
|
},
|
|
|
|
_zoom: function () {
|
|
this.model.set({ zoomed: true, zoom_enabled: false });
|
|
this.histogramChartView.removeSelection();
|
|
},
|
|
|
|
_onZoomIn: function () {
|
|
this.lockedByUser = false;
|
|
this._showMiniRange();
|
|
this.histogramChartView.setBounds();
|
|
this._dataviewModel.enableFilter();
|
|
this._dataviewModel.fetch();
|
|
},
|
|
|
|
_resetWidget: function () {
|
|
this._numberOfFilters = 0;
|
|
this.model.set({
|
|
zoomed: false,
|
|
zoom_enabled: false,
|
|
filter_enabled: false,
|
|
lo_index: null,
|
|
hi_index: null,
|
|
min: null,
|
|
max: null,
|
|
zlo_index: null,
|
|
zhi_index: null,
|
|
zmin: null,
|
|
zmax: null
|
|
});
|
|
this.filter.unsetRange();
|
|
this._dataviewModel.disableFilter();
|
|
this.histogramChartView.unsetBounds();
|
|
this.miniHistogramChartView.hide();
|
|
this._clearTooltip();
|
|
this._updateStats();
|
|
},
|
|
|
|
clean: function () {
|
|
window.removeEventListener('resize', this._onWindowResized.bind(this));
|
|
CoreView.prototype.clean.apply(this);
|
|
}
|
|
});
|