|  | /* | 
|  | * 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 * as clazzUtil from '../util/clazz'; | 
|  | import { Dictionary } from 'zrender/src/core/types'; | 
|  | import SeriesData from '../data/SeriesData'; | 
|  | import { | 
|  | DimensionName, | 
|  | ScaleDataValue, | 
|  | OptionDataValue, | 
|  | DimensionLoose, | 
|  | ScaleTick | 
|  | } from '../util/types'; | 
|  | import { ScaleRawExtentInfo } from '../coord/scaleRawExtentInfo'; | 
|  |  | 
|  |  | 
|  | abstract class Scale<SETTING extends Dictionary<unknown> = Dictionary<unknown>> { | 
|  |  | 
|  | type: string; | 
|  |  | 
|  | private _setting: SETTING; | 
|  |  | 
|  | protected _extent: [number, number]; | 
|  |  | 
|  | private _isBlank: boolean; | 
|  |  | 
|  | // Inject | 
|  | readonly rawExtentInfo: ScaleRawExtentInfo; | 
|  |  | 
|  | constructor(setting?: SETTING) { | 
|  | this._setting = setting || {} as SETTING; | 
|  | this._extent = [Infinity, -Infinity]; | 
|  | } | 
|  |  | 
|  | getSetting<KEY extends keyof SETTING>(name: KEY): SETTING[KEY] { | 
|  | return this._setting[name]; | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Parse input val to valid inner number. | 
|  | * Notice: This would be a trap here, If the implementation | 
|  | * of this method depends on extent, and this method is used | 
|  | * before extent set (like in dataZoom), it would be wrong. | 
|  | * Nevertheless, parse does not depend on extent generally. | 
|  | */ | 
|  | abstract parse(val: OptionDataValue): number; | 
|  |  | 
|  | /** | 
|  | * Whether contain the given value. | 
|  | */ | 
|  | abstract contain(val: ScaleDataValue): boolean; | 
|  |  | 
|  | /** | 
|  | * Normalize value to linear [0, 1], return 0.5 if extent span is 0. | 
|  | */ | 
|  | abstract normalize(val: ScaleDataValue): number; | 
|  |  | 
|  | /** | 
|  | * Scale normalized value to extent. | 
|  | */ | 
|  | abstract scale(val: number): number; | 
|  |  | 
|  | /** | 
|  | * Set extent from data | 
|  | */ | 
|  | unionExtent(other: [number, number]): void { | 
|  | const extent = this._extent; | 
|  | other[0] < extent[0] && (extent[0] = other[0]); | 
|  | other[1] > extent[1] && (extent[1] = other[1]); | 
|  | // not setExtent because in log axis it may transformed to power | 
|  | // this.setExtent(extent[0], extent[1]); | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Set extent from data | 
|  | */ | 
|  | unionExtentFromData(data: SeriesData, dim: DimensionName | DimensionLoose): void { | 
|  | this.unionExtent(data.getApproximateExtent(dim)); | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Get extent | 
|  | * | 
|  | * Extent is always in increase order. | 
|  | */ | 
|  | getExtent(): [number, number] { | 
|  | return this._extent.slice() as [number, number]; | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Set extent | 
|  | */ | 
|  | setExtent(start: number, end: number): void { | 
|  | const thisExtent = this._extent; | 
|  | if (!isNaN(start)) { | 
|  | thisExtent[0] = start; | 
|  | } | 
|  | if (!isNaN(end)) { | 
|  | thisExtent[1] = end; | 
|  | } | 
|  | } | 
|  |  | 
|  | /** | 
|  | * If value is in extent range | 
|  | */ | 
|  | isInExtentRange(value: number): boolean { | 
|  | return this._extent[0] <= value && this._extent[1] >= value; | 
|  | } | 
|  |  | 
|  | /** | 
|  | * When axis extent depends on data and no data exists, | 
|  | * axis ticks should not be drawn, which is named 'blank'. | 
|  | */ | 
|  | isBlank(): boolean { | 
|  | return this._isBlank; | 
|  | } | 
|  |  | 
|  | /** | 
|  | * When axis extent depends on data and no data exists, | 
|  | * axis ticks should not be drawn, which is named 'blank'. | 
|  | */ | 
|  | setBlank(isBlank: boolean) { | 
|  | this._isBlank = isBlank; | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Update interval and extent of intervals for nice ticks | 
|  | * | 
|  | * @param splitNumber Approximated tick numbers. Optional. | 
|  | *        The implementation of `niceTicks` should decide tick numbers | 
|  | *        whether `splitNumber` is given. | 
|  | * @param minInterval Optional. | 
|  | * @param maxInterval Optional. | 
|  | */ | 
|  | abstract calcNiceTicks( | 
|  | // FIXME:TS make them in a "opt", the same with `niceExtent`? | 
|  | splitNumber?: number, | 
|  | minInterval?: number, | 
|  | maxInterval?: number | 
|  | ): void; | 
|  |  | 
|  | abstract calcNiceExtent( | 
|  | opt?: { | 
|  | splitNumber?: number, | 
|  | fixMin?: boolean, | 
|  | fixMax?: boolean, | 
|  | minInterval?: number, | 
|  | maxInterval?: number | 
|  | } | 
|  | ): void; | 
|  |  | 
|  | /** | 
|  | * @return label of the tick. | 
|  | */ | 
|  | abstract getLabel(tick: ScaleTick): string; | 
|  |  | 
|  | abstract getTicks(): ScaleTick[]; | 
|  |  | 
|  | abstract getMinorTicks(splitNumber: number): number[][]; | 
|  |  | 
|  | static registerClass: clazzUtil.ClassManager['registerClass']; | 
|  |  | 
|  | static getClass: clazzUtil.ClassManager['getClass']; | 
|  | } | 
|  |  | 
|  | type ScaleConstructor = typeof Scale & clazzUtil.ClassManager; | 
|  | clazzUtil.enableClassManagement(Scale as ScaleConstructor); | 
|  |  | 
|  | export default Scale; |