315 lines
8.8 KiB
Java
315 lines
8.8 KiB
Java
/**
|
||
* @fileOverview The controller of chart's events
|
||
* @author sima.zhang
|
||
*/
|
||
var Util = require('../../util');
|
||
|
||
function isSameShape(shape1, shape2) {
|
||
if (Util.isNil(shape1) || Util.isNil(shape2)) {
|
||
return false;
|
||
}
|
||
|
||
var shape1Origin = shape1.get('origin');
|
||
var shape2Origin = shape2.get('origin'); // hotfix: if both shapes have no data,just compare shapes.
|
||
|
||
if (Util.isNil(shape1Origin) && Util.isNil(shape2Origin)) {
|
||
return Util.isEqual(shape1, shape2);
|
||
}
|
||
|
||
return Util.isEqual(shape1Origin, shape2Origin);
|
||
}
|
||
|
||
function registerData(eventObj) {
|
||
if (eventObj.shape && eventObj.shape.get('origin')) {
|
||
eventObj.data = eventObj.shape.get('origin');
|
||
}
|
||
}
|
||
|
||
var EventController = /*#__PURE__*/function () {
|
||
function EventController(cfg) {
|
||
this.view = null;
|
||
this.canvas = null;
|
||
Util.assign(this, cfg);
|
||
|
||
this._init();
|
||
}
|
||
|
||
var _proto = EventController.prototype;
|
||
|
||
_proto._init = function _init() {
|
||
this.pixelRatio = this.canvas.get('pixelRatio');
|
||
};
|
||
|
||
_proto._getShapeEventObj = function _getShapeEventObj(ev) {
|
||
return {
|
||
x: ev.x / this.pixelRatio,
|
||
y: ev.y / this.pixelRatio,
|
||
target: ev.target,
|
||
// canvas 元素
|
||
toElement: ev.event.toElement || ev.event.relatedTarget
|
||
};
|
||
};
|
||
|
||
_proto._getShape = function _getShape(x, y) {
|
||
var view = this.view;
|
||
var container = view.get('canvas');
|
||
return container.getShape(x, y);
|
||
};
|
||
|
||
_proto._getPointInfo = function _getPointInfo(ev) {
|
||
var view = this.view;
|
||
var point = {
|
||
x: ev.x / this.pixelRatio,
|
||
y: ev.y / this.pixelRatio
|
||
};
|
||
var views = view.getViewsByPoint(point);
|
||
point.views = views;
|
||
return point;
|
||
};
|
||
|
||
_proto._getEventObj = function _getEventObj(ev, point, views) {
|
||
return {
|
||
x: point.x,
|
||
y: point.y,
|
||
target: ev.target,
|
||
// canvas 元素
|
||
toElement: ev.event.toElement || ev.event.relatedTarget,
|
||
// 目标元素
|
||
views: views
|
||
};
|
||
};
|
||
|
||
_proto.bindEvents = function bindEvents() {
|
||
var canvas = this.canvas;
|
||
canvas.on('mousedown', Util.wrapBehavior(this, 'onDown'));
|
||
canvas.on('mousemove', Util.wrapBehavior(this, 'onMove'));
|
||
canvas.on('mouseleave', Util.wrapBehavior(this, 'onOut'));
|
||
canvas.on('mouseup', Util.wrapBehavior(this, 'onUp'));
|
||
canvas.on('click', Util.wrapBehavior(this, 'onClick'));
|
||
canvas.on('dblclick', Util.wrapBehavior(this, 'onClick'));
|
||
canvas.on('touchstart', Util.wrapBehavior(this, 'onTouchstart'));
|
||
canvas.on('touchmove', Util.wrapBehavior(this, 'onTouchmove'));
|
||
canvas.on('touchend', Util.wrapBehavior(this, 'onTouchend'));
|
||
};
|
||
|
||
_proto._triggerShapeEvent = function _triggerShapeEvent(shape, eventName, eventObj) {
|
||
if (shape && shape.name && !shape.get('destroyed')) {
|
||
var view = this.view;
|
||
|
||
if (view.isShapeInView(shape)) {
|
||
var name = shape.name + ':' + eventName;
|
||
eventObj.view = view;
|
||
eventObj.appendInfo = shape.get('appendInfo'); // appendInfo is defined by user
|
||
|
||
view.emit(name, eventObj);
|
||
var parent = view.get('parent');
|
||
|
||
if (parent) {
|
||
// chart 上也需要抛出该事件,本期先不抛出
|
||
parent.emit(name, eventObj);
|
||
}
|
||
}
|
||
}
|
||
};
|
||
|
||
_proto.onDown = function onDown(ev) {
|
||
var view = this.view;
|
||
|
||
var eventObj = this._getShapeEventObj(ev);
|
||
|
||
eventObj.shape = this.currentShape;
|
||
registerData(eventObj);
|
||
view.emit('mousedown', eventObj);
|
||
|
||
this._triggerShapeEvent(this.currentShape, 'mousedown', eventObj);
|
||
};
|
||
|
||
_proto.onMove = function onMove(ev) {
|
||
var self = this;
|
||
var view = self.view;
|
||
var currentShape = self.currentShape; // 如果图形被销毁,则设置当前 shape 为空
|
||
|
||
if (currentShape && currentShape.get('destroyed')) {
|
||
currentShape = null;
|
||
self.currentShape = null;
|
||
}
|
||
|
||
var shape = self._getShape(ev.x, ev.y) || ev.currentTarget;
|
||
|
||
var eventObj = self._getShapeEventObj(ev);
|
||
|
||
eventObj.shape = shape;
|
||
registerData(eventObj);
|
||
view.emit('mousemove', eventObj);
|
||
|
||
self._triggerShapeEvent(shape, 'mousemove', eventObj);
|
||
|
||
if (currentShape && !isSameShape(currentShape, shape)) {
|
||
var leaveObj = self._getShapeEventObj(ev);
|
||
|
||
leaveObj.shape = currentShape;
|
||
leaveObj.toShape = shape;
|
||
registerData(leaveObj);
|
||
|
||
self._triggerShapeEvent(currentShape, 'mouseleave', leaveObj);
|
||
}
|
||
|
||
if (shape && !isSameShape(currentShape, shape)) {
|
||
var enterObj = self._getShapeEventObj(ev);
|
||
|
||
enterObj.shape = shape;
|
||
enterObj.fromShape = currentShape;
|
||
registerData(enterObj);
|
||
|
||
self._triggerShapeEvent(shape, 'mouseenter', enterObj);
|
||
}
|
||
|
||
self.currentShape = shape;
|
||
|
||
var point = self._getPointInfo(ev);
|
||
|
||
var preViews = self.curViews || [];
|
||
|
||
if (preViews.length === 0 && point.views.length) {
|
||
view.emit('plotenter', self._getEventObj(ev, point, point.views));
|
||
} // point.views 是指当前 view 或者子 view,不会取跟当前 view 同一层级的兄弟元素(view)
|
||
|
||
|
||
if (preViews.length && point.views.length === 0) {
|
||
view.emit('plotleave', self._getEventObj(ev, point, preViews));
|
||
}
|
||
|
||
if (point.views.length) {
|
||
eventObj = self._getEventObj(ev, point, point.views);
|
||
eventObj.shape = shape;
|
||
registerData(eventObj);
|
||
view.emit('plotmove', eventObj);
|
||
}
|
||
|
||
self.curViews = point.views;
|
||
};
|
||
|
||
_proto.onOut = function onOut(ev) {
|
||
var self = this;
|
||
var view = self.view;
|
||
|
||
var point = self._getPointInfo(ev);
|
||
|
||
var preViews = self.curViews || [];
|
||
|
||
var evtObj = self._getEventObj(ev, point, preViews); // 只有没有padding 时,当前依然在 view 的 plotRange 情况下才会出现这个情况,保证 plotleave 触发
|
||
|
||
|
||
if (self.curViews && self.curViews.length !== 0 && (!evtObj.toElement || evtObj.toElement.tagName !== 'CANVAS')) {
|
||
view.emit('plotleave', evtObj);
|
||
self.curViews = []; // 清空
|
||
}
|
||
};
|
||
|
||
_proto.onUp = function onUp(ev) {
|
||
var view = this.view;
|
||
|
||
var eventObj = this._getShapeEventObj(ev);
|
||
|
||
eventObj.shape = this.currentShape;
|
||
view.emit('mouseup', eventObj);
|
||
|
||
this._triggerShapeEvent(this.currentShape, 'mouseup', eventObj);
|
||
};
|
||
|
||
_proto.onClick = function onClick(ev) {
|
||
var self = this;
|
||
var view = self.view;
|
||
var shape = self._getShape(ev.x, ev.y) || ev.currentTarget;
|
||
|
||
var shapeEventObj = self._getShapeEventObj(ev);
|
||
|
||
shapeEventObj.shape = shape;
|
||
registerData(shapeEventObj);
|
||
view.emit('click', shapeEventObj);
|
||
|
||
self._triggerShapeEvent(shape, ev.type, shapeEventObj);
|
||
|
||
self.currentShape = shape;
|
||
|
||
var point = self._getPointInfo(ev);
|
||
|
||
var views = point.views;
|
||
|
||
if (!Util.isEmpty(views)) {
|
||
var eventObj = self._getEventObj(ev, point, views);
|
||
|
||
if (self.currentShape) {
|
||
var _shape = self.currentShape;
|
||
eventObj.shape = _shape;
|
||
registerData(eventObj); // eventObj.data = shape.get('origin');
|
||
}
|
||
|
||
if (ev.type === 'dblclick') {
|
||
view.emit('plotdblclick', eventObj);
|
||
view.emit('dblclick', shapeEventObj);
|
||
} else {
|
||
view.emit('plotclick', eventObj);
|
||
}
|
||
}
|
||
};
|
||
|
||
_proto.onTouchstart = function onTouchstart(ev) {
|
||
var view = this.view;
|
||
var shape = this._getShape(ev.x, ev.y) || ev.currentTarget;
|
||
|
||
var eventObj = this._getShapeEventObj(ev);
|
||
|
||
eventObj.shape = shape;
|
||
registerData(eventObj);
|
||
view.emit('touchstart', eventObj);
|
||
|
||
this._triggerShapeEvent(shape, 'touchstart', eventObj);
|
||
|
||
this.currentShape = shape;
|
||
};
|
||
|
||
_proto.onTouchmove = function onTouchmove(ev) {
|
||
var view = this.view;
|
||
var shape = this._getShape(ev.x, ev.y) || ev.currentTarget;
|
||
|
||
var eventObj = this._getShapeEventObj(ev);
|
||
|
||
eventObj.shape = shape;
|
||
registerData(eventObj);
|
||
view.emit('touchmove', eventObj);
|
||
|
||
this._triggerShapeEvent(shape, 'touchmove', eventObj);
|
||
|
||
this.currentShape = shape;
|
||
};
|
||
|
||
_proto.onTouchend = function onTouchend(ev) {
|
||
var view = this.view;
|
||
|
||
var eventObj = this._getShapeEventObj(ev);
|
||
|
||
eventObj.shape = this.currentShape;
|
||
registerData(eventObj);
|
||
view.emit('touchend', eventObj);
|
||
|
||
this._triggerShapeEvent(this.currentShape, 'touchend', eventObj);
|
||
};
|
||
|
||
_proto.clearEvents = function clearEvents() {
|
||
var canvas = this.canvas;
|
||
canvas.off('mousemove', Util.getWrapBehavior(this, 'onMove'));
|
||
canvas.off('mouseleave', Util.getWrapBehavior(this, 'onOut'));
|
||
canvas.off('mousedown', Util.getWrapBehavior(this, 'onDown'));
|
||
canvas.off('mouseup', Util.getWrapBehavior(this, 'onUp'));
|
||
canvas.off('click', Util.getWrapBehavior(this, 'onClick'));
|
||
canvas.off('dblclick', Util.getWrapBehavior(this, 'onClick'));
|
||
canvas.off('touchstart', Util.getWrapBehavior(this, 'onTouchstart'));
|
||
canvas.off('touchmove', Util.getWrapBehavior(this, 'onTouchmove'));
|
||
canvas.off('touchend', Util.getWrapBehavior(this, 'onTouchend'));
|
||
};
|
||
|
||
return EventController;
|
||
}();
|
||
|
||
module.exports = EventController; |