/** * @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;