/** * @fileOverview the interaction when geom was selected * @author sima.zhang */ var Util = require('../../util'); var FIELD_ORIGIN = '_origin'; var ZIndexUtil = require('./zindex-util'); 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 getOriginAttrs(selectedCfg, shape) { var originAttrs = {}; Util.each(selectedCfg, function (v, k) { if (k === 'transform') { k = 'matrix'; } var originValue = shape.attr(k); if (Util.isArray(originValue)) { originValue = Util.cloneDeep(originValue); // 缓存原来的属性,由于 .attr('matrix') 是数组,所以此处需要深度复制 } originAttrs[k] = originValue; }); return originAttrs; } var SelectMixin = { _isAllowSelect: function _isAllowSelect() { var isAllowSelect = this.get('allowSelect'); if (Util.isNil(isAllowSelect)) { var type = this.get('type'); var coord = this.get('coord'); var coordType = coord && coord.type; if (type === 'interval' && coordType === 'theta') { // 饼图默认可以进行选中 return true; } } else { // 用户设置了 select 配置 return isAllowSelect; } return false; }, _onClick: function _onClick(ev) { var self = this; if (self._isAllowSelect()) { // 允许选中下才执行 // self.clearActivedShapes(); // 不需要清除hover效果 var shape = ev.shape; var shapeContainer = self.get('shapeContainer'); if (shape && shapeContainer.contain(shape)) { // 去除 !shape.get('animating') 的判定,点击反馈更加及时 self.setShapeSelected(shape); } } }, _bindSelectedAction: function _bindSelectedAction() { var self = this; var view = self.get('view'); var type = self.get('type'); view.on(type + ':click', Util.wrapBehavior(self, '_onClick')); }, _offSelectedAction: function _offSelectedAction() { var self = this; var view = self.get('view'); var type = self.get('type'); view.off(type + ':click', Util.getWrapBehavior(self, '_onClick')); }, _setShapeStatus: function _setShapeStatus(shape, status) { var self = this; var view = self.get('view'); var selectedOptions = self.get('selectedOptions') || {}; var animate = selectedOptions.animate !== false; // 默认允许动画 var canvas = view.get('canvas'); shape.set('selected', status); var shapeData = shape.get('origin'); if (status) { // 选中状态 var shapeName = shapeData.shape || self.getDefaultValue('shape'); if (Util.isArray(shapeName)) { shapeName = shapeName[0]; } var shapeFactory = self.get('shapeFactory'); var cfg = Util.mix({ geom: self, point: shapeData }, selectedOptions); var selectedStyle = shapeFactory.getSelectedCfg(shapeName, cfg); Util.mix(selectedStyle, cfg.style); // 用户设置的优先级更高 if (!shape.get('_originAttrs')) { // 缓存原有属性 if (shape.get('animating')) { // 停止动画 shape.stopAnimate(); } shape.set('_originAttrs', getOriginAttrs(selectedStyle, shape)); } // 选中时图形要到最上面 if (selectedOptions.toFront) { ZIndexUtil.toFront(shape); } if (animate) { shape.animate(selectedStyle, 300); } else { shape.attr(selectedStyle); canvas.draw(); } } else { var originAttrs = shape.get('_originAttrs'); // 取消选中时,要恢复到原先的位置 if (selectedOptions.toFront) { ZIndexUtil.resetZIndex(shape); } shape.set('_originAttrs', null); if (animate) { shape.animate(originAttrs, 300); } else { shape.attr(originAttrs); canvas.draw(); } } }, setShapeSelected: function setShapeSelected(shape) { var self = this; var selectedShapes = self._getSelectedShapes(); var selectedOptions = self.get('selectedOptions') || {}; var cancelable = selectedOptions.cancelable !== false; // 选中状态是否允许取消,默认允许 if (selectedOptions.mode === 'multiple') { // 支持多选 if (Util.indexOf(selectedShapes, shape) === -1) { selectedShapes.push(shape); self._setShapeStatus(shape, true); } else if (cancelable) { // 图形已经被选中并且选中状态允许取消选中 Util.Array.remove(selectedShapes, shape); self._setShapeStatus(shape, false); } } else { var selectedShape = selectedShapes[0]; if (cancelable) { // 如果允许取消,则选中null shape = isSameShape(selectedShape, shape) ? null : shape; } if (!isSameShape(selectedShape, shape)) { if (selectedShape) { self._setShapeStatus(selectedShape, false); } if (shape) { self._setShapeStatus(shape, true); } } } }, clearSelected: function clearSelected() { var self = this; var shapeContainer = self.get('shapeContainer'); if (shapeContainer && !shapeContainer.get('destroyed')) { var selectedShapes = self._getSelectedShapes(); Util.each(selectedShapes, function (shape) { self._setShapeStatus(shape, false); shape.set('_originAttrs', null); }); } }, /** * 设置记录对应的图形选中 * @param {Object} record 选中的记录 * @chainable * @return {Geom} 返回当前的 Geometry */ setSelected: function setSelected(record) { var self = this; var shapes = self.getShapes(); Util.each(shapes, function (shape) { var origin = shape.get('origin'); if (origin && origin[FIELD_ORIGIN] === record) { self.setShapeSelected(shape); } }); return this; }, _getSelectedShapes: function _getSelectedShapes() { var self = this; var shapes = self.getShapes(); var selectedShapes = []; Util.each(shapes, function (shape) { if (shape.get('selected')) { selectedShapes.push(shape); } }); self.set('selectedShapes', selectedShapes); return selectedShapes; } }; module.exports = SelectMixin;