function _createSuper(Derived) { return function () { var Super = _getPrototypeOf(Derived), result; if (_isNativeReflectConstruct()) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; } function _possibleConstructorReturn(self, call) { if (call && (typeof call === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); } function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } } function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; subClass.__proto__ = superClass; } /** * @fileOverview The base class of continuous legend * @author sima.zhang */ var Util = require('../util'); var Legend = require('./base'); var Slider = require('./slider'); var _require = require('../const'), FONT_FAMILY = _require.FONT_FAMILY; var TRIGGER_WIDTH = 8; var Event = Util.Event; var Group = Util.Group; var Continuous = /*#__PURE__*/function (_Legend) { _inheritsLoose(Continuous, _Legend); var _super = _createSuper(Continuous); function Continuous() { return _Legend.apply(this, arguments) || this; } var _proto = Continuous.prototype; _proto.getDefaultCfg = function getDefaultCfg() { var cfg = _Legend.prototype.getDefaultCfg.call(this); return Util.mix({}, cfg, { /** * 类型 * @type {String} */ type: 'continuous-legend', /** * 子项 * @type {Array} */ items: null, /** * 布局方式 * horizontal 水平 * vertical 垂直 * @type {String} */ layout: 'vertical', /** * 宽度 * @type {Number} */ width: 20, /** * 高度 * @type {Number} */ height: 156, /** * 默认文本图形属性 * @type {ATTRS} */ textStyle: { fill: '#333', textAlign: 'center', textBaseline: 'middle', stroke: '#fff', lineWidth: 5, fontFamily: FONT_FAMILY }, hoverTextStyle: { fill: 'rgba(0,0,0,0.25)' }, /** * 连续图例是否可滑动 * @type {Boolean} */ slidable: true, /** * 两头滑块的样式 * @type {object} */ triggerAttr: { fill: '#fff', // shadowOffsetX: -2, // shadowOffsetY: 2, shadowBlur: 10, shadowColor: 'rgba(0,0,0,0.65)', radius: 2 }, /** * slider 的范围 * @type {array}} */ _range: [0, 100], /** * 中间 bar 背景灰色 * @type {ATTRS} */ middleBackgroundStyle: { fill: '#D9D9D9' }, /** * 文本与图例间距 * @type {Number} */ textOffset: 4, /** * line segment to seperate the unslidable slider blocks * @type {object} */ lineStyle: { lineWidth: 1, stroke: '#fff' }, /** * the pointer while activate the legend by mouse hovering or called by outside * @type {object} */ pointerStyle: { // color: '#ccc', fill: 'rgb(230, 230, 230)' } }); }; _proto._calStartPoint = function _calStartPoint() { var start = { x: 10, y: this.get('titleGap') - TRIGGER_WIDTH }; var titleShape = this.get('titleShape'); if (titleShape) { var titleBox = titleShape.getBBox(); start.y += titleBox.height; } return start; }; _proto.beforeRender = function beforeRender() { var items = this.get('items'); if (!Util.isArray(items) || Util.isEmpty(items)) { return; } _Legend.prototype.beforeRender.call(this); this.set('firstItem', items[0]); this.set('lastItem', items[items.length - 1]); }; _proto._formatItemValue = function _formatItemValue(value) { var formatter = this.get('formatter') || this.get('itemFormatter'); if (formatter) { value = formatter.call(this, value); } return value; }; _proto.render = function render() { _Legend.prototype.render.call(this); if (this.get('slidable')) { this._renderSlider(); } else { this._renderUnslidable(); } }; _proto._renderSlider = function _renderSlider() { var minHandleElement = new Group(); var maxHandleElement = new Group(); var backgroundElement = new Group(); var start = this._calStartPoint(); var group = this.get('group'); var slider = group.addGroup(Slider, { minHandleElement: minHandleElement, maxHandleElement: maxHandleElement, backgroundElement: backgroundElement, layout: this.get('layout'), range: this.get('_range'), width: this.get('width'), height: this.get('height') }); slider.translate(start.x, start.y); this.set('slider', slider); var shape = this._renderSliderShape(); shape.attr('clip', slider.get('middleHandleElement')); this._renderTrigger(); } // the middle bar ; _proto._addMiddleBar = function _addMiddleBar(parent, name, attrs) { // background of the middle bar parent.addShape(name, { attrs: Util.mix({}, attrs, this.get('middleBackgroundStyle')) }); // frontground of the middle bar return parent.addShape(name, { attrs: attrs }); }; _proto._renderTrigger = function _renderTrigger() { var min = this.get('firstItem'); var max = this.get('lastItem'); var layout = this.get('layout'); var textStyle = this.get('textStyle'); var triggerAttr = this.get('triggerAttr'); var minBlockAttr = Util.mix({}, triggerAttr); var maxBlockAttr = Util.mix({}, triggerAttr); var minTextAttr = Util.mix({ text: this._formatItemValue(min.value) + '' }, textStyle); var maxTextAttr = Util.mix({ text: this._formatItemValue(max.value) + '' }, textStyle); if (layout === 'vertical') { this._addVerticalTrigger('min', minBlockAttr, minTextAttr); this._addVerticalTrigger('max', maxBlockAttr, maxTextAttr); } else { this._addHorizontalTrigger('min', minBlockAttr, minTextAttr); this._addHorizontalTrigger('max', maxBlockAttr, maxTextAttr); } }; _proto._addVerticalTrigger = function _addVerticalTrigger(type, blockAttr, textAttr) { var slider = this.get('slider'); var trigger = slider.get(type + 'HandleElement'); var width = this.get('width'); var button = trigger.addShape('rect', { attrs: Util.mix({ x: width / 2 - TRIGGER_WIDTH - 2, y: type === 'min' ? 0 : -TRIGGER_WIDTH, width: 2 * TRIGGER_WIDTH + 2, height: TRIGGER_WIDTH }, blockAttr) }); var text = trigger.addShape('text', { attrs: Util.mix(textAttr, { x: width + this.get('textOffset'), y: type === 'max' ? -4 : 4, textAlign: 'start', lineHeight: 1, textBaseline: 'middle' }) }); var layout = this.get('layout'); var trigerCursor = layout === 'vertical' ? 'ns-resize' : 'ew-resize'; button.attr('cursor', trigerCursor); text.attr('cursor', trigerCursor); this.set(type + 'ButtonElement', button); this.set(type + 'TextElement', text); }; _proto._addHorizontalTrigger = function _addHorizontalTrigger(type, blockAttr, textAttr) { var slider = this.get('slider'); var trigger = slider.get(type + 'HandleElement'); var button = trigger.addShape('rect', { attrs: Util.mix({ x: type === 'min' ? -TRIGGER_WIDTH : 0, y: -TRIGGER_WIDTH - this.get('height') / 2, width: TRIGGER_WIDTH, height: 2 * TRIGGER_WIDTH }, blockAttr) }); var text = trigger.addShape('text', { attrs: Util.mix(textAttr, { x: type === 'min' ? -TRIGGER_WIDTH - 4 : TRIGGER_WIDTH + 4, y: TRIGGER_WIDTH / 2 + this.get('textOffset') + 10, textAlign: type === 'min' ? 'end' : 'start', textBaseline: 'middle' }) }); var layout = this.get('layout'); var trigerCursor = layout === 'vertical' ? 'ns-resize' : 'ew-resize'; button.attr('cursor', trigerCursor); text.attr('cursor', trigerCursor); this.set(type + 'ButtonElement', button); this.set(type + 'TextElement', text); }; _proto._bindEvents = function _bindEvents() { var _this = this; if (this.get('slidable')) { var slider = this.get('slider'); slider.on('sliderchange', function (ev) { var range = ev.range; var firstItemValue = _this.get('firstItem').value; var lastItemValue = _this.get('lastItem').value; var minValue = firstItemValue + range[0] / 100 * (lastItemValue - firstItemValue); var maxValue = firstItemValue + range[1] / 100 * (lastItemValue - firstItemValue); _this._updateElement(minValue, maxValue); var itemFiltered = new Event('itemfilter', ev, true, true); itemFiltered.range = [minValue, maxValue]; _this.emit('itemfilter', itemFiltered); }); } if (this.get('hoverable')) { this.get('group').on('mousemove', Util.wrapBehavior(this, '_onMouseMove')); this.get('group').on('mouseleave', Util.wrapBehavior(this, '_onMouseLeave')); } } // update the text of min and max trigger ; _proto._updateElement = function _updateElement(min, max) { var minTextElement = this.get('minTextElement'); var maxTextElement = this.get('maxTextElement'); if (max > 1) { // 对于大于 1 的值,默认显示为整数 min = parseInt(min, 10); max = parseInt(max, 10); } minTextElement.attr('text', this._formatItemValue(min) + ''); maxTextElement.attr('text', this._formatItemValue(max) + ''); }; _proto._onMouseLeave = function _onMouseLeave() { var hoverPointer = this.get('group').findById('hoverPointer'); hoverPointer && hoverPointer.destroy(); var hoverText = this.get('group').findById('hoverText'); hoverText && hoverText.destroy(); this.get('canvas').draw(); } // activate the legend while mouse moving ; _proto._onMouseMove = function _onMouseMove(ev) { var height = this.get('height'); var width = this.get('width'); var items = this.get('items'); var el = this.get('canvas').get('el'); var el_bbox = el.getBoundingClientRect(); var bbox = this.get('group').getBBox(); var value; if (this.get('layout') === 'vertical') { var valuePadding = 5; if (this.get('type') === 'color-legend') { valuePadding = 30; } var titleOffset = this.get('titleGap'); var titleShape = this.get('titleShape'); if (titleShape) titleOffset += titleShape.getBBox().maxY - titleShape.getBBox().minY; var currentPage = ev.clientY || ev.event.clientY; currentPage = currentPage - el_bbox.y - this.get('group').attr('matrix')[7] + bbox.y - valuePadding + titleOffset; value = items[0].value + (1 - currentPage / height) * (items[items.length - 1].value - items[0].value); } else { var _currentPage = ev.clientX || ev.event.clientX; _currentPage = _currentPage - el_bbox.x - this.get('group').attr('matrix')[6]; value = items[0].value + _currentPage / width * (items[items.length - 1].value - items[0].value); } value = value.toFixed(2); this.activate(value); this.emit('mousehover', { value: value }); } // activated by mouse moving or being called ; _proto.activate = function activate(value) { if (!value) { return; } var hoverPointer = this.get('group').findById('hoverPointer'); var hoverText = this.get('group').findById('hoverText'); var items = this.get('items'); if (value < items[0].value || value > items[items.length - 1].value) { return; } var height = this.get('height'); var width = this.get('width'); var titleShape = this.get('titleShape'); var titleGap = this.get('titleGap'); var points = []; var page = (value - items[0].value) / (items[items.length - 1].value - items[0].value); var textStyle; if (this.get('layout') === 'vertical') { // revise the offset var paddingY = 0, paddingX = 0; if (this.get('type') === 'color-legend') { paddingY = titleGap; if (titleShape) paddingY += titleShape.getBBox().height; } if (this.get('slidable')) { if (this.get('type') === 'color-legend') { paddingY -= 13; } else { paddingY = titleGap - 15; if (titleShape) paddingY += titleShape.getBBox().height; } paddingX += 10; } page = (1 - page) * height; points = [[paddingX, page + paddingY], [paddingX - 10, page + paddingY - 5], [paddingX - 10, page + paddingY + 5]]; textStyle = Util.mix({}, { x: width + this.get('textOffset') / 2 + paddingX, y: page + paddingY, text: this._formatItemValue(value) + '' // 以字符串格式展示 }, this.get('textStyle'), { textAlign: 'start' }); } else { var _paddingY = 0, _paddingX = 0; if (this.get('type') === 'color-legend') { _paddingY = titleGap; if (titleShape) _paddingY += titleShape.getBBox().height; } if (this.get('slidable')) { if (this.get('type') === 'color-legend') { // hoverPointer三角形的高 _paddingY -= 7; } else { _paddingY = titleGap; if (!titleShape) _paddingY -= 7; } _paddingX += 10; } page *= width; points = [[page + _paddingX, _paddingY], [page + _paddingX - 5, _paddingY - 10], [page + _paddingX + 5, _paddingY - 10]]; textStyle = Util.mix({}, { x: page - 5, y: height + this.get('textOffset') + _paddingY, text: this._formatItemValue(value) + '' // 以字符串格式展示 }, this.get('textStyle')); } var hoverTextStyle = Util.mix(textStyle, this.get('hoverTextStyle')); if (!hoverText) { // mouse enter the legend, add hoverText hoverText = this.get('group').addShape('text', { attrs: hoverTextStyle }); hoverText.set('id', 'hoverText'); } else { // mouse move, update hoverText hoverText.attr(hoverTextStyle); } if (!hoverPointer) { // mouse enter the legend, add hoverPointer hoverPointer = this.get('group').addShape('Polygon', { attrs: Util.mix({ points: points }, this.get('pointerStyle')) }); hoverPointer.set('id', 'hoverPointer'); } else { // mouse move, update hoverPointer hoverPointer.attr(Util.mix({ points: points }, this.get('pointerStyle'))); } this.get('canvas').draw(); }; _proto.deactivate = function deactivate() { var hoverPointer = this.get('group').findById('hoverPointer'); hoverPointer && hoverPointer.destroy(); var hoverText = this.get('group').findById('hoverText'); hoverText && hoverText.destroy(); this.get('canvas').draw(); }; return Continuous; }(Legend); module.exports = Continuous;