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; _setPrototypeOf(subClass, superClass); }

function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }

/**
 * @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.<String>} 滤后的值
   */
  ;

  _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.<String>} 滤出的值
   */
  ;

  _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;