function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; subClass.__proto__ = superClass; } /** * @fileOverview view * @author dxq613@gmail.com */ var Base = require('../base'); var Geom = require('../geom/base'); var Util = require('../util'); var Controller = require('./controller/index'); var Global = require('../global'); var Theme = require('../theme/index'); var FIELD_ORIGIN = '_origin'; var Animate = require('../animate/index'); function isFullCircle(coord) { var startAngle = coord.startAngle; var endAngle = coord.endAngle; if (!Util.isNil(startAngle) && !Util.isNil(endAngle) && endAngle - startAngle < Math.PI * 2) { return false; } return true; } function isBetween(value, start, end) { var tmp = (value - start) / (end - start); return tmp >= 0 && tmp <= 1; } function isPointInCoord(coord, point) { var result = false; if (coord) { var type = coord.type; if (type === 'theta') { var start = coord.start; var end = coord.end; result = isBetween(point.x, start.x, end.x) && isBetween(point.y, start.y, end.y); } else { var invertPoint = coord.invert(point); result = invertPoint.x >= 0 && invertPoint.y >= 0 && invertPoint.x <= 1 && invertPoint.y <= 1; } } return result; } var ViewGeoms = {}; Util.each(Geom, function (geomConstructor, className) { var methodName = Util.lowerFirst(className); ViewGeoms[methodName] = function (cfg) { var geom = new geomConstructor(cfg); this.addGeom(geom); return geom; }; }); /** * 图表中的视图 * @class View */ var View = /*#__PURE__*/function (_Base) { _inheritsLoose(View, _Base); var _proto = View.prototype; /** * 获取默认的配置属性 * @protected * @return {Object} 默认属性 */ _proto.getDefaultCfg = function getDefaultCfg() { return { viewContainer: null, coord: null, start: { x: 0, y: 0 }, end: { x: 1, y: 1 }, geoms: [], scales: {}, options: {}, scaleController: null, padding: 0, theme: null, parent: null, tooltipEnable: true, // 是否展示 tooltip animate: Global.animate, visible: true }; }; function View(cfg) { var _this; _this = _Base.call(this, cfg) || this; var self = _assertThisInitialized(_this); self._setTheme(); Util.each(Geom, function (GeomConstructor, className) { var methodName = Util.lowerFirst(className); self[methodName] = function (cfg) { if (cfg === void 0) { cfg = {}; } cfg.viewTheme = self.get('viewTheme'); var geom = new GeomConstructor(cfg); self.addGeom(geom); return geom; }; }); // Util.mix(this, ViewGeoms); self.init(); return _this; } _proto._setTheme = function _setTheme() { var self = this; var theme = self.get('theme'); var viewTheme = {}; var newTheme = {}; if (Util.isObject(theme)) { newTheme = theme; } else if (Util.indexOf(Object.keys(Theme), theme) !== -1) { newTheme = Theme[theme]; } Util.deepMix(viewTheme, Global, newTheme); self.set('viewTheme', viewTheme); } /** * @protected * 初始化 */ ; _proto.init = function init() { this._initViewPlot(); // 先创建容器 if (this.get('data')) { this._initData(this.get('data')); } this._initOptions(); this._initControllers(); this._bindEvents(); } // 初始化配置项 ; _proto._initOptions = function _initOptions() { var self = this; var options = Util.mix({}, self.get('options')); // 防止修改原始值 if (!options.scales) { options.scales = {}; } if (!options.coord) { options.coord = {}; } if (options.animate === false) { this.set('animate', false); } if (options.tooltip === false || Util.isNull(options.tooltip)) { // 配置项方式关闭 tooltip this.set('tooltipEnable', false); } if (options.geoms && options.geoms.length) { Util.each(options.geoms, function (geomOption) { self._createGeom(geomOption); }); } var scaleController = self.get('scaleController'); if (scaleController) { scaleController.defs = options.scales; } var coordController = self.get('coordController'); if (coordController) { coordController.reset(options.coord); } this.set('options', options); }; _proto._createGeom = function _createGeom(cfg) { var type = cfg.type; var geom; if (this[type]) { geom = this[type](); Util.each(cfg, function (v, k) { if (geom[k]) { if (Util.isObject(v) && v.field) { // 配置项传入 if (v === 'label') { geom[k](v.field, v.callback, v.cfg); } else { var _cfg; Util.each(v, function (value, key) { if (key !== 'field') { _cfg = value; } }); geom[k](v.field, _cfg); } } else { geom[k](v); } } }); } } // 初始化所有的控制器 ; _proto._initControllers = function _initControllers() { var self = this; var options = self.get('options'); var viewTheme = self.get('viewTheme'); var canvas = self.get('canvas'); var scaleController = new Controller.Scale({ viewTheme: viewTheme, defs: options.scales }); var coordController = new Controller.Coord(options.coord); this.set('scaleController', scaleController); this.set('coordController', coordController); var axisController = new Controller.Axis({ canvas: canvas, viewTheme: viewTheme }); this.set('axisController', axisController); var guideController = new Controller.Guide({ viewTheme: viewTheme, options: options.guides || [] }); this.set('guideController', guideController); }; _proto._initViewPlot = function _initViewPlot() { if (!this.get('viewContainer')) { // 用于 geom 的绘制 this.set('viewContainer', this.get('middlePlot')); } }; _proto._initGeoms = function _initGeoms() { var geoms = this.get('geoms'); var filteredData = this.get('filteredData'); var coord = this.get('coord'); var viewId = this.get('_id'); for (var i = 0; i < geoms.length; i++) { var geom = geoms[i]; geom.set('data', filteredData); geom.set('coord', coord); geom.set('_id', viewId + '-geom' + i); geom.set('keyFields', this.get('keyFields')); geom.init(); } }; _proto._clearGeoms = function _clearGeoms() { var self = this; var geoms = self.get('geoms'); for (var i = 0; i < geoms.length; i++) { var geom = geoms[i]; geom.clear(); } }; _proto._removeGeoms = function _removeGeoms() { var self = this; var geoms = self.get('geoms'); while (geoms.length > 0) { var geom = geoms.shift(); geom.destroy(); } }; _proto._drawGeoms = function _drawGeoms() { this.emit('beforedrawgeoms'); var geoms = this.get('geoms'); var coord = this.get('coord'); for (var i = 0; i < geoms.length; i++) { var geom = geoms[i]; geom.setCoord(coord); geom.paint(); } this.emit('afterdrawgeoms'); }; _proto.isShapeInView = function isShapeInView(shape) { var id = this.get('_id'); var shapeId = shape._id; if (shapeId) { return shapeId.split('-')[0] === id; } var parent = shape; while (parent) { if (parent.get('viewId') === id) { return true; } parent = parent.get('parent'); } return false; } /** * View 所在的范围 * @protected * @return {Object} View 所在的范围 */ ; _proto.getViewRegion = function getViewRegion() { var self = this; var parent = self.get('parent'); var start; var end; if (parent) { var region = parent.getViewRegion(); var viewRegion = self._getViewRegion(region.start, region.end); start = viewRegion.start; end = viewRegion.end; } else { start = self.get('start'); end = self.get('end'); } return { start: start, end: end }; } // 获取 range 所在的范围 ; _proto._getViewRegion = function _getViewRegion(plotStart, plotEnd) { var start = this.get('start'); var end = this.get('end'); var startX = start.x; var startY = 1 - end.y; var endX = end.x; var endY = 1 - start.y; var padding = this.get('padding'); // 转换成 上、右、下、左的模式 var allPadding = Util.toAllPadding(padding); var top = allPadding[0]; var right = allPadding[1]; var bottom = allPadding[2]; var left = allPadding[3]; var startPoint = { x: startX * (plotEnd.x - plotStart.x) + plotStart.x + left, y: startY * (plotEnd.y - plotStart.y) + plotStart.y - bottom }; var endPoint = { x: endX * (plotEnd.x - plotStart.x) + plotStart.x - right, y: endY * (plotEnd.y - plotStart.y) + plotStart.y + top }; return { start: startPoint, end: endPoint }; }; _proto._createCoord = function _createCoord() { var coordController = this.get('coordController'); var region = this.getViewRegion(); var coord = coordController.createCoord(region.start, region.end); this.set('coord', coord); }; _proto._renderAxes = function _renderAxes() { var options = this.get('options'); var axesOptions = options.axes; if (axesOptions === false) { // 不渲染坐标轴 return; } var axisController = this.get('axisController'); axisController.container = this.get('backPlot'); axisController.coord = this.get('coord'); axisController.options = axesOptions || {}; var xScale = this.getXScale(); var yScales = this.getYScales(); var viewId = this.get('_id'); axisController.createAxis(xScale, yScales, viewId); }; _proto._renderGuides = function _renderGuides() { var guideController = this.get('guideController'); if (!Util.isEmpty(guideController.options)) { var coord = this.get('coord'); guideController.view = this; guideController.backContainer = this.get('backPlot'); guideController.frontContainer = this.get('frontPlot'); guideController.xScales = this._getScales('x'); guideController.yScales = this._getScales('y'); guideController.render(coord); } } // 注册事件 ; _proto._bindEvents = function _bindEvents() { var eventController = new Controller.Event({ view: this, canvas: this.get('canvas') }); eventController.bindEvents(); this.set('eventController', eventController); } // 清理时间 ; _proto._clearEvents = function _clearEvents() { var eventController = this.get('eventController'); eventController && eventController.clearEvents(); }; _proto._getScales = function _getScales(dimType) { var geoms = this.get('geoms'); var result = {}; for (var i = 0; i < geoms.length; i++) { var geom = geoms[i]; var scale = dimType === 'x' ? geom.getXScale() : geom.getYScale(); if (scale && !result[scale.field]) { result[scale.field] = scale; } } return result; }; _proto._adjustScale = function _adjustScale() { this._setCatScalesRange(); var geoms = this.get('geoms'); var scaleController = this.get('scaleController'); var colDefs = scaleController.defs; for (var i = 0; i < geoms.length; i++) { var geom = geoms[i]; if (geom.get('type') === 'interval') { var yScale = geom.getYScale(); var field = yScale.field, min = yScale.min, max = yScale.max, type = yScale.type; if (!(colDefs[field] && colDefs[field].min) && type !== 'time') { if (min > 0) { yScale.change({ min: 0 }); } else if (max <= 0) { // 当柱状图全为负值时也需要从 0 开始生长 yScale.change({ max: 0 }); } } } } }; _proto._setCatScalesRange = function _setCatScalesRange() { var self = this; var coord = self.get('coord'); var viewTheme = self.get('viewTheme'); var xScale = self.getXScale(); var yScales = self.getYScales(); var scales = []; xScale && scales.push(xScale); scales = scales.concat(yScales); var inFullCircle = coord.isPolar && isFullCircle(coord); var scaleController = self.get('scaleController'); var colDefs = scaleController.defs; Util.each(scales, function (scale) { if ((scale.isCategory || scale.isIdentity) && scale.values && !(colDefs[scale.field] && colDefs[scale.field].range)) { var count = scale.values.length; var range; if (count === 1) { range = [0.5, 1]; // 只有一个分类时,防止计算出现 [0.5,0.5]的状态 } else { var widthRatio = 1; var offset = 0; if (inFullCircle) { if (!coord.isTransposed) { range = [0, 1 - 1 / count]; } else { widthRatio = viewTheme.widthRatio.multiplePie; offset = 1 / count * widthRatio; range = [offset / 2, 1 - offset / 2]; } } else { offset = 1 / count * 1 / 2; // 两边留下分类空间的一半 range = [offset, 1 - offset]; // 坐标轴最前面和最后面留下空白防止绘制柱状图时 } } scale.range = range; } }); }; _proto.getXScale = function getXScale() { var geoms = this.get('geoms'); // 如果进行过滤,那么 geom 默认隐藏时会出现不一致 // 默认隐藏时坐标轴不绘制,但是调用了 geom.show() 后,则图形显示了,坐标轴依然不见 /* .filter(function(geom) { return geom.get('visible'); }); */ var xScale = null; if (!Util.isEmpty(geoms)) { xScale = geoms[0].getXScale(); } return xScale; }; _proto.getYScales = function getYScales() { var geoms = this.get('geoms'); /* .filter(function(geom) { return geom.get('visible'); }); */ var rst = []; for (var i = 0; i < geoms.length; i++) { var geom = geoms[i]; var yScale = geom.getYScale(); if (yScale && Util.indexOf(rst, yScale) === -1) { rst.push(yScale); } } return rst; } /** * 获取数据对应在画布空间的坐标 * @param {Object} item 原始数据 * @return {Object} 返回对应的画布上的坐标点 */ ; _proto.getXY = function getXY(item) { var self = this; var coord = self.get('coord'); var xScales = self._getScales('x'); var yScales = self._getScales('y'); var x; var y; for (var field in item) { if (xScales[field]) { x = xScales[field].scale(item[field]); } if (yScales[field]) { y = yScales[field].scale(item[field]); } } if (!Util.isNil(x) && !Util.isNil(y)) { return coord.convert({ x: x, y: y }); } return null; } /** * 获取逼近的点的数据集合 * @param {Object} point 画布上的像素点 * @return {Array} 数据 */ ; _proto.getSnapRecords = function getSnapRecords(point) { var self = this; var geoms = self.get('geoms'); var rst = []; Util.each(geoms, function (geom) { var dataArray = geom.get('dataArray'); var record; Util.each(dataArray, function (data) { record = geom.findPoint(point, data); record && rst.push(record); }); }); return rst; } /** * @protected * 添加几何标记 * @param {Geom} geom 几何标记 */ ; _proto.addGeom = function addGeom(geom) { var self = this; var geoms = self.get('geoms'); geoms.push(geom); geom.set('view', self); var container = self.get('viewContainer'); geom.set('container', container); geom.set('animate', self.get('animate')); geom.bindEvents(); } /** * @protected * 移除几何标记 * @param {Geom} geom 几何标记 */ ; _proto.removeGeom = function removeGeom(geom) { var geoms = this.get('geoms'); Util.Array.remove(geoms, geom); geom.destroy(); }; _proto.createScale = function createScale(field, data) { var scales = this.get('scales'); var parent = this.get('parent'); var scale = scales[field]; // const filters = this._getFilters(); if (!data) { var filteredData = this.get('filteredData'); var legendFields = this._getFieldsForLegend(); // 过滤导致数据为空时,需要使用全局数据 // 参与过滤的字段的度量也根据全局数据来生成 if (filteredData.length && !legendFields.includes(field)) { data = filteredData; } else { data = this.get('data'); } } var scaleController = this.get('scaleController'); if (!scale) { scale = scaleController.createScale(field, data); if (scale.sync && parent) { var parentScale = parent.createScale(field, data); scale = this._getSyncScale(parentScale, scale); } scales[field] = scale; } else if (scale.sync) { // 防止 view 内部创建的scale,Chart 上的scale 范围更大 var newScale = scaleController.createScale(field, data); this._syncScale(scale, newScale); } return scale; }; _proto._getFieldsForLegend = function _getFieldsForLegend() { var fields = []; var geoms = this.get('geoms'); Util.each(geoms, function (geom) { var geomFields = geom.getFieldsForLegend(); fields = fields.concat(geomFields); }); return Util.uniq(fields); } // 如果需要同步度量,则使得 values,min,max的范围最大 ; _proto._getSyncScale = function _getSyncScale(parentScale, scale) { if (parentScale.type !== scale.type) { return scale; } this._syncScale(parentScale, scale); return parentScale; }; _proto._syncScale = function _syncScale(distScale, sourceScale) { var mergeValues = Util.union(distScale.values, sourceScale.values); if (sourceScale.isLinear) { var max = Math.max(distScale.max, sourceScale.max); var min = Math.min(distScale.min, sourceScale.min); if (distScale.max !== max || distScale.min !== min) { distScale.change({ min: min, max: max, values: mergeValues }); } } if (mergeValues.length !== distScale.values.length) { distScale.change({ values: mergeValues }); } } /** * @protected * 获取过滤后的值(需要显示的值) * @param {String} field 度量 * @return {Array.} 滤后的值 */ ; _proto.getFilteredValues = function getFilteredValues(field) { var scale = this.get('scales')[field]; var values = scale.values; var filters = this._getFilters(); var rst; if (filters && filters[field]) { rst = values.filter(filters[field]); } else { rst = values.slice(0); } return rst; } /** * @protected * 获取被过滤的值(不需显示的值) * @param {String} field 度量 * @return {Array.} 滤出的值 */ ; _proto.getFilteredOutValues = function getFilteredOutValues(field) { var scale = this.get('scales')[field]; var values = scale.values; var filters = this._getFilters(); var rst; if (filters && filters[field]) { rst = values.filter(function () { return !filters[field].apply(filters, arguments); }); } else { rst = []; } return rst; }; _proto.filter = function filter(field, condition) { var options = this.get('options'); if (!options.filters) { options.filters = {}; } options.filters[field] = condition; this.get('scaleController').filters = options.filters; } // 获取 filters ; _proto._getFilters = function _getFilters() { var options = this.get('options'); return options.filters; } // 执行 filter 数据 ; _proto.execFilter = function execFilter(data) { var self = this; var filters = self._getFilters(); if (filters) { data = data.filter(function (obj) { var rst = true; Util.each(filters, function (fn, k) { if (fn) { rst = fn(obj[k], obj); if (!rst) { return false; } } }); return rst; }); } return data; }; _proto.axis = function axis(field, cfg) { var options = this.get('options'); if (field === false) { options.axes = false; } else { if (!options.axes) { options.axes = {}; } var axisOptions = options.axes; axisOptions[field] = cfg; } return this; }; _proto.guide = function guide() { return this.get('guideController'); }; _proto._getKeyFields = function _getKeyFields(scaleDefs) { var keyFields = []; Util.each(scaleDefs, function (def, field) { if (def.key) { keyFields.push(field); } }); this.set('keyFields', keyFields); }; _proto.scale = function scale(field, cfg) { var options = this.get('options'); var scaleDefs = options.scales; if (Util.isObject(field)) { Util.mix(scaleDefs, field); } else { scaleDefs[field] = cfg; } this._getKeyFields(scaleDefs); return this; }; _proto.tooltip = function tooltip(visible) { this.set('tooltipEnable', visible); return this; }; _proto.animate = function animate(enable) { var options = this.get('options'); options.animate = enable; this.set('animate', enable); return this; }; _proto.changeOptions = function changeOptions(options) { this.set('options', options); this._initOptions(options); return this; } /** * @internal 查找包含指定点的视图 * @param {Object} point 点的位置 * @return {Array} 多个视图 */ ; _proto.getViewsByPoint = function getViewsByPoint(point) { var rst = []; var views = this.get('views'); if (isPointInCoord(this.get('coord'), point)) { rst.push(this); } Util.each(views, function (view) { if (view.get('visible') && isPointInCoord(view.get('coord'), point)) { rst.push(view); } }); return rst; } /** * 遍历所有的 shape ,用户更改 shape 后进行刷新 * @param {Function} fn 回调函数包含参数:record,shape,geom,view * @return {View} 当前视图 */ ; _proto.eachShape = function eachShape(fn) { var self = this; var views = self.get('views'); var canvas = self.get('canvas'); Util.each(views, function (view) { view.eachShape(fn); }); var geoms = this.get('geoms'); Util.each(geoms, function (geom) { var shapes = geom.getShapes(); Util.each(shapes, function (shape) { var origin = shape.get('origin'); if (Util.isArray(origin)) { var arr = origin.map(function (subOrigin) { return subOrigin[FIELD_ORIGIN]; }); fn(arr, shape, geom, self); } else { var obj = origin[FIELD_ORIGIN]; fn(obj, shape, geom, self); } }); }); canvas.draw(); return this; } /** * 遍历所有的 shape ,回调函数中 true / false 控制图形是否显示 * @param {Function} fn 回调函数包含参数:record,shape,geom,view * @return {View} 当前视图 */ ; _proto.filterShape = function filterShape(fn) { var callback = function callback(record, shape, geom, view) { if (!fn(record, shape, geom, view)) { shape.hide(); } else { shape.show(); } }; this.eachShape(callback); return this; }; _proto.clearInner = function clearInner() { this.set('scales', {}); this.emit('beforeclearinner'); var options = this.get('options'); options.geoms = null; this._clearGeoms(); // reset guide this.get('guideController') && this.get('guideController').reset(); // clear axis this.get('axisController') && this.get('axisController').clear(); this.emit('afterclearinner'); } /** * 清除视图内容,包括 geoms * @return {View} 当前视图 */ ; _proto.clear = function clear() { var options = this.get('options'); options.filters = null; this._removeGeoms(); // const container = this.get('viewContainer'); // container.clear(); this.clearInner(); this.get('guideController') && this.get('guideController').clear(); this.set('isUpdate', false); this.set('keyFields', []); return this; } /** * 设置坐标系信息 * @param {String} type 类型 * @param {Object} cfg 配置项 * @return {Object} coordController 坐标系的管理器 */ ; _proto.coord = function coord(type, cfg) { var coordController = this.get('coordController'); coordController.reset({ type: type, cfg: cfg }); return coordController; } /** * 当父元素边框发生改变时坐标系需要重新调整 * @protected */ ; _proto.resetCoord = function resetCoord() { this._createCoord(); }; _proto.source = function source(data, scales) { this._initData(data); if (scales) { this.scale(scales); } this.emit('setdata'); return this; }; _proto.changeData = function changeData(data) { this.emit('beforechangedata'); this._initData(data); this.emit('afterchangedata'); this.repaint(); return this; }; _proto._initData = function _initData(data) { var dataView = this.get('dataView'); if (dataView) { dataView.off('change', Util.getWrapBehavior(this, '_onViewChange')); this.set('dataView', null); } if (data && data.isDataView) { data.on('change', Util.wrapBehavior(this, '_onViewChange')); this.set('dataView', data); data = data.rows; } this.set('data', data); }; _proto._onViewChange = function _onViewChange() { this.emit('beforechangedata'); var dataView = this.get('dataView'); var rows = dataView.rows; this.set('data', rows); this.emit('afterchangedata'); this.repaint(); } // 初始化各个 view 和绘制辅助元素 ; _proto.beforeRender = function beforeRender() { var views = this.get('views'); // 如果存在 views 则初始化子 view 的方法 Util.each(views, function (view) { view.beforeRender(); }); this.initView(); } // 绘制坐标轴、图例、辅助元素等图表组件 ; _proto.drawComponents = function drawComponents() { var views = this.get('views'); // 如果存在 views 则初始化子 view 的方法 Util.each(views, function (view) { view.drawComponents(); }); this._renderAxes(); this._renderGuides(); } // 绘制图形 ; _proto.drawCanvas = function drawCanvas(stopDraw) { if (!stopDraw) { var views = this.get('views'); var backPlot = this.get('backPlot'); backPlot.sort(); var canvas = this.get('canvas'); var animate = this.get('animate'); if (animate) { var isUpdate = this.get('isUpdate'); Util.each(views, function (view) { Animate.execAnimation(view, isUpdate); }); Animate.execAnimation(this, isUpdate); } else { canvas.draw(); } } }; _proto.render = function render(stopDraw) { this.clearInner(); this.emit('beforerender'); this.beforeRender(); this.emit('beforepaint'); this.drawComponents(); this.paint(); this.emit('afterpaint'); this.drawCanvas(stopDraw); this.emit('afterrender'); this.set('rendered', true); return this; }; _proto.initView = function initView() { var data = this.get('data') || []; var filteredData = this.execFilter(data); this.set('filteredData', filteredData); // if (!Util.isEmpty(data)) { this._createCoord(); // draw geometry 前绘制区域可能会发生改变 this.emit('beforeinitgeoms'); this._initGeoms(); this._adjustScale(); // } }; _proto.paint = function paint() { var views = this.get('views'); // 绘制 Util.each(views, function (view) { view.paint(); }); var data = this.get('data'); if (!Util.isEmpty(data)) { this._drawGeoms(); } // 如果 view 隐藏了,隐藏所有的图形和坐标轴 if (!this.get('visible')) { this.changeVisible(false, true); // 隐藏所有的图形,但是不绘制 } }; _proto.changeVisible = function changeVisible(visible, stopDraw) { var geoms = this.get('geoms'); Util.each(geoms, function (geom) { // if (geom.get('visible')) { // geom 隐藏时不受 geom.changeVisible(visible, true); // } }); this.get('axisController') && this.get('axisController').changeVisible(visible); this.get('guideController') && this.get('guideController').changeVisible(visible); if (!stopDraw) { var canvas = this.get('canvas'); canvas.draw(); } }; _proto.repaint = function repaint() { this.set('isUpdate', true); this.clearInner(); this.render(); }; _proto.destroy = function destroy() { this._clearEvents(); var dataView = this.get('dataView'); dataView && dataView.off('change', Util.getWrapBehavior(this, '_onViewChange')); this.clear(); _Base.prototype.destroy.call(this); }; return View; }(Base); module.exports = View;