| /* |
| * 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. |
| */ |
| |
| /** |
| * Calculate slider move result. |
| * Usage: |
| * (1) If both handle0 and handle1 are needed to be moved, set minSpan the same as |
| * maxSpan and the same as `Math.abs(handleEnd[1] - handleEnds[0])`. |
| * (2) If handle0 is forbidden to cross handle1, set minSpan as `0`. |
| * |
| * @param delta Move length. |
| * @param handleEnds handleEnds[0] can be bigger then handleEnds[1]. |
| * handleEnds will be modified in this method. |
| * @param extent handleEnds is restricted by extent. |
| * extent[0] should less or equals than extent[1]. |
| * @param handleIndex Can be 'all', means that both move the two handleEnds. |
| * @param minSpan The range of dataZoom can not be smaller than that. |
| * If not set, handle0 and cross handle1. If set as a non-negative |
| * number (including `0`), handles will push each other when reaching |
| * the minSpan. |
| * @param maxSpan The range of dataZoom can not be larger than that. |
| * @return The input handleEnds. |
| */ |
| export default function sliderMove( |
| delta: number, |
| handleEnds: number[], |
| extent: number[], |
| handleIndex: 'all' | 0 | 1, |
| minSpan?: number, |
| maxSpan?: number |
| ): number[] { |
| |
| delta = delta || 0; |
| |
| const extentSpan = extent[1] - extent[0]; |
| |
| // Notice maxSpan and minSpan can be null/undefined. |
| if (minSpan != null) { |
| minSpan = restrict(minSpan, [0, extentSpan]); |
| } |
| if (maxSpan != null) { |
| maxSpan = Math.max(maxSpan, minSpan != null ? minSpan : 0); |
| } |
| if (handleIndex === 'all') { |
| let handleSpan = Math.abs(handleEnds[1] - handleEnds[0]); |
| handleSpan = restrict(handleSpan, [0, extentSpan]); |
| minSpan = maxSpan = restrict(handleSpan, [minSpan, maxSpan]); |
| handleIndex = 0; |
| } |
| |
| handleEnds[0] = restrict(handleEnds[0], extent); |
| handleEnds[1] = restrict(handleEnds[1], extent); |
| |
| const originalDistSign = getSpanSign(handleEnds, handleIndex); |
| |
| handleEnds[handleIndex] += delta; |
| |
| // Restrict in extent. |
| const extentMinSpan = minSpan || 0; |
| const realExtent = extent.slice(); |
| originalDistSign.sign < 0 ? (realExtent[0] += extentMinSpan) : (realExtent[1] -= extentMinSpan); |
| handleEnds[handleIndex] = restrict(handleEnds[handleIndex], realExtent); |
| |
| // Expand span. |
| let currDistSign; |
| currDistSign = getSpanSign(handleEnds, handleIndex); |
| if (minSpan != null && ( |
| currDistSign.sign !== originalDistSign.sign || currDistSign.span < minSpan |
| )) { |
| // If minSpan exists, 'cross' is forbidden. |
| handleEnds[1 - handleIndex] = handleEnds[handleIndex] + originalDistSign.sign * minSpan; |
| } |
| |
| // Shrink span. |
| currDistSign = getSpanSign(handleEnds, handleIndex); |
| if (maxSpan != null && currDistSign.span > maxSpan) { |
| handleEnds[1 - handleIndex] = handleEnds[handleIndex] + currDistSign.sign * maxSpan; |
| } |
| |
| return handleEnds; |
| } |
| |
| function getSpanSign(handleEnds: number[], handleIndex: 0 | 1) { |
| const dist = handleEnds[handleIndex] - handleEnds[1 - handleIndex]; |
| // If `handleEnds[0] === handleEnds[1]`, always believe that handleEnd[0] |
| // is at left of handleEnds[1] for non-cross case. |
| return {span: Math.abs(dist), sign: dist > 0 ? -1 : dist < 0 ? 1 : handleIndex ? -1 : 1}; |
| } |
| |
| function restrict(value: number, extend: number[]) { |
| return Math.min( |
| extend[1] != null ? extend[1] : Infinity, |
| Math.max(extend[0] != null ? extend[0] : -Infinity, value) |
| ); |
| } |