197 lines
5.5 KiB
JavaScript
197 lines
5.5 KiB
JavaScript
|
var _ = require('underscore');
|
||
|
var $ = require('jquery');
|
||
|
var Ps = require('perfect-scrollbar');
|
||
|
var CoreView = require('backbone/core-view');
|
||
|
var CategoryContentView = require('./widgets/category/content-view');
|
||
|
var FormulaContentView = require('./widgets/formula/content-view');
|
||
|
var HistogramContentView = require('./widgets/histogram/content-view');
|
||
|
var WidgetViewFactory = require('./widgets/widget-view-factory');
|
||
|
var template = require('./dashboard-sidebar.tpl');
|
||
|
var matchMedia = window.matchMedia;
|
||
|
|
||
|
module.exports = CoreView.extend({
|
||
|
className: 'CDB-Widget-canvas',
|
||
|
|
||
|
initialize: function (options) {
|
||
|
this._widgetViewFactory = new WidgetViewFactory([
|
||
|
{
|
||
|
type: 'formula',
|
||
|
createContentView: function (widgetModel) {
|
||
|
return new FormulaContentView({
|
||
|
model: widgetModel
|
||
|
});
|
||
|
}
|
||
|
}, {
|
||
|
type: 'histogram',
|
||
|
createContentView: function (widgetModel) {
|
||
|
return new HistogramContentView({
|
||
|
model: widgetModel
|
||
|
});
|
||
|
}
|
||
|
}, {
|
||
|
type: 'category',
|
||
|
createContentView: function (widgetModel) {
|
||
|
return new CategoryContentView({
|
||
|
model: widgetModel
|
||
|
});
|
||
|
}
|
||
|
}
|
||
|
]);
|
||
|
|
||
|
this._widgets = options.widgets;
|
||
|
|
||
|
this._widgets.bind('add', this._maybeRenderWidgetView, this);
|
||
|
this._widgets.bind('reset', this.render, this);
|
||
|
this._widgets.bind('orderChanged', this.render, this);
|
||
|
this._widgets.bind('change:collapsed', this._onWidgetUpdate, this);
|
||
|
this._widgets.bind('add remove reset', this._onWidgetsChange, this);
|
||
|
this.add_related_model(this._widgets);
|
||
|
|
||
|
this._resizeHandler = this._onResize.bind(this);
|
||
|
},
|
||
|
|
||
|
render: function () {
|
||
|
this._cleanScroll();
|
||
|
this._observer && this._observer.disconnect();
|
||
|
this.clearSubViews();
|
||
|
|
||
|
this.$el.html(template());
|
||
|
this.$el.toggleClass('CDB-Widget-canvas--withMenu', this.model.get('renderMenu'));
|
||
|
this._widgets.each(this._maybeRenderWidgetView, this);
|
||
|
this._toggleVisiblity();
|
||
|
|
||
|
this._renderScroll();
|
||
|
this._renderShadows();
|
||
|
this._bindScroll();
|
||
|
this._initResize();
|
||
|
|
||
|
return this;
|
||
|
},
|
||
|
|
||
|
_initResize: function () {
|
||
|
var breakpoints = ['(max-width: 1600px)', '(max-width: 1280px)', '(max-width: 759px)'];
|
||
|
breakpoints.forEach(function (breakpoint) {
|
||
|
var mq = matchMedia(breakpoint);
|
||
|
mq.addListener(this._resizeHandler);
|
||
|
}, this);
|
||
|
},
|
||
|
|
||
|
_updateScrollCss: function () {
|
||
|
this._onWidgetUpdate();
|
||
|
|
||
|
var element = this._container();
|
||
|
if (!element) return;
|
||
|
|
||
|
var containerWidth = element.clientWidth;
|
||
|
var containerHeight = element.clientHeight;
|
||
|
var contentWidth = element.scrollWidth;
|
||
|
var contentHeight = element.scrollHeight;
|
||
|
var xScroll = containerWidth < contentWidth;
|
||
|
var yScroll = containerHeight < contentHeight;
|
||
|
|
||
|
this._$container().toggleClass('hasXScroll', xScroll);
|
||
|
this._$container().toggleClass('hasYScroll', yScroll);
|
||
|
},
|
||
|
|
||
|
_$container: function () {
|
||
|
return $(this._container());
|
||
|
},
|
||
|
|
||
|
_container: function () {
|
||
|
return this.el.querySelector('.js-container');
|
||
|
},
|
||
|
|
||
|
_maybeRenderWidgetView: function (widgetModel) {
|
||
|
var view = this._widgetViewFactory.createWidgetView(widgetModel);
|
||
|
|
||
|
if (view) {
|
||
|
this.addView(view);
|
||
|
this._$container().append(view.render().el);
|
||
|
}
|
||
|
},
|
||
|
|
||
|
_bindScroll: function () {
|
||
|
this._$container()
|
||
|
.on('ps-y-reach-start', _.bind(this._onScrollTop, this))
|
||
|
.on('ps-y-reach-end', _.bind(this._onScrollBottom, this))
|
||
|
.on('ps-scroll-y', _.bind(this._onScroll, this));
|
||
|
},
|
||
|
|
||
|
_renderScroll: function () {
|
||
|
Ps.initialize(this._container(), {
|
||
|
wheelSpeed: 1,
|
||
|
wheelPropagation: false,
|
||
|
swipePropagation: true,
|
||
|
stopPropagationOnClick: false,
|
||
|
minScrollbarLength: 20,
|
||
|
useBothWheelAxes: true
|
||
|
});
|
||
|
},
|
||
|
|
||
|
_onWidgetUpdate: function () {
|
||
|
Ps.update(this._container());
|
||
|
},
|
||
|
|
||
|
_renderShadows: function () {
|
||
|
this.$shadowTop = $('<div>').addClass('CDB-Widget-canvasShadow CDB-Widget-canvasShadow--top');
|
||
|
this.$shadowBottom = $('<div>').addClass('CDB-Widget-canvasShadow CDB-Widget-canvasShadow--bottom');
|
||
|
this.$el.append(this.$shadowTop);
|
||
|
this.$el.append(this.$shadowBottom);
|
||
|
},
|
||
|
|
||
|
_onScrollTop: function () {
|
||
|
this.$shadowTop.removeClass('is-visible');
|
||
|
},
|
||
|
|
||
|
_onScroll: function () {
|
||
|
var $el = this._$container();
|
||
|
var currentPos = $el.scrollTop();
|
||
|
var max = $el.get(0).scrollHeight;
|
||
|
var height = $el.outerHeight();
|
||
|
var maxPos = max - height;
|
||
|
|
||
|
this.$shadowTop.toggleClass('is-visible', currentPos > 0);
|
||
|
this.$shadowBottom.toggleClass('is-visible', currentPos < maxPos);
|
||
|
},
|
||
|
|
||
|
_updateScroll: function () {
|
||
|
this._$container().scrollLeft = 0;
|
||
|
this._$container().scrollTop = 0;
|
||
|
},
|
||
|
|
||
|
_onResize: function (mediaQuery) {
|
||
|
// we don't use mediaQuery.matches
|
||
|
// trigger actions always if breakpoints changes
|
||
|
this._updateScroll();
|
||
|
this._onScroll();
|
||
|
},
|
||
|
|
||
|
_onScrollBottom: function () {
|
||
|
this.$shadowBottom.removeClass('is-visible');
|
||
|
},
|
||
|
|
||
|
_cleanScroll: function () {
|
||
|
$(window).off('resize', this._resizeHandler);
|
||
|
if (this._container()) {
|
||
|
this._$container().off('ps-scroll-y');
|
||
|
Ps.destroy(this._container());
|
||
|
}
|
||
|
},
|
||
|
|
||
|
_toggleVisiblity: function () {
|
||
|
this.$el.toggle(!_.isEmpty(this._subviews));
|
||
|
},
|
||
|
|
||
|
_onWidgetsChange: function () {
|
||
|
this._toggleVisiblity();
|
||
|
this.render();
|
||
|
},
|
||
|
|
||
|
clean: function () {
|
||
|
this._cleanScroll();
|
||
|
this._observer && this._observer.disconnect();
|
||
|
CoreView.prototype.clean.call(this);
|
||
|
}
|
||
|
|
||
|
});
|