333 lines
9.4 KiB
Java
333 lines
9.4 KiB
Java
/**
|
||
* @fileOverview the interaction when geom was actived
|
||
* @author sima.zhang
|
||
*/
|
||
var Util = require('../../util');
|
||
|
||
var FIELD_ORIGIN = '_origin';
|
||
|
||
var ZIndexUtil = require('./zindex-util');
|
||
|
||
var ATTRS_ORIGIN_ACTIVE = '_originActiveAttrs';
|
||
|
||
function isSameShape(shape1, shape2) {
|
||
if (Util.isNil(shape1) || Util.isNil(shape2)) {
|
||
return false;
|
||
}
|
||
|
||
var shape1Origin = shape1.get('origin');
|
||
var shape2Origin = shape2.get('origin');
|
||
return Util.isEqual(shape1Origin, shape2Origin);
|
||
}
|
||
|
||
function isChange(preShapes, shapes) {
|
||
if (!preShapes) {
|
||
return true;
|
||
}
|
||
|
||
if (preShapes.length !== shapes.length) {
|
||
return true;
|
||
}
|
||
|
||
var rst = false;
|
||
Util.each(shapes, function (shape, index) {
|
||
if (!isSameShape(shape, preShapes[index])) {
|
||
rst = true;
|
||
return false;
|
||
}
|
||
});
|
||
return rst;
|
||
}
|
||
|
||
function getOriginAttrs(activeCfg, shape) {
|
||
var originAttrs = {};
|
||
Util.each(activeCfg, function (v, k) {
|
||
var originValue = shape.attr(k);
|
||
|
||
if (Util.isArray(originValue)) {
|
||
originValue = Util.cloneDeep(originValue); // 缓存原来的属性,由于 .attr('matrix') 是数组,所以此处需要深度复制
|
||
}
|
||
|
||
originAttrs[k] = originValue;
|
||
});
|
||
return originAttrs;
|
||
}
|
||
|
||
var ActiveMixin = {
|
||
_isAllowActive: function _isAllowActive() {
|
||
var allowActive = this.get('allowActive');
|
||
|
||
if (Util.isNil(allowActive)) {
|
||
// 用户未设置,使用默认的策略
|
||
var view = this.get('view');
|
||
var isShareTooltip = this.isShareTooltip();
|
||
var options = view.get('options'); // 默认情况下,tooltip 关闭或者 tooltip 模式为 shared === false 的时候允许 active
|
||
|
||
if (options.tooltip === false || !isShareTooltip) {
|
||
return true;
|
||
}
|
||
} else {
|
||
return allowActive;
|
||
}
|
||
|
||
return false;
|
||
},
|
||
_onMouseenter: function _onMouseenter(ev) {
|
||
var self = this;
|
||
var shape = ev.shape;
|
||
var shapeContainer = self.get('shapeContainer');
|
||
|
||
if (shape && shapeContainer.contain(shape) && self._isAllowActive()) {
|
||
// shape.get('animating')
|
||
self.setShapesActived(shape);
|
||
}
|
||
},
|
||
_onMouseleave: function _onMouseleave() {
|
||
var self = this;
|
||
var view = self.get('view');
|
||
var canvas = view.get('canvas');
|
||
|
||
if (self.get('activeShapes')) {
|
||
self.clearActivedShapes();
|
||
canvas.draw();
|
||
}
|
||
},
|
||
_bindActiveAction: function _bindActiveAction() {
|
||
var self = this;
|
||
var view = self.get('view');
|
||
var type = self.get('type');
|
||
view.on(type + ':mouseenter', Util.wrapBehavior(self, '_onMouseenter'));
|
||
view.on(type + ':mouseleave', Util.wrapBehavior(self, '_onMouseleave'));
|
||
},
|
||
_offActiveAction: function _offActiveAction() {
|
||
var self = this;
|
||
var view = self.get('view');
|
||
var type = self.get('type');
|
||
view.off(type + ':mouseenter', Util.getWrapBehavior(self, '_onMouseenter'));
|
||
view.off(type + ':mouseleave', Util.getWrapBehavior(self, '_onMouseleave'));
|
||
},
|
||
_setActiveShape: function _setActiveShape(shape) {
|
||
var self = this;
|
||
var activedOptions = self.get('activedOptions') || {};
|
||
var shapeData = shape.get('origin');
|
||
var shapeName = shapeData.shape || self.getDefaultValue('shape');
|
||
|
||
if (Util.isArray(shapeName)) {
|
||
shapeName = shapeName[0];
|
||
}
|
||
|
||
var shapeFactory = self.get('shapeFactory');
|
||
var shapeCfg = Util.mix({}, shape.attr(), {
|
||
origin: shapeData
|
||
});
|
||
var activeCfg = shapeFactory.getActiveCfg(shapeName, shapeCfg);
|
||
|
||
if (activedOptions.style) {
|
||
Util.mix(activeCfg, activedOptions.style);
|
||
}
|
||
|
||
var originAttrs = getOriginAttrs(activeCfg, shape);
|
||
shape.setSilent(ATTRS_ORIGIN_ACTIVE, originAttrs);
|
||
|
||
if (activedOptions.animate) {
|
||
shape.animate(activeCfg, 300);
|
||
} else {
|
||
shape.attr(activeCfg);
|
||
}
|
||
|
||
ZIndexUtil.toFront(shape); // 提前
|
||
},
|
||
setShapesActived: function setShapesActived(shapes) {
|
||
var self = this;
|
||
|
||
if (!Util.isArray(shapes)) {
|
||
shapes = [shapes];
|
||
}
|
||
|
||
var preShapes = self.get('activeShapes'); // 获取上次被激活的 shapes
|
||
|
||
if (!isChange(preShapes, shapes)) {
|
||
return;
|
||
}
|
||
|
||
var view = self.get('view');
|
||
var canvas = view.get('canvas');
|
||
var activedOptions = self.get('activedOptions');
|
||
|
||
if (activedOptions && activedOptions.highlight) {
|
||
// 上次的动画未完成,所以要停止掉动画
|
||
Util.each(shapes, function (shape) {
|
||
if (shape.get('animating')) {
|
||
shape.stopAnimate();
|
||
}
|
||
});
|
||
self.highlightShapes(shapes);
|
||
} else {
|
||
if (preShapes) {
|
||
self.clearActivedShapes(); // 先清除激活元素
|
||
}
|
||
|
||
Util.each(shapes, function (shape) {
|
||
if (shape.get('animating')) {
|
||
shape.stopAnimate();
|
||
}
|
||
|
||
if (shape.get('visible')) {
|
||
// && !shape.get('selected')
|
||
self._setActiveShape(shape);
|
||
}
|
||
});
|
||
}
|
||
|
||
self.set('activeShapes', shapes); // shapeContainer.sort(); // toFront, resetZIndex 不需要再排序
|
||
|
||
canvas.draw();
|
||
},
|
||
clearActivedShapes: function clearActivedShapes() {
|
||
var self = this;
|
||
var shapeContainer = self.get('shapeContainer');
|
||
var activedOptions = self.get('activedOptions');
|
||
var activeAnimate = activedOptions && activedOptions.animate;
|
||
|
||
if (shapeContainer && !shapeContainer.get('destroyed')) {
|
||
var activeShapes = self.get('activeShapes');
|
||
Util.each(activeShapes, function (activeShape) {
|
||
// if (!activeShape.get('selected')) {
|
||
var originAttrs = activeShape.get(ATTRS_ORIGIN_ACTIVE);
|
||
|
||
if (activeAnimate) {
|
||
activeShape.stopAnimate();
|
||
activeShape.animate(originAttrs, 300);
|
||
} else {
|
||
activeShape.attr(originAttrs);
|
||
}
|
||
|
||
ZIndexUtil.resetZIndex(activeShape);
|
||
activeShape.setSilent(ATTRS_ORIGIN_ACTIVE, null); // }
|
||
});
|
||
var preHighlightShapes = self.get('preHighlightShapes');
|
||
|
||
if (preHighlightShapes) {
|
||
var shapes = shapeContainer.get('children');
|
||
Util.each(shapes, function (shape) {
|
||
// if (!shape.get('selected')) {
|
||
var originAttrs = shape.get(ATTRS_ORIGIN_ACTIVE);
|
||
|
||
if (originAttrs) {
|
||
if (activeAnimate) {
|
||
shape.stopAnimate();
|
||
shape.animate(originAttrs, 300);
|
||
} else {
|
||
shape.attr(originAttrs);
|
||
}
|
||
|
||
ZIndexUtil.resetZIndex(shape);
|
||
shape.setSilent(ATTRS_ORIGIN_ACTIVE, null);
|
||
} // }
|
||
|
||
});
|
||
} // 恢复原来排序
|
||
// const children = shapeContainer.get('children');
|
||
// children.sort((obj1, obj2) => {
|
||
// return obj1._INDEX - obj2._INDEX;
|
||
// });
|
||
|
||
|
||
self.set('activeShapes', null);
|
||
self.set('preHighlightShapes', null);
|
||
}
|
||
},
|
||
getGroupShapesByPoint: function getGroupShapesByPoint(point) {
|
||
var self = this;
|
||
var shapeContainer = self.get('shapeContainer');
|
||
var activeShapes = [];
|
||
|
||
if (shapeContainer) {
|
||
var xField = self.getXScale().field;
|
||
var shapes = self.getShapes();
|
||
|
||
var originObj = self._getOriginByPoint(point);
|
||
|
||
Util.each(shapes, function (shape) {
|
||
var origin = shape.get('origin');
|
||
|
||
if (shape.get('visible') && origin) {
|
||
// 有可能不是图形,而是label文本,所以判断一下
|
||
var shapeXValue = origin[FIELD_ORIGIN][xField];
|
||
|
||
if (shapeXValue === originObj[xField]) {
|
||
activeShapes.push(shape);
|
||
}
|
||
}
|
||
});
|
||
}
|
||
|
||
return activeShapes;
|
||
},
|
||
getSingleShapeByPoint: function getSingleShapeByPoint(point) {
|
||
var self = this;
|
||
var shapeContainer = self.get('shapeContainer');
|
||
var canvas = shapeContainer.get('canvas');
|
||
var pixelRatio = canvas.get('pixelRatio');
|
||
var result;
|
||
|
||
if (shapeContainer) {
|
||
result = shapeContainer.getShape(point.x * pixelRatio, point.y * pixelRatio);
|
||
}
|
||
|
||
if (result && result.get('origin')) {
|
||
return result;
|
||
}
|
||
},
|
||
highlightShapes: function highlightShapes(_highlightShapes, highlightCfg) {
|
||
var self = this;
|
||
|
||
if (!Util.isArray(_highlightShapes)) {
|
||
_highlightShapes = [_highlightShapes];
|
||
}
|
||
|
||
var preHighlightShapes = self.get('activeShapes'); // 获取上次被激活的 shapes
|
||
|
||
if (!isChange(preHighlightShapes, _highlightShapes)) {
|
||
return;
|
||
}
|
||
|
||
if (preHighlightShapes) {
|
||
self.clearActivedShapes();
|
||
}
|
||
|
||
var shapes = self.getShapes();
|
||
var activedOptions = self.get('activedOptions');
|
||
var activeAnimate = activedOptions && activedOptions.animate;
|
||
var activeStyle = activedOptions && activedOptions.style;
|
||
Util.each(shapes, function (shape) {
|
||
var changeAttrs = {};
|
||
shape.stopAnimate();
|
||
|
||
if (Util.indexOf(_highlightShapes, shape) !== -1) {
|
||
Util.mix(changeAttrs, activeStyle, highlightCfg); // shape.setZIndex(1); // 提前
|
||
|
||
ZIndexUtil.toFront(shape);
|
||
} else {
|
||
Util.mix(changeAttrs, {
|
||
fillOpacity: 0.3,
|
||
// @2018-07-11 by blue.lb 由于线图只有stoke,fillOpacity不生效,最好还是直接改成整个图形透明度opacity
|
||
opacity: 0.3
|
||
});
|
||
ZIndexUtil.resetZIndex(shape);
|
||
}
|
||
|
||
var originAttrs = getOriginAttrs(changeAttrs, shape);
|
||
shape.setSilent(ATTRS_ORIGIN_ACTIVE, originAttrs);
|
||
|
||
if (activeAnimate) {
|
||
shape.animate(changeAttrs, 300);
|
||
} else {
|
||
shape.attr(changeAttrs);
|
||
}
|
||
});
|
||
self.set('preHighlightShapes', _highlightShapes);
|
||
self.set('activeShapes', _highlightShapes);
|
||
}
|
||
};
|
||
module.exports = ActiveMixin; |