/* * 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 = Dictionary> { 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(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;