/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ /** * AUTO-GENERATED FILE. DO NOT MODIFY. */ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import { __extends } from "tslib"; import { bind, each, isFunction, isString, indexOf } from 'zrender/lib/core/util.js'; import * as eventTool from 'zrender/lib/core/event.js'; import * as graphic from '../../util/graphic.js'; import * as throttle from '../../util/throttle.js'; import DataZoomView from './DataZoomView.js'; import { linearMap, asc, parsePercent } from '../../util/number.js'; import * as layout from '../../util/layout.js'; import sliderMove from '../helper/sliderMove.js'; import { getAxisMainType, collectReferCoordSysModelInfo } from './helper.js'; import { enableHoverEmphasis } from '../../util/states.js'; import { createSymbol, symbolBuildProxies } from '../../util/symbol.js'; import { deprecateLog } from '../../util/log.js'; import { createTextStyle } from '../../label/labelStyle.js'; var Rect = graphic.Rect; // Constants var DEFAULT_LOCATION_EDGE_GAP = 7; var DEFAULT_FRAME_BORDER_WIDTH = 1; var DEFAULT_FILLER_SIZE = 30; var DEFAULT_MOVE_HANDLE_SIZE = 7; var HORIZONTAL = 'horizontal'; var VERTICAL = 'vertical'; var LABEL_GAP = 5; var SHOW_DATA_SHADOW_SERIES_TYPE = ['line', 'bar', 'candlestick', 'scatter']; var REALTIME_ANIMATION_CONFIG = { easing: 'cubicOut', duration: 100, delay: 0 }; var SliderZoomView = /** @class */function (_super) { __extends(SliderZoomView, _super); function SliderZoomView() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.type = SliderZoomView.type; _this._displayables = {}; return _this; } SliderZoomView.prototype.init = function (ecModel, api) { this.api = api; // A unique handler for each dataZoom component this._onBrush = bind(this._onBrush, this); this._onBrushEnd = bind(this._onBrushEnd, this); }; SliderZoomView.prototype.render = function (dataZoomModel, ecModel, api, payload) { _super.prototype.render.apply(this, arguments); throttle.createOrUpdate(this, '_dispatchZoomAction', dataZoomModel.get('throttle'), 'fixRate'); this._orient = dataZoomModel.getOrient(); if (dataZoomModel.get('show') === false) { this.group.removeAll(); return; } if (dataZoomModel.noTarget()) { this._clear(); this.group.removeAll(); return; } // Notice: this._resetInterval() should not be executed when payload.type // is 'dataZoom', origin this._range should be maintained, otherwise 'pan' // or 'zoom' info will be missed because of 'throttle' of this.dispatchAction, if (!payload || payload.type !== 'dataZoom' || payload.from !== this.uid) { this._buildView(); } this._updateView(); }; SliderZoomView.prototype.dispose = function () { this._clear(); _super.prototype.dispose.apply(this, arguments); }; SliderZoomView.prototype._clear = function () { throttle.clear(this, '_dispatchZoomAction'); var zr = this.api.getZr(); zr.off('mousemove', this._onBrush); zr.off('mouseup', this._onBrushEnd); }; SliderZoomView.prototype._buildView = function () { var thisGroup = this.group; thisGroup.removeAll(); this._brushing = false; this._displayables.brushRect = null; this._resetLocation(); this._resetInterval(); var barGroup = this._displayables.sliderGroup = new graphic.Group(); this._renderBackground(); this._renderHandle(); this._renderDataShadow(); thisGroup.add(barGroup); this._positionGroup(); }; SliderZoomView.prototype._resetLocation = function () { var dataZoomModel = this.dataZoomModel; var api = this.api; var showMoveHandle = dataZoomModel.get('brushSelect'); var moveHandleSize = showMoveHandle ? DEFAULT_MOVE_HANDLE_SIZE : 0; // If some of x/y/width/height are not specified, // auto-adapt according to target grid. var coordRect = this._findCoordRect(); var ecSize = { width: api.getWidth(), height: api.getHeight() }; // Default align by coordinate system rect. var positionInfo = this._orient === HORIZONTAL ? { // Why using 'right', because right should be used in vertical, // and it is better to be consistent for dealing with position param merge. right: ecSize.width - coordRect.x - coordRect.width, top: ecSize.height - DEFAULT_FILLER_SIZE - DEFAULT_LOCATION_EDGE_GAP - moveHandleSize, width: coordRect.width, height: DEFAULT_FILLER_SIZE } : { right: DEFAULT_LOCATION_EDGE_GAP, top: coordRect.y, width: DEFAULT_FILLER_SIZE, height: coordRect.height }; // Do not write back to option and replace value 'ph', because // the 'ph' value should be recalculated when resize. var layoutParams = layout.getLayoutParams(dataZoomModel.option); // Replace the placeholder value. each(['right', 'top', 'width', 'height'], function (name) { if (layoutParams[name] === 'ph') { layoutParams[name] = positionInfo[name]; } }); var layoutRect = layout.getLayoutRect(layoutParams, ecSize); this._location = { x: layoutRect.x, y: layoutRect.y }; this._size = [layoutRect.width, layoutRect.height]; this._orient === VERTICAL && this._size.reverse(); }; SliderZoomView.prototype._positionGroup = function () { var thisGroup = this.group; var location = this._location; var orient = this._orient; // Just use the first axis to determine mapping. var targetAxisModel = this.dataZoomModel.getFirstTargetAxisModel(); var inverse = targetAxisModel && targetAxisModel.get('inverse'); var sliderGroup = this._displayables.sliderGroup; var otherAxisInverse = (this._dataShadowInfo || {}).otherAxisInverse; // Transform barGroup. sliderGroup.attr(orient === HORIZONTAL && !inverse ? { scaleY: otherAxisInverse ? 1 : -1, scaleX: 1 } : orient === HORIZONTAL && inverse ? { scaleY: otherAxisInverse ? 1 : -1, scaleX: -1 } : orient === VERTICAL && !inverse ? { scaleY: otherAxisInverse ? -1 : 1, scaleX: 1, rotation: Math.PI / 2 } // Don't use Math.PI, considering shadow direction. : { scaleY: otherAxisInverse ? -1 : 1, scaleX: -1, rotation: Math.PI / 2 }); // Position barGroup var rect = thisGroup.getBoundingRect([sliderGroup]); thisGroup.x = location.x - rect.x; thisGroup.y = location.y - rect.y; thisGroup.markRedraw(); }; SliderZoomView.prototype._getViewExtent = function () { return [0, this._size[0]]; }; SliderZoomView.prototype._renderBackground = function () { var dataZoomModel = this.dataZoomModel; var size = this._size; var barGroup = this._displayables.sliderGroup; var brushSelect = dataZoomModel.get('brushSelect'); barGroup.add(new Rect({ silent: true, shape: { x: 0, y: 0, width: size[0], height: size[1] }, style: { fill: dataZoomModel.get('backgroundColor') }, z2: -40 })); // Click panel, over shadow, below handles. var clickPanel = new Rect({ shape: { x: 0, y: 0, width: size[0], height: size[1] }, style: { fill: 'transparent' }, z2: 0, onclick: bind(this._onClickPanel, this) }); var zr = this.api.getZr(); if (brushSelect) { clickPanel.on('mousedown', this._onBrushStart, this); clickPanel.cursor = 'crosshair'; zr.on('mousemove', this._onBrush); zr.on('mouseup', this._onBrushEnd); } else { zr.off('mousemove', this._onBrush); zr.off('mouseup', this._onBrushEnd); } barGroup.add(clickPanel); }; SliderZoomView.prototype._renderDataShadow = function () { var info = this._dataShadowInfo = this._prepareDataShadowInfo(); this._displayables.dataShadowSegs = []; if (!info) { return; } var size = this._size; var oldSize = this._shadowSize || []; var seriesModel = info.series; var data = seriesModel.getRawData(); var candlestickDim = seriesModel.getShadowDim && seriesModel.getShadowDim(); var otherDim = candlestickDim && data.getDimensionInfo(candlestickDim) ? seriesModel.getShadowDim() // @see candlestick : info.otherDim; if (otherDim == null) { return; } var polygonPts = this._shadowPolygonPts; var polylinePts = this._shadowPolylinePts; // Not re-render if data doesn't change. if (data !== this._shadowData || otherDim !== this._shadowDim || size[0] !== oldSize[0] || size[1] !== oldSize[1]) { var otherDataExtent_1 = data.getDataExtent(otherDim); // Nice extent. var otherOffset = (otherDataExtent_1[1] - otherDataExtent_1[0]) * 0.3; otherDataExtent_1 = [otherDataExtent_1[0] - otherOffset, otherDataExtent_1[1] + otherOffset]; var otherShadowExtent_1 = [0, size[1]]; var thisShadowExtent = [0, size[0]]; var areaPoints_1 = [[size[0], 0], [0, 0]]; var linePoints_1 = []; var step_1 = thisShadowExtent[1] / (data.count() - 1); var thisCoord_1 = 0; // Optimize for large data shadow var stride_1 = Math.round(data.count() / size[0]); var lastIsEmpty_1; data.each([otherDim], function (value, index) { if (stride_1 > 0 && index % stride_1) { thisCoord_1 += step_1; return; } // FIXME // Should consider axis.min/axis.max when drawing dataShadow. // FIXME // 应该使用统一的空判断?还是在list里进行空判断? var isEmpty = value == null || isNaN(value) || value === ''; // See #4235. var otherCoord = isEmpty ? 0 : linearMap(value, otherDataExtent_1, otherShadowExtent_1, true); // Attempt to draw data shadow precisely when there are empty value. if (isEmpty && !lastIsEmpty_1 && index) { areaPoints_1.push([areaPoints_1[areaPoints_1.length - 1][0], 0]); linePoints_1.push([linePoints_1[linePoints_1.length - 1][0], 0]); } else if (!isEmpty && lastIsEmpty_1) { areaPoints_1.push([thisCoord_1, 0]); linePoints_1.push([thisCoord_1, 0]); } areaPoints_1.push([thisCoord_1, otherCoord]); linePoints_1.push([thisCoord_1, otherCoord]); thisCoord_1 += step_1; lastIsEmpty_1 = isEmpty; }); polygonPts = this._shadowPolygonPts = areaPoints_1; polylinePts = this._shadowPolylinePts = linePoints_1; } this._shadowData = data; this._shadowDim = otherDim; this._shadowSize = [size[0], size[1]]; var dataZoomModel = this.dataZoomModel; function createDataShadowGroup(isSelectedArea) { var model = dataZoomModel.getModel(isSelectedArea ? 'selectedDataBackground' : 'dataBackground'); var group = new graphic.Group(); var polygon = new graphic.Polygon({ shape: { points: polygonPts }, segmentIgnoreThreshold: 1, style: model.getModel('areaStyle').getAreaStyle(), silent: true, z2: -20 }); var polyline = new graphic.Polyline({ shape: { points: polylinePts }, segmentIgnoreThreshold: 1, style: model.getModel('lineStyle').getLineStyle(), silent: true, z2: -19 }); group.add(polygon); group.add(polyline); return group; } // let dataBackgroundModel = dataZoomModel.getModel('dataBackground'); for (var i = 0; i < 3; i++) { var group = createDataShadowGroup(i === 1); this._displayables.sliderGroup.add(group); this._displayables.dataShadowSegs.push(group); } }; SliderZoomView.prototype._prepareDataShadowInfo = function () { var dataZoomModel = this.dataZoomModel; var showDataShadow = dataZoomModel.get('showDataShadow'); if (showDataShadow === false) { return; } // Find a representative series. var result; var ecModel = this.ecModel; dataZoomModel.eachTargetAxis(function (axisDim, axisIndex) { var seriesModels = dataZoomModel.getAxisProxy(axisDim, axisIndex).getTargetSeriesModels(); each(seriesModels, function (seriesModel) { if (result) { return; } if (showDataShadow !== true && indexOf(SHOW_DATA_SHADOW_SERIES_TYPE, seriesModel.get('type')) < 0) { return; } var thisAxis = ecModel.getComponent(getAxisMainType(axisDim), axisIndex).axis; var otherDim = getOtherDim(axisDim); var otherAxisInverse; var coordSys = seriesModel.coordinateSystem; if (otherDim != null && coordSys.getOtherAxis) { otherAxisInverse = coordSys.getOtherAxis(thisAxis).inverse; } otherDim = seriesModel.getData().mapDimension(otherDim); result = { thisAxis: thisAxis, series: seriesModel, thisDim: axisDim, otherDim: otherDim, otherAxisInverse: otherAxisInverse }; }, this); }, this); return result; }; SliderZoomView.prototype._renderHandle = function () { var thisGroup = this.group; var displayables = this._displayables; var handles = displayables.handles = [null, null]; var handleLabels = displayables.handleLabels = [null, null]; var sliderGroup = this._displayables.sliderGroup; var size = this._size; var dataZoomModel = this.dataZoomModel; var api = this.api; var borderRadius = dataZoomModel.get('borderRadius') || 0; var brushSelect = dataZoomModel.get('brushSelect'); var filler = displayables.filler = new Rect({ silent: brushSelect, style: { fill: dataZoomModel.get('fillerColor') }, textConfig: { position: 'inside' } }); sliderGroup.add(filler); // Frame border. sliderGroup.add(new Rect({ silent: true, subPixelOptimize: true, shape: { x: 0, y: 0, width: size[0], height: size[1], r: borderRadius }, style: { // deprecated option stroke: dataZoomModel.get('dataBackgroundColor') || dataZoomModel.get('borderColor'), lineWidth: DEFAULT_FRAME_BORDER_WIDTH, fill: 'rgba(0,0,0,0)' } })); // Left and right handle to resize each([0, 1], function (handleIndex) { var iconStr = dataZoomModel.get('handleIcon'); if (!symbolBuildProxies[iconStr] && iconStr.indexOf('path://') < 0 && iconStr.indexOf('image://') < 0) { // Compatitable with the old icon parsers. Which can use a path string without path:// iconStr = 'path://' + iconStr; if (process.env.NODE_ENV !== 'production') { deprecateLog('handleIcon now needs \'path://\' prefix when using a path string'); } } var path = createSymbol(iconStr, -1, 0, 2, 2, null, true); path.attr({ cursor: getCursor(this._orient), draggable: true, drift: bind(this._onDragMove, this, handleIndex), ondragend: bind(this._onDragEnd, this), onmouseover: bind(this._showDataInfo, this, true), onmouseout: bind(this._showDataInfo, this, false), z2: 5 }); var bRect = path.getBoundingRect(); var handleSize = dataZoomModel.get('handleSize'); this._handleHeight = parsePercent(handleSize, this._size[1]); this._handleWidth = bRect.width / bRect.height * this._handleHeight; path.setStyle(dataZoomModel.getModel('handleStyle').getItemStyle()); path.style.strokeNoScale = true; path.rectHover = true; path.ensureState('emphasis').style = dataZoomModel.getModel(['emphasis', 'handleStyle']).getItemStyle(); enableHoverEmphasis(path); var handleColor = dataZoomModel.get('handleColor'); // deprecated option // Compatitable with previous version if (handleColor != null) { path.style.fill = handleColor; } sliderGroup.add(handles[handleIndex] = path); var textStyleModel = dataZoomModel.getModel('textStyle'); thisGroup.add(handleLabels[handleIndex] = new graphic.Text({ silent: true, invisible: true, style: createTextStyle(textStyleModel, { x: 0, y: 0, text: '', verticalAlign: 'middle', align: 'center', fill: textStyleModel.getTextColor(), font: textStyleModel.getFont() }), z2: 10 })); }, this); // Handle to move. Only visible when brushSelect is set true. var actualMoveZone = filler; if (brushSelect) { var moveHandleHeight = parsePercent(dataZoomModel.get('moveHandleSize'), size[1]); var moveHandle_1 = displayables.moveHandle = new graphic.Rect({ style: dataZoomModel.getModel('moveHandleStyle').getItemStyle(), silent: true, shape: { r: [0, 0, 2, 2], y: size[1] - 0.5, height: moveHandleHeight } }); var iconSize = moveHandleHeight * 0.8; var moveHandleIcon = displayables.moveHandleIcon = createSymbol(dataZoomModel.get('moveHandleIcon'), -iconSize / 2, -iconSize / 2, iconSize, iconSize, '#fff', true); moveHandleIcon.silent = true; moveHandleIcon.y = size[1] + moveHandleHeight / 2 - 0.5; moveHandle_1.ensureState('emphasis').style = dataZoomModel.getModel(['emphasis', 'moveHandleStyle']).getItemStyle(); var moveZoneExpandSize = Math.min(size[1] / 2, Math.max(moveHandleHeight, 10)); actualMoveZone = displayables.moveZone = new graphic.Rect({ invisible: true, shape: { y: size[1] - moveZoneExpandSize, height: moveHandleHeight + moveZoneExpandSize } }); actualMoveZone.on('mouseover', function () { api.enterEmphasis(moveHandle_1); }).on('mouseout', function () { api.leaveEmphasis(moveHandle_1); }); sliderGroup.add(moveHandle_1); sliderGroup.add(moveHandleIcon); sliderGroup.add(actualMoveZone); } actualMoveZone.attr({ draggable: true, cursor: getCursor(this._orient), drift: bind(this._onDragMove, this, 'all'), ondragstart: bind(this._showDataInfo, this, true), ondragend: bind(this._onDragEnd, this), onmouseover: bind(this._showDataInfo, this, true), onmouseout: bind(this._showDataInfo, this, false) }); }; SliderZoomView.prototype._resetInterval = function () { var range = this._range = this.dataZoomModel.getPercentRange(); var viewExtent = this._getViewExtent(); this._handleEnds = [linearMap(range[0], [0, 100], viewExtent, true), linearMap(range[1], [0, 100], viewExtent, true)]; }; SliderZoomView.prototype._updateInterval = function (handleIndex, delta) { var dataZoomModel = this.dataZoomModel; var handleEnds = this._handleEnds; var viewExtend = this._getViewExtent(); var minMaxSpan = dataZoomModel.findRepresentativeAxisProxy().getMinMaxSpan(); var percentExtent = [0, 100]; sliderMove(delta, handleEnds, viewExtend, dataZoomModel.get('zoomLock') ? 'all' : handleIndex, minMaxSpan.minSpan != null ? linearMap(minMaxSpan.minSpan, percentExtent, viewExtend, true) : null, minMaxSpan.maxSpan != null ? linearMap(minMaxSpan.maxSpan, percentExtent, viewExtend, true) : null); var lastRange = this._range; var range = this._range = asc([linearMap(handleEnds[0], viewExtend, percentExtent, true), linearMap(handleEnds[1], viewExtend, percentExtent, true)]); return !lastRange || lastRange[0] !== range[0] || lastRange[1] !== range[1]; }; SliderZoomView.prototype._updateView = function (nonRealtime) { var displaybles = this._displayables; var handleEnds = this._handleEnds; var handleInterval = asc(handleEnds.slice()); var size = this._size; each([0, 1], function (handleIndex) { // Handles var handle = displaybles.handles[handleIndex]; var handleHeight = this._handleHeight; handle.attr({ scaleX: handleHeight / 2, scaleY: handleHeight / 2, // This is a trick, by adding an extra tiny offset to let the default handle's end point align to the drag window. // NOTE: It may affect some custom shapes a bit. But we prefer to have better result by default. x: handleEnds[handleIndex] + (handleIndex ? -1 : 1), y: size[1] / 2 - handleHeight / 2 }); }, this); // Filler displaybles.filler.setShape({ x: handleInterval[0], y: 0, width: handleInterval[1] - handleInterval[0], height: size[1] }); var viewExtent = { x: handleInterval[0], width: handleInterval[1] - handleInterval[0] }; // Move handle if (displaybles.moveHandle) { displaybles.moveHandle.setShape(viewExtent); displaybles.moveZone.setShape(viewExtent); // Force update path on the invisible object displaybles.moveZone.getBoundingRect(); displaybles.moveHandleIcon && displaybles.moveHandleIcon.attr('x', viewExtent.x + viewExtent.width / 2); } // update clip path of shadow. var dataShadowSegs = displaybles.dataShadowSegs; var segIntervals = [0, handleInterval[0], handleInterval[1], size[0]]; for (var i = 0; i < dataShadowSegs.length; i++) { var segGroup = dataShadowSegs[i]; var clipPath = segGroup.getClipPath(); if (!clipPath) { clipPath = new graphic.Rect(); segGroup.setClipPath(clipPath); } clipPath.setShape({ x: segIntervals[i], y: 0, width: segIntervals[i + 1] - segIntervals[i], height: size[1] }); } this._updateDataInfo(nonRealtime); }; SliderZoomView.prototype._updateDataInfo = function (nonRealtime) { var dataZoomModel = this.dataZoomModel; var displaybles = this._displayables; var handleLabels = displaybles.handleLabels; var orient = this._orient; var labelTexts = ['', '']; // FIXME // date型,支持formatter,autoformatter(ec2 date.getAutoFormatter) if (dataZoomModel.get('showDetail')) { var axisProxy = dataZoomModel.findRepresentativeAxisProxy(); if (axisProxy) { var axis = axisProxy.getAxisModel().axis; var range = this._range; var dataInterval = nonRealtime // See #4434, data and axis are not processed and reset yet in non-realtime mode. ? axisProxy.calculateDataWindow({ start: range[0], end: range[1] }).valueWindow : axisProxy.getDataValueWindow(); labelTexts = [this._formatLabel(dataInterval[0], axis), this._formatLabel(dataInterval[1], axis)]; } } var orderedHandleEnds = asc(this._handleEnds.slice()); setLabel.call(this, 0); setLabel.call(this, 1); function setLabel(handleIndex) { // Label // Text should not transform by barGroup. // Ignore handlers transform var barTransform = graphic.getTransform(displaybles.handles[handleIndex].parent, this.group); var direction = graphic.transformDirection(handleIndex === 0 ? 'right' : 'left', barTransform); var offset = this._handleWidth / 2 + LABEL_GAP; var textPoint = graphic.applyTransform([orderedHandleEnds[handleIndex] + (handleIndex === 0 ? -offset : offset), this._size[1] / 2], barTransform); handleLabels[handleIndex].setStyle({ x: textPoint[0], y: textPoint[1], verticalAlign: orient === HORIZONTAL ? 'middle' : direction, align: orient === HORIZONTAL ? direction : 'center', text: labelTexts[handleIndex] }); } }; SliderZoomView.prototype._formatLabel = function (value, axis) { var dataZoomModel = this.dataZoomModel; var labelFormatter = dataZoomModel.get('labelFormatter'); var labelPrecision = dataZoomModel.get('labelPrecision'); if (labelPrecision == null || labelPrecision === 'auto') { labelPrecision = axis.getPixelPrecision(); } var valueStr = value == null || isNaN(value) ? '' // FIXME Glue code : axis.type === 'category' || axis.type === 'time' ? axis.scale.getLabel({ value: Math.round(value) }) // param of toFixed should less then 20. : value.toFixed(Math.min(labelPrecision, 20)); return isFunction(labelFormatter) ? labelFormatter(value, valueStr) : isString(labelFormatter) ? labelFormatter.replace('{value}', valueStr) : valueStr; }; /** * @param showOrHide true: show, false: hide */ SliderZoomView.prototype._showDataInfo = function (showOrHide) { // Always show when drgging. showOrHide = this._dragging || showOrHide; var displayables = this._displayables; var handleLabels = displayables.handleLabels; handleLabels[0].attr('invisible', !showOrHide); handleLabels[1].attr('invisible', !showOrHide); // Highlight move handle displayables.moveHandle && this.api[showOrHide ? 'enterEmphasis' : 'leaveEmphasis'](displayables.moveHandle, 1); }; SliderZoomView.prototype._onDragMove = function (handleIndex, dx, dy, event) { this._dragging = true; // For mobile device, prevent screen slider on the button. eventTool.stop(event.event); // Transform dx, dy to bar coordination. var barTransform = this._displayables.sliderGroup.getLocalTransform(); var vertex = graphic.applyTransform([dx, dy], barTransform, true); var changed = this._updateInterval(handleIndex, vertex[0]); var realtime = this.dataZoomModel.get('realtime'); this._updateView(!realtime); // Avoid dispatch dataZoom repeatly but range not changed, // which cause bad visual effect when progressive enabled. changed && realtime && this._dispatchZoomAction(true); }; SliderZoomView.prototype._onDragEnd = function () { this._dragging = false; this._showDataInfo(false); // While in realtime mode and stream mode, dispatch action when // drag end will cause the whole view rerender, which is unnecessary. var realtime = this.dataZoomModel.get('realtime'); !realtime && this._dispatchZoomAction(false); }; SliderZoomView.prototype._onClickPanel = function (e) { var size = this._size; var localPoint = this._displayables.sliderGroup.transformCoordToLocal(e.offsetX, e.offsetY); if (localPoint[0] < 0 || localPoint[0] > size[0] || localPoint[1] < 0 || localPoint[1] > size[1]) { return; } var handleEnds = this._handleEnds; var center = (handleEnds[0] + handleEnds[1]) / 2; var changed = this._updateInterval('all', localPoint[0] - center); this._updateView(); changed && this._dispatchZoomAction(false); }; SliderZoomView.prototype._onBrushStart = function (e) { var x = e.offsetX; var y = e.offsetY; this._brushStart = new graphic.Point(x, y); this._brushing = true; this._brushStartTime = +new Date(); // this._updateBrushRect(x, y); }; SliderZoomView.prototype._onBrushEnd = function (e) { if (!this._brushing) { return; } var brushRect = this._displayables.brushRect; this._brushing = false; if (!brushRect) { return; } brushRect.attr('ignore', true); var brushShape = brushRect.shape; var brushEndTime = +new Date(); // console.log(brushEndTime - this._brushStartTime); if (brushEndTime - this._brushStartTime < 200 && Math.abs(brushShape.width) < 5) { // Will treat it as a click return; } var viewExtend = this._getViewExtent(); var percentExtent = [0, 100]; this._range = asc([linearMap(brushShape.x, viewExtend, percentExtent, true), linearMap(brushShape.x + brushShape.width, viewExtend, percentExtent, true)]); this._handleEnds = [brushShape.x, brushShape.x + brushShape.width]; this._updateView(); this._dispatchZoomAction(false); }; SliderZoomView.prototype._onBrush = function (e) { if (this._brushing) { // For mobile device, prevent screen slider on the button. eventTool.stop(e.event); this._updateBrushRect(e.offsetX, e.offsetY); } }; SliderZoomView.prototype._updateBrushRect = function (mouseX, mouseY) { var displayables = this._displayables; var dataZoomModel = this.dataZoomModel; var brushRect = displayables.brushRect; if (!brushRect) { brushRect = displayables.brushRect = new Rect({ silent: true, style: dataZoomModel.getModel('brushStyle').getItemStyle() }); displayables.sliderGroup.add(brushRect); } brushRect.attr('ignore', false); var brushStart = this._brushStart; var sliderGroup = this._displayables.sliderGroup; var endPoint = sliderGroup.transformCoordToLocal(mouseX, mouseY); var startPoint = sliderGroup.transformCoordToLocal(brushStart.x, brushStart.y); var size = this._size; endPoint[0] = Math.max(Math.min(size[0], endPoint[0]), 0); brushRect.setShape({ x: startPoint[0], y: 0, width: endPoint[0] - startPoint[0], height: size[1] }); }; /** * This action will be throttled. */ SliderZoomView.prototype._dispatchZoomAction = function (realtime) { var range = this._range; this.api.dispatchAction({ type: 'dataZoom', from: this.uid, dataZoomId: this.dataZoomModel.id, animation: realtime ? REALTIME_ANIMATION_CONFIG : null, start: range[0], end: range[1] }); }; SliderZoomView.prototype._findCoordRect = function () { // Find the grid corresponding to the first axis referred by dataZoom. var rect; var coordSysInfoList = collectReferCoordSysModelInfo(this.dataZoomModel).infoList; if (!rect && coordSysInfoList.length) { var coordSys = coordSysInfoList[0].model.coordinateSystem; rect = coordSys.getRect && coordSys.getRect(); } if (!rect) { var width = this.api.getWidth(); var height = this.api.getHeight(); rect = { x: width * 0.2, y: height * 0.2, width: width * 0.6, height: height * 0.6 }; } return rect; }; SliderZoomView.type = 'dataZoom.slider'; return SliderZoomView; }(DataZoomView); function getOtherDim(thisDim) { // FIXME // 这个逻辑和getOtherAxis里一致,但是写在这里是否不好 var map = { x: 'y', y: 'x', radius: 'angle', angle: 'radius' }; return map[thisDim]; } function getCursor(orient) { return orient === 'vertical' ? 'ns-resize' : 'ew-resize'; } export default SliderZoomView;