808 lines
21 KiB
Java
808 lines
21 KiB
Java
function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; subClass.__proto__ = superClass; }
|
||
|
||
/**
|
||
* @fileOverview G2 图表的入口文件
|
||
* @author dxq613@gmail.com
|
||
*/
|
||
var Util = require('../util');
|
||
|
||
var View = require('./view');
|
||
|
||
var G = require('../renderer');
|
||
|
||
var Canvas = G.Canvas;
|
||
var DomUtil = Util.DomUtil;
|
||
|
||
var Global = require('../global');
|
||
|
||
var Plot = require('../component/plot');
|
||
|
||
var Controller = require('./controller/index');
|
||
|
||
var mergeBBox = require('./util/merge-bbox');
|
||
|
||
var bboxOfBackPlot = require('./util/bbox-of-back-plot');
|
||
|
||
var plotRange2BBox = require('./util/plot-range2bbox');
|
||
|
||
var AUTO_STR = 'auto';
|
||
|
||
function _isScaleExist(scales, compareScale) {
|
||
var flag = false;
|
||
Util.each(scales, function (scale) {
|
||
var scaleValues = [].concat(scale.values);
|
||
var compareScaleValues = [].concat(compareScale.values);
|
||
|
||
if (scale.type === compareScale.type && scale.field === compareScale.field && scaleValues.sort().toString() === compareScaleValues.sort().toString()) {
|
||
flag = true;
|
||
return;
|
||
}
|
||
});
|
||
return flag;
|
||
}
|
||
|
||
function isEqualArray(arr1, arr2) {
|
||
return Util.isEqualWith(arr1, arr2, function (v1, v2) {
|
||
return v1 === v2;
|
||
});
|
||
}
|
||
/**
|
||
* 图表的入口
|
||
* @class Chart
|
||
*/
|
||
|
||
|
||
var Chart = /*#__PURE__*/function (_View) {
|
||
_inheritsLoose(Chart, _View);
|
||
|
||
function Chart() {
|
||
return _View.apply(this, arguments) || this;
|
||
}
|
||
|
||
var _proto = Chart.prototype;
|
||
|
||
/**
|
||
* 获取默认的配置属性
|
||
* @protected
|
||
* @return {Object} 默认属性
|
||
*/
|
||
_proto.getDefaultCfg = function getDefaultCfg() {
|
||
var viewCfg = _View.prototype.getDefaultCfg.call(this);
|
||
|
||
return Util.mix(viewCfg, {
|
||
id: null,
|
||
forceFit: false,
|
||
container: null,
|
||
wrapperEl: null,
|
||
canvas: null,
|
||
width: 500,
|
||
height: 500,
|
||
pixelRatio: null,
|
||
backPlot: null,
|
||
frontPlot: null,
|
||
plotBackground: null,
|
||
padding: Global.plotCfg.padding,
|
||
background: null,
|
||
autoPaddingAppend: 5,
|
||
limitInPlot: false,
|
||
renderer: Global.renderer,
|
||
// renderer: 'svg',
|
||
views: []
|
||
});
|
||
};
|
||
|
||
_proto.init = function init() {
|
||
var self = this;
|
||
var viewTheme = self.get('viewTheme');
|
||
|
||
self._initCanvas();
|
||
|
||
self._initPlot();
|
||
|
||
self._initEvents();
|
||
|
||
_View.prototype.init.call(this);
|
||
|
||
var tooltipController = new Controller.Tooltip({
|
||
chart: self,
|
||
viewTheme: viewTheme,
|
||
options: {}
|
||
});
|
||
self.set('tooltipController', tooltipController);
|
||
var legendController = new Controller.Legend({
|
||
chart: self,
|
||
viewTheme: viewTheme
|
||
});
|
||
self.set('legendController', legendController);
|
||
self.set('_id', 'chart'); // 防止同用户设定的 id 同名
|
||
|
||
self.emit('afterinit'); // 初始化完毕
|
||
};
|
||
|
||
_proto._isAutoPadding = function _isAutoPadding() {
|
||
var padding = this.get('padding');
|
||
|
||
if (Util.isArray(padding)) {
|
||
return padding.includes(AUTO_STR);
|
||
}
|
||
|
||
return padding === AUTO_STR;
|
||
};
|
||
|
||
_proto._getAutoPadding = function _getAutoPadding() {
|
||
var padding = this.get('padding'); // 图例在最前面的一层
|
||
|
||
var frontPlot = this.get('frontPlot');
|
||
var frontBBox = frontPlot.getBBox(); // 坐标轴在最后面的一层
|
||
|
||
var backPlot = this.get('backPlot'); // 这段代码临时处理了title 过长的情况,但是是非常不好的代码
|
||
|
||
var backBBox = bboxOfBackPlot(backPlot, plotRange2BBox(this.get('plotRange')));
|
||
var box = mergeBBox(frontBBox, backBBox);
|
||
var outter = [0 - box.minY, // 上面超出的部分
|
||
box.maxX - this.get('width'), // 右边超出的部分
|
||
box.maxY - this.get('height'), // 下边超出的部分
|
||
0 - box.minX]; // 如果原始的 padding 内部存在 'auto' 则替换对应的边
|
||
|
||
var autoPadding = Util.toAllPadding(padding);
|
||
|
||
for (var i = 0; i < autoPadding.length; i++) {
|
||
if (autoPadding[i] === AUTO_STR) {
|
||
var tmp = Math.max(0, outter[i]);
|
||
autoPadding[i] = tmp + this.get('autoPaddingAppend');
|
||
}
|
||
}
|
||
|
||
return autoPadding;
|
||
} // 初始化画布
|
||
;
|
||
|
||
_proto._initCanvas = function _initCanvas() {
|
||
var container = this.get('container');
|
||
var id = this.get('id'); // 如果未设置 container 使用 ID, 兼容 2.x 版本
|
||
|
||
if (!container && id) {
|
||
container = id;
|
||
this.set('container', id);
|
||
}
|
||
|
||
var width = this.get('width');
|
||
var height = this.get('height');
|
||
|
||
if (Util.isString(container)) {
|
||
container = document.getElementById(container);
|
||
|
||
if (!container) {
|
||
throw new Error('Please specify the container for the chart!');
|
||
}
|
||
|
||
this.set('container', container);
|
||
}
|
||
|
||
var wrapperEl = DomUtil.createDom('<div style="position:relative;"></div>');
|
||
container.appendChild(wrapperEl);
|
||
this.set('wrapperEl', wrapperEl);
|
||
|
||
if (this.get('forceFit')) {
|
||
width = DomUtil.getWidth(container, width);
|
||
this.set('width', width);
|
||
}
|
||
|
||
var renderer = this.get('renderer');
|
||
var canvas = new Canvas({
|
||
containerDOM: wrapperEl,
|
||
width: width,
|
||
height: height,
|
||
// NOTICE: 有问题找青湳
|
||
pixelRatio: renderer === 'svg' ? 1 : this.get('pixelRatio'),
|
||
renderer: renderer
|
||
});
|
||
this.set('canvas', canvas);
|
||
} // 初始化绘图区间
|
||
;
|
||
|
||
_proto._initPlot = function _initPlot() {
|
||
var self = this;
|
||
|
||
self._initPlotBack(); // 最底层的是背景相关的 group
|
||
|
||
|
||
var canvas = self.get('canvas');
|
||
var backPlot = canvas.addGroup({
|
||
zIndex: 1
|
||
}); // 图表最后面的容器
|
||
|
||
var plotContainer = canvas.addGroup({
|
||
zIndex: 0
|
||
}); // 图表所在的容器
|
||
|
||
var frontPlot = canvas.addGroup({
|
||
zIndex: 3
|
||
}); // 图表前面的容器
|
||
|
||
self.set('backPlot', backPlot);
|
||
self.set('middlePlot', plotContainer);
|
||
self.set('frontPlot', frontPlot);
|
||
} // 初始化背景
|
||
;
|
||
|
||
_proto._initPlotBack = function _initPlotBack() {
|
||
var self = this;
|
||
var canvas = self.get('canvas');
|
||
var viewTheme = self.get('viewTheme');
|
||
var plot = canvas.addGroup(Plot, {
|
||
padding: this.get('padding'),
|
||
plotBackground: Util.mix({}, viewTheme.plotBackground, self.get('plotBackground')),
|
||
background: Util.mix({}, viewTheme.background, self.get('background'))
|
||
});
|
||
self.set('plot', plot);
|
||
self.set('plotRange', plot.get('plotRange'));
|
||
};
|
||
|
||
_proto._initEvents = function _initEvents() {
|
||
if (this.get('forceFit')) {
|
||
window.addEventListener('resize', Util.wrapBehavior(this, '_initForceFitEvent'));
|
||
}
|
||
};
|
||
|
||
_proto._initForceFitEvent = function _initForceFitEvent() {
|
||
var timer = setTimeout(Util.wrapBehavior(this, 'forceFit'), 200);
|
||
clearTimeout(this.get('resizeTimer'));
|
||
this.set('resizeTimer', timer);
|
||
} // 绘制图例
|
||
;
|
||
|
||
_proto._renderLegends = function _renderLegends() {
|
||
var options = this.get('options');
|
||
var legendOptions = options.legends;
|
||
|
||
if (Util.isNil(legendOptions) || legendOptions !== false) {
|
||
// 没有关闭图例
|
||
var legendController = this.get('legendController');
|
||
legendController.options = legendOptions || {};
|
||
legendController.plotRange = this.get('plotRange');
|
||
|
||
if (legendOptions && legendOptions.custom) {
|
||
// 用户自定义图例
|
||
legendController.addCustomLegend();
|
||
} else {
|
||
var geoms = this.getAllGeoms();
|
||
var scales = [];
|
||
Util.each(geoms, function (geom) {
|
||
var view = geom.get('view');
|
||
var attrs = geom.getAttrsForLegend();
|
||
Util.each(attrs, function (attr) {
|
||
var type = attr.type;
|
||
var scale = attr.getScale(type);
|
||
|
||
if (scale.field && scale.type !== 'identity' && !_isScaleExist(scales, scale)) {
|
||
scales.push(scale);
|
||
var filteredValues = view.getFilteredOutValues(scale.field);
|
||
legendController.addLegend(scale, attr, geom, filteredValues);
|
||
}
|
||
});
|
||
}); // 双轴的情况
|
||
|
||
var yScales = this.getYScales();
|
||
|
||
if (scales.length === 0 && yScales.length > 1) {
|
||
legendController.addMixedLegend(yScales, geoms);
|
||
}
|
||
}
|
||
|
||
legendController.alignLegends();
|
||
}
|
||
} // 绘制 tooltip
|
||
;
|
||
|
||
_proto._renderTooltips = function _renderTooltips() {
|
||
var options = this.get('options');
|
||
|
||
if (Util.isNil(options.tooltip) || options.tooltip !== false) {
|
||
// 用户没有关闭 tooltip
|
||
var tooltipController = this.get('tooltipController');
|
||
tooltipController.options = options.tooltip || {};
|
||
tooltipController.renderTooltip();
|
||
}
|
||
}
|
||
/**
|
||
* 获取所有的几何标记
|
||
* @return {Array} 所有的几何标记
|
||
*/
|
||
;
|
||
|
||
_proto.getAllGeoms = function getAllGeoms() {
|
||
var geoms = [];
|
||
geoms = geoms.concat(this.get('geoms'));
|
||
var views = this.get('views');
|
||
Util.each(views, function (view) {
|
||
geoms = geoms.concat(view.get('geoms'));
|
||
});
|
||
return geoms;
|
||
}
|
||
/**
|
||
* 自适应宽度
|
||
* @chainable
|
||
* @return {Chart} 图表对象
|
||
*/
|
||
;
|
||
|
||
_proto.forceFit = function forceFit() {
|
||
var self = this;
|
||
|
||
if (!self || self.destroyed) {
|
||
return;
|
||
}
|
||
|
||
var container = self.get('container');
|
||
var oldWidth = self.get('width');
|
||
var width = DomUtil.getWidth(container, oldWidth);
|
||
|
||
if (width !== 0 && width !== oldWidth) {
|
||
var height = self.get('height');
|
||
self.changeSize(width, height);
|
||
}
|
||
|
||
return self;
|
||
};
|
||
|
||
_proto.resetPlot = function resetPlot() {
|
||
var plot = this.get('plot');
|
||
var padding = this.get('padding');
|
||
|
||
if (!isEqualArray(padding, plot.get('padding'))) {
|
||
// 重置 padding,仅当padding 发生更改
|
||
plot.set('padding', padding);
|
||
plot.repaint();
|
||
}
|
||
}
|
||
/**
|
||
* 改变大小
|
||
* @param {Number} width 图表宽度
|
||
* @param {Number} height 图表高度
|
||
* @return {Chart} 图表对象
|
||
*/
|
||
;
|
||
|
||
_proto.changeSize = function changeSize(width, height) {
|
||
var self = this;
|
||
var canvas = self.get('canvas');
|
||
canvas.changeSize(width, height);
|
||
var plot = this.get('plot');
|
||
self.set('width', width);
|
||
self.set('height', height); // change size 时重新计算边框
|
||
|
||
plot.repaint(); // 保持边框不变,防止自动 padding 时绘制多遍
|
||
|
||
this.set('keepPadding', true);
|
||
self.repaint();
|
||
this.set('keepPadding', false);
|
||
this.emit('afterchangesize');
|
||
return self;
|
||
}
|
||
/**
|
||
* 改变宽度
|
||
* @param {Number} width 图表宽度
|
||
* @return {Chart} 图表对象
|
||
*/
|
||
;
|
||
|
||
_proto.changeWidth = function changeWidth(width) {
|
||
return this.changeSize(width, this.get('height'));
|
||
}
|
||
/**
|
||
* 改变宽度
|
||
* @param {Number} height 图表高度
|
||
* @return {Chart} 图表对象
|
||
*/
|
||
;
|
||
|
||
_proto.changeHeight = function changeHeight(height) {
|
||
return this.changeSize(this.get('width'), height);
|
||
}
|
||
/**
|
||
* 创建一个视图
|
||
* @param {Object} cfg 视图的配置项
|
||
* @return {View} 视图对象
|
||
*/
|
||
;
|
||
|
||
_proto.view = function view(cfg) {
|
||
cfg = cfg || {};
|
||
cfg.theme = this.get('theme');
|
||
cfg.parent = this;
|
||
cfg.backPlot = this.get('backPlot');
|
||
cfg.middlePlot = this.get('middlePlot');
|
||
cfg.frontPlot = this.get('frontPlot');
|
||
cfg.canvas = this.get('canvas');
|
||
|
||
if (Util.isNil(cfg.animate)) {
|
||
cfg.animate = this.get('animate');
|
||
}
|
||
|
||
cfg.options = Util.mix({}, this._getSharedOptions(), cfg.options);
|
||
var view = new View(cfg);
|
||
view.set('_id', 'view' + this.get('views').length); // 标识 ID,防止同用户设定的 id 重名
|
||
|
||
this.get('views').push(view);
|
||
this.emit('addview', {
|
||
view: view
|
||
});
|
||
return view;
|
||
} // isShapeInView() {
|
||
// return true;
|
||
// }
|
||
;
|
||
|
||
_proto.removeView = function removeView(view) {
|
||
var views = this.get('views');
|
||
Util.Array.remove(views, view);
|
||
view.destroy();
|
||
};
|
||
|
||
_proto._getSharedOptions = function _getSharedOptions() {
|
||
var options = this.get('options');
|
||
var sharedOptions = {};
|
||
Util.each(['scales', 'coord', 'axes'], function (name) {
|
||
sharedOptions[name] = Util.cloneDeep(options[name]);
|
||
});
|
||
return sharedOptions;
|
||
}
|
||
/**
|
||
* @override
|
||
* 当前chart 的范围
|
||
*/
|
||
;
|
||
|
||
_proto.getViewRegion = function getViewRegion() {
|
||
var plotRange = this.get('plotRange');
|
||
return {
|
||
start: plotRange.bl,
|
||
end: plotRange.tr
|
||
};
|
||
}
|
||
/**
|
||
* 设置图例配置信息
|
||
* @param {String|Object} field 字段名
|
||
* @param {Object} [cfg] 图例的配置项
|
||
* @return {Chart} 当前的图表对象
|
||
*/
|
||
;
|
||
|
||
_proto.legend = function legend(field, cfg) {
|
||
var options = this.get('options');
|
||
|
||
if (!options.legends) {
|
||
options.legends = {};
|
||
}
|
||
|
||
var legends = {};
|
||
|
||
if (field === false) {
|
||
options.legends = false;
|
||
} else if (Util.isObject(field)) {
|
||
legends = field;
|
||
} else if (Util.isString(field)) {
|
||
legends[field] = cfg;
|
||
} else {
|
||
legends = cfg;
|
||
}
|
||
|
||
Util.mix(options.legends, legends);
|
||
return this;
|
||
}
|
||
/**
|
||
* 设置提示信息
|
||
* @param {String|Object} visible 是否可见
|
||
* @param {Object} [cfg] 提示信息的配置项
|
||
* @return {Chart} 当前的图表对象
|
||
*/
|
||
;
|
||
|
||
_proto.tooltip = function tooltip(visible, cfg) {
|
||
var options = this.get('options');
|
||
|
||
if (!options.tooltip) {
|
||
options.tooltip = {};
|
||
}
|
||
|
||
if (visible === false) {
|
||
options.tooltip = false;
|
||
} else if (Util.isObject(visible)) {
|
||
Util.mix(options.tooltip, visible);
|
||
} else {
|
||
Util.mix(options.tooltip, cfg);
|
||
}
|
||
|
||
return this;
|
||
}
|
||
/**
|
||
* 清空图表
|
||
* @return {Chart} 当前的图表对象
|
||
*/
|
||
;
|
||
|
||
_proto.clear = function clear() {
|
||
this.emit('beforeclear');
|
||
var views = this.get('views');
|
||
|
||
while (views.length > 0) {
|
||
var view = views.shift();
|
||
view.destroy();
|
||
}
|
||
|
||
_View.prototype.clear.call(this);
|
||
|
||
var canvas = this.get('canvas');
|
||
this.resetPlot();
|
||
canvas.draw();
|
||
this.emit('afterclear');
|
||
return this;
|
||
};
|
||
|
||
_proto.clearInner = function clearInner() {
|
||
var views = this.get('views');
|
||
Util.each(views, function (view) {
|
||
view.clearInner();
|
||
});
|
||
var tooltipController = this.get('tooltipController');
|
||
tooltipController && tooltipController.clear();
|
||
|
||
if (!this.get('keepLegend')) {
|
||
var legendController = this.get('legendController');
|
||
legendController && legendController.clear();
|
||
}
|
||
|
||
_View.prototype.clearInner.call(this);
|
||
} // chart 除了view 上绘制的组件外,还会绘制图例和 tooltip
|
||
;
|
||
|
||
_proto.drawComponents = function drawComponents() {
|
||
_View.prototype.drawComponents.call(this); // 一般是点击图例时,仅仅隐藏某些选项,而不销毁图例
|
||
|
||
|
||
if (!this.get('keepLegend')) {
|
||
this._renderLegends(); // 渲染图例
|
||
|
||
}
|
||
}
|
||
/**
|
||
* 绘制图表
|
||
* @override
|
||
*/
|
||
;
|
||
|
||
_proto.render = function render() {
|
||
var self = this; // 需要自动计算边框,则重新设置
|
||
|
||
if (!self.get('keepPadding') && self._isAutoPadding()) {
|
||
self.beforeRender(); // 初始化各个 view 和 绘制
|
||
|
||
self.drawComponents();
|
||
|
||
var autoPadding = self._getAutoPadding();
|
||
|
||
var plot = self.get('plot'); // 在计算出来的边框不一致的情况,重新改变边框
|
||
|
||
if (!isEqualArray(plot.get('padding'), autoPadding)) {
|
||
plot.set('padding', autoPadding);
|
||
plot.repaint();
|
||
}
|
||
}
|
||
|
||
var middlePlot = self.get('middlePlot');
|
||
|
||
if (self.get('limitInPlot') && !middlePlot.attr('clip')) {
|
||
var clip = Util.getClipByRange(self.get('plotRange')); // TODO Polar coord
|
||
|
||
middlePlot.attr('clip', clip); // clip.attr('fill', 'grey');
|
||
// clip.attr('opacity', 0.5);
|
||
// middlePlot.add(clip);
|
||
}
|
||
|
||
_View.prototype.render.call(this);
|
||
|
||
self._renderTooltips(); // 渲染 tooltip
|
||
|
||
};
|
||
|
||
_proto.repaint = function repaint() {
|
||
// 重绘时需要判定当前的 padding 是否发生过改变,如果发生过改变进行调整
|
||
// 需要判定是否使用了自动 padding
|
||
if (!this.get('keepPadding')) {
|
||
this.resetPlot();
|
||
}
|
||
|
||
_View.prototype.repaint.call(this);
|
||
}
|
||
/**
|
||
* @override
|
||
* 显示或者隐藏
|
||
*/
|
||
;
|
||
|
||
_proto.changeVisible = function changeVisible(visible) {
|
||
var wrapperEl = this.get('wrapperEl');
|
||
var visibleStr = visible ? '' : 'none';
|
||
wrapperEl.style.display = visibleStr;
|
||
}
|
||
/**
|
||
* 返回图表的 dataUrl 用于生成图片
|
||
* @return {String} dataUrl 路径
|
||
*/
|
||
;
|
||
|
||
_proto.toDataURL = function toDataURL() {
|
||
var chart = this;
|
||
var canvas = chart.get('canvas');
|
||
var renderer = chart.get('renderer');
|
||
var canvasDom = canvas.get('el');
|
||
var dataURL = '';
|
||
|
||
if (renderer === 'svg') {
|
||
var clone = canvasDom.cloneNode(true);
|
||
var svgDocType = document.implementation.createDocumentType('svg', '-//W3C//DTD SVG 1.1//EN', 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd');
|
||
var svgDoc = document.implementation.createDocument('http://www.w3.org/2000/svg', 'svg', svgDocType);
|
||
svgDoc.replaceChild(clone, svgDoc.documentElement);
|
||
var svgData = new XMLSerializer().serializeToString(svgDoc);
|
||
dataURL = 'data:image/svg+xml;charset=utf8,' + encodeURIComponent(svgData);
|
||
} else if (renderer === 'canvas') {
|
||
dataURL = canvasDom.toDataURL('image/png');
|
||
}
|
||
|
||
return dataURL;
|
||
}
|
||
/**
|
||
* 图表导出功能
|
||
* @param {String} [name] 图片的名称,默认为 chart(.png|.svg)
|
||
*/
|
||
;
|
||
|
||
_proto.downloadImage = function downloadImage(name) {
|
||
var chart = this;
|
||
var link = document.createElement('a');
|
||
var renderer = chart.get('renderer');
|
||
var filename = (name || 'chart') + (renderer === 'svg' ? '.svg' : '.png');
|
||
var canvas = chart.get('canvas');
|
||
canvas.get('timeline').stopAllAnimations();
|
||
setTimeout(function () {
|
||
var dataURL = chart.toDataURL();
|
||
|
||
if (window.Blob && window.URL && renderer !== 'svg') {
|
||
var arr = dataURL.split(',');
|
||
var mime = arr[0].match(/:(.*?);/)[1];
|
||
var bstr = atob(arr[1]);
|
||
var n = bstr.length;
|
||
var u8arr = new Uint8Array(n);
|
||
|
||
while (n--) {
|
||
u8arr[n] = bstr.charCodeAt(n);
|
||
}
|
||
|
||
var blobObj = new Blob([u8arr], {
|
||
type: mime
|
||
});
|
||
|
||
if (window.navigator.msSaveBlob) {
|
||
window.navigator.msSaveBlob(blobObj, filename);
|
||
} else {
|
||
link.addEventListener('click', function () {
|
||
link.download = filename;
|
||
link.href = window.URL.createObjectURL(blobObj);
|
||
});
|
||
}
|
||
} else {
|
||
link.addEventListener('click', function () {
|
||
link.download = filename;
|
||
link.href = dataURL;
|
||
});
|
||
}
|
||
|
||
var e = document.createEvent('MouseEvents');
|
||
e.initEvent('click', false, false);
|
||
link.dispatchEvent(e);
|
||
}, 16);
|
||
}
|
||
/**
|
||
* 根据坐标点显示对应的 tooltip
|
||
* @param {Object} point 画布上的点
|
||
* @return {Chart} 返回 chart 实例
|
||
*/
|
||
;
|
||
|
||
_proto.showTooltip = function showTooltip(point) {
|
||
var views = this.getViewsByPoint(point);
|
||
|
||
if (views.length) {
|
||
var tooltipController = this.get('tooltipController');
|
||
tooltipController.showTooltip(point, views);
|
||
}
|
||
|
||
return this;
|
||
}
|
||
/**
|
||
* 将tooltip 锁定到当前位置不能移动
|
||
* @return {Chart} 返回 chart 实例
|
||
*/
|
||
;
|
||
|
||
_proto.lockTooltip = function lockTooltip() {
|
||
var tooltipController = this.get('tooltipController');
|
||
tooltipController.lockTooltip();
|
||
return this;
|
||
}
|
||
/**
|
||
* 将tooltip 锁定解除
|
||
* @return {Chart} 返回 chart 实例
|
||
*/
|
||
;
|
||
|
||
_proto.unlockTooltip = function unlockTooltip() {
|
||
var tooltipController = this.get('tooltipController');
|
||
tooltipController.unlockTooltip();
|
||
return this;
|
||
}
|
||
/**
|
||
* 隐藏 tooltip
|
||
* @return {Chart} 返回 chart 实例
|
||
*/
|
||
;
|
||
|
||
_proto.hideTooltip = function hideTooltip() {
|
||
var tooltipController = this.get('tooltipController');
|
||
tooltipController.hideTooltip();
|
||
return this;
|
||
}
|
||
/**
|
||
* 根据传入的画布坐标,获取该处的 tooltip 上的记录信息
|
||
* @param {Object} point 画布坐标点
|
||
* @return {Array} 返回结果
|
||
*/
|
||
;
|
||
|
||
_proto.getTooltipItems = function getTooltipItems(point) {
|
||
var self = this;
|
||
var views = self.getViewsByPoint(point);
|
||
var rst = [];
|
||
Util.each(views, function (view) {
|
||
var geoms = view.get('geoms');
|
||
Util.each(geoms, function (geom) {
|
||
var dataArray = geom.get('dataArray');
|
||
var items = [];
|
||
Util.each(dataArray, function (data) {
|
||
var tmpPoint = geom.findPoint(point, data);
|
||
|
||
if (tmpPoint) {
|
||
var subItems = geom.getTipItems(tmpPoint);
|
||
items = items.concat(subItems);
|
||
}
|
||
});
|
||
rst = rst.concat(items);
|
||
});
|
||
});
|
||
return rst;
|
||
}
|
||
/**
|
||
* @override
|
||
* 销毁图表
|
||
*/
|
||
;
|
||
|
||
_proto.destroy = function destroy() {
|
||
this.emit('beforedestroy');
|
||
clearTimeout(this.get('resizeTimer'));
|
||
var canvas = this.get('canvas');
|
||
var wrapperEl = this.get('wrapperEl');
|
||
wrapperEl.parentNode.removeChild(wrapperEl);
|
||
|
||
_View.prototype.destroy.call(this);
|
||
|
||
canvas.destroy();
|
||
window.removeEventListener('resize', Util.getWrapBehavior(this, '_initForceFitEvent'));
|
||
this.emit('afterdestroy');
|
||
};
|
||
|
||
return Chart;
|
||
}(View);
|
||
|
||
module.exports = Chart; |