'use strict' ; import type { AlignValue } from '../Renderer/AlignObject' ; import type AnimationOptions from '../Animation/AnimationOptions' ; import type AxisComposition from './AxisComposition' ; import type { AxisCrosshairOptions , AxisLabelFormatterCallback , AxisLabelFormatterContextObject , AxisOptions , AxisTitleOptions , XAxisOptions , YAxisOptions } from './AxisOptions' ; import type AxisLike from './AxisLike' ; import type { AxisTypeOptions } from './AxisType' ; import type Chart from '../Chart/Chart' ; import type CSSObject from '../Renderer/CSSObject' ; import type { EventCallback } from '../Callback' ; import type FontMetricsObject from '../Renderer/FontMetricsObject' ; import type PlotLineOptions from './PlotLineOrBand/PlotLineOptions' ; import type PlotLineOrBand from './PlotLineOrBand/PlotLineOrBand' ; import type Point from '../Series/Point' ; import type PointerEvent from '../PointerEvent' ; import type PositionObject from '../Renderer/PositionObject' ; import type Series from '../Series/Series' ; import type SizeObject from '../Renderer/SizeObject' ; import type SVGAttributes from '../Renderer/SVG/SVGAttributes' ; import type SVGElement from '../Renderer/SVG/SVGElement' ; import type SVGPath from '../Renderer/SVG/SVGPath' ; import type TickPositionsArray from './TickPositionsArray' ; import A from '../Animation/AnimationUtilities.js' ; const { animObject } = A ; import AxisDefaults from './AxisDefaults.js' ; import Color from '../Color/Color.js' ; import D from '../DefaultOptions.js' ; const { defaultOptions } = D ; import F from '../Foundation.js' ; const { registerEventOptions } = F ; import H from '../Globals.js' ; const { deg2rad } = H ; import { Palette } from '../Color/Palettes.js' ; import Tick from './Tick.js' ; import U from '../Utilities.js' ; const { arrayMax , arrayMin , clamp , correctFloat , defined , destroyObjectProperties , erase , error , extend , fireEvent , getMagnitude , isArray , isNumber , isString , merge , normalizeTickInterval , objectEach , pick , relativeLength , removeEvent , splat , syncTimeout } = U ; declare module '../Series/SeriesOptions' { interface SeriesOptions { softThreshold ? : boolean ; startFromThreshold ? : boolean ; threshold ? : number | null ; } } /**
 * Create a new axis object. Called internally when instanciating a new chart or
 * adding axes by  Highcharts . Chart .
 *
 * A chart can have from 0 axes (pie chart) to multiples. In a normal, single
 * series cartesian chart, there is one X axis and one Y axis.
 *
 * The X axis or axes are referenced by  Highcharts . Chart . xAxis , which is
 * an array of Axis objects. If there is only one axis, it can be referenced
 * through `chart.xAxis[0]`, and multiple axes have increasing indices. The same
 * pattern goes for Y axes.
 *
 * If you need to get the axes from a series object, use the `series.xAxis` and
 * `series.yAxis` properties. These are not arrays, as one series can only be
 * associated to one X and one Y axis.
 *
 * A third way to reference the axis programmatically is by `id`. Add an `id` in
 * the axis configuration options, and get the axis by
 *  Highcharts . Chart .
 *
 * Configuration options for the axes are given in options.xAxis and
 * options.yAxis.
 *
 *  class name param { Highcharts . Chart } chart param { Highcharts . AxisOptions } userOptions class Axis { public static readonly defaultOptions = AxisDefaults . defaultXAxisOptions ; public static keepProps = [ 'extKey' , 'hcEvents' , 'names' , 'series' , 'userMax' , 'userMin' ] ; public constructor ( chart , userOptions ) { this . init ( chart , userOptions ) ; } public _addedPlotLB ? : boolean ; public allowZoomOutside ? : boolean ; public alternateBands : Record < string , PlotLineOrBand > = void 0 as any ; public autoRotation ? : Array < number > ; public axisGroup ? : SVGElement ; public axisLine ? : SVGElement ; public axisParent ? : SVGElement ; public axisPointRange ? : number ; public axisTitle ? : SVGElement ; public axisTitleMargin ? : number ; public bottom : number = void 0 as any ; public categories ? : Array < string > ; public chart : Chart = void 0 as any ; public closestPointRange : number = void 0 as any ; public coll : string = void 0 as any ; public cross ? : SVGElement ; public crosshair ? : AxisCrosshairOptions ; public dataMax ? : ( null | number ) ; public dataMin ? : ( null | number ) ; public displayBtn ? : boolean ; public eventArgs ? : any ; public eventOptions : Record < string , EventCallback < Series , Event > > = void 0 as any ; public finalTickAmt ? : number ; public forceRedraw ? : boolean ; public gridGroup ? : SVGElement ; public hasNames : boolean = void 0 as any ; public hasVisibleSeries : boolean = void 0 as any ; public height : number = void 0 as any ; public horiz ? : boolean ; public isDirty ? : boolean ; public isLinked : boolean = void 0 as any ; public isOrdinal ? : boolean ; public isRadial ? : boolean ; public isXAxis ? : boolean ; public isZAxis ? : boolean ; public keepProps ? : Array < string > ; public labelAlign ? : AlignValue ; public labelEdge : Array < null > = void 0 as any ; public labelFormatter : AxisLabelFormatterCallback = void 0 as any ; public labelGroup ? : SVGElement ; public labelOffset ? : number ; public labelRotation ? : number ; public left : number = void 0 as any ; public len : number = void 0 as any ; public linkedParent ? : Axis ; public max : ( null | number ) = void 0 as any ; public maxLabelDimensions ? : SizeObject ; public maxLabelLength : number = void 0 as any ; public min : ( null | number ) = void 0 as any ; public minorTickInterval : number = void 0 as any ; public minorTicks : Record < string , Tick > = void 0 as any ; public minPixelPadding : number = void 0 as any ; public minPointOffset ? : number ; public minRange ? : ( null | number ) ; public names : Array < string > = void 0 as any ; public offset : number = void 0 as any ; public old ? : { len : number ; max : number | null ; min : number | null ; transA : number ; userMax ? : number ; userMin ? : number ; } ; public opposite ? : boolean ; public options : ( AxisOptions | XAxisOptions | YAxisOptions ) = void 0 as any ; public ordinal ? : AxisComposition [ 'ordinal' ] ; public overlap : boolean = void 0 as any ; public paddedTicks : Array < number > = void 0 as any ; public panningState ? : Axis . PanningState ; public plotLinesAndBands : Array < PlotLineOrBand > = void 0 as any ; public plotLinesAndBandsGroups : Record < string , SVGElement > = void 0 as any ; public pointRange : number = void 0 as any ; public pointRangePadding : number = void 0 as any ; public pos : number = void 0 as any ; public positiveValuesOnly : boolean = void 0 as any ; public reserveSpaceDefault ? : boolean ; public reversed ? : boolean ; public right : number = void 0 as any ; public sector ? : number ; public series : Array < Series > = void 0 as any ; public showAxis ? : boolean ; public side : number = void 0 as any ; public single ? : boolean ; public softThreshold ? : boolean ; public staggerLines ? : number ; public staticScale ? : number ; public threshold ? : number ; public thresholdAlignment ? : number ; public tickAmount : number = void 0 as any ; public tickInterval : number = void 0 as any ; public tickmarkOffset : number = void 0 as any ; public tickPositions : TickPositionsArray = void 0 as any ; public tickRotCorr : PositionObject = void 0 as any ; public ticks : Record < string , Tick > = void 0 as any ; public titleOffset ? : number ; public top : number = void 0 as any ; public transA : number = void 0 as any ; public transB : number = void 0 as any ; public translationSlope : number = void 0 as any ; public userMax ? : number ; public userMin ? : number ; public userMinRange ? : number ; public userOptions : DeepPartial < AxisOptions > = void 0 as any ; public visible : boolean = void 0 as any ; public width : number = void 0 as any ; public zoomEnabled : boolean = void 0 as any ; see Axis function param { Highcharts . Chart } chart param { AxisOptions } userOptions emits emits public init ( chart , userOptions ) { const isXAxis = userOptions . isX , axis = this ; name type { Highcharts . Chart } axis . chart = chart ; name type { boolean | undefined } axis . horiz = chart . inverted && ! axis . isZAxis ? ! isXAxis : isXAxis ; name type { boolean | undefined } axis . isXAxis = isXAxis ; /**
         * The collection where the axis belongs, for example `xAxis`, `yAxis`
         * or `colorAxis`. Corresponds to properties on Chart, for example
         *  Chart . xAxis .
         *
         *  name type { string } axis . coll = axis . coll || ( isXAxis ? 'xAxis' : 'yAxis' ) ; fireEvent ( this , 'init' , { userOptions : userOptions } ) ; axis . opposite = pick ( userOptions . opposite , axis . opposite ) ; name type { number } axis . side = pick ( userOptions . side , axis . side , ( axis . horiz ? ( axis . opposite ? 0 : 2 ) : ( axis . opposite ? 1 : 3 ) ) ) ; name type { Highcharts . AxisOptions } axis . setOptions ( userOptions ) ; const options = this . options , labelsOptions = options . labels , type = options . type ; name type { Highcharts . AxisOptions } axis . userOptions = userOptions ; axis . minPixelPadding = 0 ; name type { boolean } axis . reversed = pick ( options . reversed , axis . reversed ) ; axis . visible = options . visible ; axis . zoomEnabled = options . zoomEnabled ; axis . hasNames = type === 'category' || ( options . categories as any ) === true ; see name type { Array < string > } readonly axis . categories = options . categories || ( axis . hasNames ? [ ] : void 0 ) ; if ( ! axis . names ) { axis . names = [ ] ; ( axis . names as any ) . keys = { } ; } axis . plotLinesAndBandsGroups = { } ; axis . positiveValuesOnly = ! ! axis . logarithmic ; axis . isLinked = defined ( options . linkedTo ) ; see Highcharts . Tick name type { Highcharts . Dictionary < Highcharts . Tick > } axis . ticks = { } ; axis . labelEdge = [ ] ; see Highcharts . Tick name type { Highcharts . Dictionary < Highcharts . Tick > } axis . minorTicks = { } ; axis . plotLinesAndBands = [ ] ; axis . alternateBands = { } ; axis . len = 0 ; axis . minRange = axis . userMinRange = options . minRange || options . maxZoom ; axis . range = options . range ; axis . offset = options . offset || 0 ; /**
         * The maximum value of the axis. In a logarithmic axis, this is the
         * logarithm of the real value, and the real value can be obtained from
         *  Axis .
         *
         *  name type { number | null } axis . max = null ; /**
         * The minimum value of the axis. In a logarithmic axis, this is the
         * logarithm of the real value, and the real value can be obtained from
         *  Axis .
         *
         *  name type { number | null } axis . min = null ; name type { boolean | Highcharts . AxisCrosshairOptions } const crosshair = pick ( options . crosshair , splat ( ( chart . options . tooltip as any ) . crosshairs ) [ isXAxis ? 0 : 1 ] ) ; axis . crosshair = crosshair === true ? { } : crosshair ; if ( chart . axes . indexOf ( axis ) === - 1 ) { if ( isXAxis ) { chart . axes . splice ( chart . xAxis . length , 0 , axis ) ; } else { chart . axes . push ( axis ) ; } ( chart as any ) [ axis . coll ] . push ( axis ) ; } name type { Array < Highcharts . Series > } axis . series = axis . series || [ ] ; if ( chart . inverted && ! axis . isZAxis && isXAxis && typeof axis . reversed === 'undefined' ) { axis . reversed = true ; } axis . labelRotation = isNumber ( labelsOptions . rotation ) ? labelsOptions . rotation : void 0 ; registerEventOptions ( axis , options ) ; fireEvent ( this , 'afterInit' ) ; } private function param { Highcharts . AxisOptions } userOptions emits public setOptions ( userOptions ) { this . options = merge ( AxisDefaults . defaultXAxisOptions , ( this . coll === 'yAxis' ) && AxisDefaults . defaultYAxisOptions , [ AxisDefaults . defaultTopAxisOptions , AxisDefaults . defaultRightAxisOptions , AxisDefaults . defaultBottomAxisOptions , AxisDefaults . defaultLeftAxisOptions ] [ this . side ] , merge ( ( defaultOptions as any ) [ this . coll ] , userOptions ) ) ; fireEvent ( this , 'afterSetOptions' , { userOptions : userOptions } ) ; } function param { Highcharts . AxisLabelsFormatterContextObject } this param { Highcharts . AxisLabelsFormatterContextObject } ctx return { string } public defaultLabelFormatter ( this , ctx ? ) { const axis = this . axis , chart = this . chart , { numberFormatter } = chart , value = isNumber ( this . value ) ? this . value : NaN , time = axis . chart . time , categories = axis . categories , dateTimeLabelFormat = this . dateTimeLabelFormat , lang = defaultOptions . lang , numericSymbols = lang . numericSymbols , numSymMagnitude = lang . numericSymbolMagnitude || 1000 , numericSymbolDetector = axis . logarithmic ? Math . abs ( value ) : axis . tickInterval ; let i = numericSymbols && numericSymbols . length , multi , ret ; if ( categories ) { ret = `${ this . value }` ; } else if ( dateTimeLabelFormat ) { ret = time . dateFormat ( dateTimeLabelFormat , value ) ; } else if ( i && numericSymbolDetector >= 1000 ) { while ( i -- && typeof ret === 'undefined' ) { multi = Math . pow ( numSymMagnitude , i + 1 ) ; if ( numericSymbolDetector >= multi && ( value * 10 ) % multi === 0 && numericSymbols [ i ] !== null && value !== 0 ) { ret = numberFormatter ( value / multi , - 1 ) + numericSymbols [ i ] ; } } } if ( typeof ret === 'undefined' ) { if ( Math . abs ( value ) >= 10000 ) { ret = numberFormatter ( value , - 1 ) ; } else { ret = numberFormatter ( value , - 1 , void 0 , '' ) ; } } return ret ; } private function emits emits public getSeriesExtremes ( ) { const axis = this , chart = axis . chart ; let xExtremes ; fireEvent ( this , 'getSeriesExtremes' , null as any , function ( ) : void { axis . hasVisibleSeries = false ; axis . dataMin = axis . dataMax = axis . threshold = null as any ; axis . softThreshold = ! axis . isXAxis ; if ( axis . stacking ) { axis . stacking . buildStacks ( ) ; } axis . series . forEach ( function ( series ) : void { if ( series . visible || ! chart . options . chart . ignoreHiddenSeries ) { const seriesOptions = series . options ; let xData , threshold = seriesOptions . threshold , seriesDataMin , seriesDataMax ; axis . hasVisibleSeries = true ; if ( axis . positiveValuesOnly && ( threshold as any ) <= 0 ) { threshold = null as any ; } if ( axis . isXAxis ) { xData = series . xData as any ; if ( xData . length ) { const isPositive = ( number ) : boolean => number > 0 ; xData = axis . logarithmic ? xData . filter ( axis . validatePositiveValue ) : xData ; xExtremes = series . getXExtremes ( xData ) ; seriesDataMin = xExtremes . min ; seriesDataMax = xExtremes . max ; if ( ! isNumber ( seriesDataMin ) && ! ( ( seriesDataMin as any ) instanceof Date ) ) { xData = xData . filter ( isNumber ) ; xExtremes = series . getXExtremes ( xData ) ; seriesDataMin = xExtremes . min ; seriesDataMax = xExtremes . max ; } if ( xData . length ) { axis . dataMin = Math . min ( pick ( axis . dataMin , seriesDataMin ) , seriesDataMin ) ; axis . dataMax = Math . max ( pick ( axis . dataMax , seriesDataMax ) , seriesDataMax ) ; } } } else { const dataExtremes = series . applyExtremes ( ) ; if ( isNumber ( dataExtremes . dataMin ) ) { seriesDataMin = dataExtremes . dataMin ; axis . dataMin = Math . min ( pick ( axis . dataMin , seriesDataMin ) , seriesDataMin ) ; } if ( isNumber ( dataExtremes . dataMax ) ) { seriesDataMax = dataExtremes . dataMax ; axis . dataMax = Math . max ( pick ( axis . dataMax , seriesDataMax ) , seriesDataMax ) ; } if ( defined ( threshold ) ) { axis . threshold = threshold ; } if ( ! seriesOptions . softThreshold || axis . positiveValuesOnly ) { axis . softThreshold = false ; } } } } ) ; } ) ; fireEvent ( this , 'afterGetSeriesExtremes' ) ; } private function public translate ( val , backwards ? , cvsCoord ? , old ? , handleLog ? , pointPlacement ? ) { const axis = ( this . linkedParent || this ) , localMin = old && axis . old ? axis . old . min : axis . min , minPixelPadding = axis . minPixelPadding , doPostTranslate = ( axis . isOrdinal || axis . brokenAxis && axis . brokenAxis . hasBreaks || ( axis . logarithmic && handleLog ) ) && axis . lin2val ; let sign = 1 , cvsOffset = 0 , localA = old && axis . old ? axis . old . transA : axis . transA , returnValue = 0 ; if ( ! localA ) { localA = axis . transA ; } if ( cvsCoord ) { sign *= - 1 ; cvsOffset = axis . len ; } if ( axis . reversed ) { sign *= - 1 ; cvsOffset -= sign * ( axis . sector || axis . len ) ; } if ( backwards ) { val = val * sign + cvsOffset ; val -= minPixelPadding ; returnValue = val / localA + ( localMin as any ) ; if ( doPostTranslate ) { returnValue = axis . lin2val ( returnValue ) ; } } else { if ( doPostTranslate ) { val = ( axis . val2lin as any ) ( val ) ; } const value = sign * ( val - ( localMin as any ) ) * localA ; returnValue = isNumber ( localMin ) ? ( ( ! axis . isRadial ? correctFloat ( value ) : value ) + cvsOffset + ( sign * minPixelPadding ) + ( isNumber ( pointPlacement ) ? localA * ( pointPlacement as any ) : 0 ) ) : void 0 as any ; } return returnValue ; } function param { number } value param { boolean } paneCoordinates return { number } public toPixels ( value , paneCoordinates ? ) { return this . translate ( value , false , ! this . horiz , null , true ) as any + ( paneCoordinates ? 0 : this . pos ) ; } function param { number } pixel param { boolean } paneCoordinates return { number } public toValue ( pixel , paneCoordinates ? ) { return this . translate ( pixel - ( paneCoordinates ? 0 : this . pos as any ) , true , ! this . horiz , null , true ) as any ; } function param { Highcharts . AxisPlotLinePathOptionsObject } options return { Highcharts . SVGPathArray | null } public getPlotLinePath ( options ) { const axis = this , chart = axis . chart , axisLeft = axis . left , axisTop = axis . top , old = options . old , value = options . value , lineWidth = options . lineWidth , cHeight = ( old && chart . oldChartHeight ) || chart . chartHeight , cWidth = ( old && chart . oldChartWidth ) || chart . chartWidth , transB = axis . transB ; let translatedValue = options . translatedValue , force = options . force , x1 , y1 , x2 , y2 , skip ; private function between ( x , a , b ) { if ( force !== 'pass' && x < a || x > b ) { if ( force ) { x = clamp ( x , a , b ) ; } else { skip = true ; } } return x ; } const evt = { value : value , lineWidth : lineWidth , old : old , force : force , acrossPanes : options . acrossPanes , translatedValue : translatedValue } as any ; fireEvent ( this , 'getPlotLinePath' , evt , function ( e ) : void { translatedValue = pick ( translatedValue , axis . translate ( value as any , null , null , old ) ) ; translatedValue = clamp ( translatedValue as any , - 1e5 , 1e5 ) ; x1 = x2 = Math . round ( translatedValue + transB ) ; y1 = y2 = Math . round ( ( cHeight as any ) - translatedValue - transB ) ; if ( ! isNumber ( translatedValue ) ) { skip = true ; force = false ; } else if ( axis . horiz ) { y1 = axisTop as any ; y2 = ( cHeight as any ) - ( axis . bottom as any ) ; x1 = x2 = between ( x1 , axisLeft as any , ( axisLeft as any ) + axis . width ) ; } else { x1 = axisLeft as any ; x2 = ( cWidth as any ) - ( axis . right as any ) ; y1 = y2 = between ( y1 , axisTop as any , ( axisTop as any ) + axis . height ) ; } ( e as any ) . path = skip && ! force ? null : chart . renderer . crispLine ( [ [ 'M' , x1 , y1 ] , [ 'L' , x2 , y2 ] ] , lineWidth || 1 ) ; } ) ; return ( evt as any ) . path ; } function param { number } tickInterval param { number } min param { number } max return { Array < number > } public getLinearTickPositions ( tickInterval , min , max ) { const roundedMin = correctFloat ( Math . floor ( min / tickInterval ) * tickInterval ) , roundedMax = correctFloat ( Math . ceil ( max / tickInterval ) * tickInterval ) , tickPositions = [ ] ; let pos , lastPos , precision ; if ( correctFloat ( roundedMin + tickInterval ) === roundedMin ) { precision = 20 ; } if ( this . single ) { return [ min ] ; } pos = roundedMin ; while ( pos <= roundedMax ) { tickPositions . push ( pos ) ; pos = correctFloat ( pos + tickInterval , precision ) ; if ( pos === lastPos ) { break ; } lastPos = pos ; } return tickPositions ; } function return { number | "auto" | null } public getMinorTickInterval ( ) { const options = this . options ; if ( options . minorTicks === true ) { return pick ( options . minorTickInterval , 'auto' ) ; } if ( options . minorTicks === false ) { return null ; } return options . minorTickInterval as any ; } function return { Array < number > } public getMinorTickPositions ( ) { const axis = this , options = axis . options , tickPositions = axis . tickPositions , minorTickInterval = axis . minorTickInterval , pointRangePadding = axis . pointRangePadding || 0 , min = ( axis . min as any ) - pointRangePadding , max = ( axis . max as any ) + pointRangePadding , range = max - min ; let minorTickPositions = [ ] as Array < number > , pos ; if ( range && range / minorTickInterval < axis . len / 3 ) { const logarithmic = axis . logarithmic ; if ( logarithmic ) { this . paddedTicks . forEach ( function ( _pos , i , paddedTicks ) : void { if ( i ) { minorTickPositions . push . apply ( minorTickPositions , logarithmic . getLogTickPositions ( minorTickInterval , paddedTicks [ i - 1 ] , paddedTicks [ i ] , true ) ) ; } } ) ; } else if ( axis . dateTime && this . getMinorTickInterval ( ) === 'auto' ) { minorTickPositions = minorTickPositions . concat ( axis . getTimeTicks ( axis . dateTime . normalizeTimeTickInterval ( minorTickInterval ) , min , max , options . startOfWeek ) ) ; } else { for ( pos = min + ( tickPositions [ 0 ] - min ) % minorTickInterval ; pos <= max ; pos += minorTickInterval ) { if ( pos === minorTickPositions [ 0 ] ) { break ; } minorTickPositions . push ( pos ) ; } } } if ( minorTickPositions . length !== 0 ) { axis . trimTicks ( minorTickPositions ) ; } return minorTickPositions ; } private function public adjustForMinRange ( ) { const axis = this , options = axis . options , log = axis . logarithmic ; let min = axis . min , max = axis . max , zoomOffset , spaceAvailable , closestDataRange = 0 , i , distance , xData , loopLength , minArgs , maxArgs , minRange ; if ( axis . isXAxis && typeof axis . minRange === 'undefined' && ! log ) { if ( defined ( options . min ) || defined ( options . max ) || defined ( options . floor ) || defined ( options . ceiling ) ) { axis . minRange = null ; } else { axis . series . forEach ( function ( series ) : void { xData = series . xData as any ; loopLength = series . xIncrement ? 1 : xData . length - 1 ; if ( xData . length > 1 ) { for ( i = loopLength ; i > 0 ; i -- ) { distance = xData [ i ] - xData [ i - 1 ] ; if ( ! closestDataRange || distance < closestDataRange ) { closestDataRange = distance ; } } } } ) ; axis . minRange = Math . min ( closestDataRange * 5 , ( axis . dataMax as any ) - ( axis . dataMin as any ) ) ; } } if ( ( max as any ) - ( min as any ) < ( axis . minRange as any ) ) { spaceAvailable = ( axis . dataMax as any ) - ( axis . dataMin as any ) >= ( axis . minRange as any ) ; minRange = axis . minRange ; zoomOffset = ( ( minRange as any ) - ( max as any ) + ( min as any ) ) / 2 ; minArgs = [ ( min as any ) - zoomOffset , pick ( options . min , ( min as any ) - zoomOffset ) ] ; if ( spaceAvailable ) { minArgs [ 2 ] = axis . logarithmic ? axis . logarithmic . log2lin ( axis . dataMin as any ) : axis . dataMin ; } min = arrayMax ( minArgs ) ; maxArgs = [ min + ( minRange as any ) , pick ( options . max , min + ( minRange as any ) ) ] ; if ( spaceAvailable ) { maxArgs [ 2 ] = log ? log . log2lin ( axis . dataMax as any ) : axis . dataMax ; } max = arrayMin ( maxArgs ) ; if ( max - min < ( minRange as any ) ) { minArgs [ 0 ] = max - ( minRange as any ) ; minArgs [ 1 ] = pick ( options . min , max - ( minRange as any ) ) ; min = arrayMax ( minArgs ) ; } } axis . min = min ; axis . max = max ; } private function public getClosest ( ) { let ret ; if ( this . categories ) { ret = 1 ; } else { this . series . forEach ( function ( series ) : void { const seriesClosest = series . closestPointRange , visible = series . visible || ! series . chart . options . chart . ignoreHiddenSeries ; if ( ! series . noSharedTooltip && defined ( seriesClosest ) && visible ) { ret = defined ( ret ) ? Math . min ( ret , seriesClosest as any ) : seriesClosest ; } } ) ; } return ret ; } private function param { Highcharts . Point } point return { number } public nameToX ( point ) { const explicitCategories = isArray ( this . options . categories ) , names = explicitCategories ? this . categories : this . names ; let nameX = point . options . x , x ; point . series . requireSorting = false ; if ( ! defined ( nameX ) ) { nameX = this . options . uniqueNames && names ? ( explicitCategories ? names . indexOf ( point . name ) : pick ( ( names as any ) . keys [ point . name ] , - 1 ) ) : point . series . autoIncrement ( ) ; } if ( nameX === - 1 ) { if ( ! explicitCategories && names ) { x = names . length ; } } else { x = nameX ; } if ( typeof x !== 'undefined' ) { this . names [ x ] = point . name as any ; ( this . names as any ) . keys [ point . name as any ] = x ; } return x as any ; } private function public updateNames ( ) { const axis = this , names = this . names , i = names . length ; if ( i > 0 ) { Object . keys ( ( names as any ) . keys ) . forEach ( function ( key ) : void { delete ( ( names as any ) . keys ) [ key ] ; } ) ; names . length = 0 ; this . minRange = this . userMinRange ; ( this . series || [ ] ) . forEach ( function ( series ) : void { series . xIncrement = null ; if ( ! series . points || series . isDirtyData ) { axis . max = Math . max ( ( axis . max as any ) , ( series . xData as any ) . length - 1 ) ; series . processData ( ) ; series . generatePoints ( ) ; } series . data . forEach ( function ( point , i ) : void { let x ; if ( point && point . options && typeof point . name !== 'undefined' ) { x = axis . nameToX ( point ) ; if ( typeof x !== 'undefined' && x !== point . x ) { point . x = x ; ( series . xData as any ) [ i ] = x ; } } } ) ; } ) ; } } private function emits public setAxisTranslation ( ) { const axis = this , range = ( axis . max as any ) - ( axis . min as any ) , linkedParent = axis . linkedParent , hasCategories = ! ! axis . categories , isXAxis = axis . isXAxis ; let pointRange = axis . axisPointRange || 0 , closestPointRange , minPointOffset = 0 , pointRangePadding = 0 , ordinalCorrection , transA = axis . transA ; if ( isXAxis || hasCategories || pointRange ) { closestPointRange = axis . getClosest ( ) ; if ( linkedParent ) { minPointOffset = linkedParent . minPointOffset as any ; pointRangePadding = linkedParent . pointRangePadding ; } else { axis . series . forEach ( function ( series ) : void { const seriesPointRange = hasCategories ? 1 : ( isXAxis ? pick ( series . options . pointRange , closestPointRange , 0 ) : ( axis . axisPointRange || 0 ) ) , pointPlacement = series . options . pointPlacement ; pointRange = Math . max ( pointRange , seriesPointRange ) ; if ( ! axis . single || hasCategories ) { const isPointPlacementAxis = series . is ( 'xrange' ) ? ! isXAxis : isXAxis ; minPointOffset = Math . max ( minPointOffset , isPointPlacementAxis && isString ( pointPlacement ) ? 0 : seriesPointRange / 2 ) ; pointRangePadding = Math . max ( pointRangePadding , isPointPlacementAxis && pointPlacement === 'on' ? 0 : seriesPointRange ) ; } } ) ; } ordinalCorrection = ( axis . ordinal && axis . ordinal . slope && closestPointRange ) ? axis . ordinal . slope / closestPointRange : 1 ; axis . minPointOffset = minPointOffset = minPointOffset * ordinalCorrection ; axis . pointRangePadding = pointRangePadding = pointRangePadding * ordinalCorrection ; axis . pointRange = Math . min ( pointRange , axis . single && hasCategories ? 1 : range ) ; if ( isXAxis ) { axis . closestPointRange = closestPointRange ; } } axis . translationSlope = axis . transA = transA = axis . staticScale || axis . len / ( ( range + pointRangePadding ) || 1 ) ; axis . transB = axis . horiz ? axis . left : axis . bottom ; axis . minPixelPadding = transA * minPointOffset ; fireEvent ( this , 'afterSetAxisTranslation' ) ; } private function public minFromRange ( ) { const axis = this ; return ( axis . max as any ) - ( axis . range as any ) ; } private function param { boolean } secondPass emits public setTickInterval ( secondPass ? ) { const axis = this , chart = axis . chart , log = axis . logarithmic , options = axis . options , isXAxis = axis . isXAxis , isLinked = axis . isLinked , tickPixelIntervalOption = options . tickPixelInterval , categories = axis . categories , softThreshold = axis . softThreshold ; let maxPadding = options . maxPadding , minPadding = options . minPadding , length , linkedParentExtremes , tickIntervalOption = isNumber ( options . tickInterval ) && options . tickInterval >= 0 ? options . tickInterval : void 0 , threshold = isNumber ( axis . threshold ) ? axis . threshold : null , thresholdMin , thresholdMax , hardMin , hardMax ; if ( ! axis . dateTime && ! categories && ! isLinked ) { this . getTickAmount ( ) ; } hardMin = pick ( axis . userMin , options . min ) ; hardMax = pick ( axis . userMax , options . max ) ; if ( isLinked ) { axis . linkedParent = ( chart as any ) [ axis . coll ] [ options . linkedTo as any ] ; linkedParentExtremes = ( axis . linkedParent as any ) . getExtremes ( ) ; axis . min = pick ( linkedParentExtremes . min , linkedParentExtremes . dataMin ) ; axis . max = pick ( linkedParentExtremes . max , linkedParentExtremes . dataMax ) ; if ( options . type !== ( axis . linkedParent as any ) . options . type ) { error ( 11 , 1 as any , chart ) ; } } else { if ( softThreshold && defined ( threshold ) ) { if ( ( axis . dataMin as any ) >= ( threshold as any ) ) { thresholdMin = threshold ; minPadding = 0 ; } else if ( ( axis . dataMax as any ) <= ( threshold as any ) ) { thresholdMax = threshold ; maxPadding = 0 ; } } axis . min = pick ( hardMin , thresholdMin , axis . dataMin as any ) ; axis . max = pick ( hardMax , thresholdMax , axis . dataMax as any ) ; } if ( log ) { if ( axis . positiveValuesOnly && ! secondPass && Math . min ( axis . min as any , pick ( axis . dataMin , axis . min as any ) ) <= 0 ) { error ( 10 , 1 as any , chart ) ; } axis . min = correctFloat ( log . log2lin ( axis . min as any ) , 16 ) ; axis . max = correctFloat ( log . log2lin ( axis . max as any ) , 16 ) ; } if ( axis . range && defined ( axis . max ) ) { axis . userMin = axis . min = hardMin = Math . max ( axis . dataMin as any , axis . minFromRange ( ) as any ) ; axis . userMax = hardMax = axis . max as any ; axis . range = null ; } fireEvent ( axis , 'foundExtremes' ) ; if ( axis . beforePadding ) { axis . beforePadding ( ) ; } axis . adjustForMinRange ( ) ; if ( ! categories && ! axis . axisPointRange && ! ( axis . stacking && axis . stacking . usePercentage ) && ! isLinked && defined ( axis . min ) && defined ( axis . max ) ) { length = axis . max - axis . min ; if ( length ) { if ( ! defined ( hardMin ) && minPadding ) { axis . min -= length * minPadding ; } if ( ! defined ( hardMax ) && maxPadding ) { axis . max += length * maxPadding ; } } } if ( ! isNumber ( axis . userMin ) ) { if ( isNumber ( options . softMin ) && options . softMin < ( axis . min as any ) ) { axis . min = hardMin = options . softMin ; } if ( isNumber ( options . floor ) ) { axis . min = Math . max ( axis . min as any , options . floor ) ; } } if ( ! isNumber ( axis . userMax ) ) { if ( isNumber ( options . softMax ) && options . softMax > ( axis . max as any ) ) { axis . max = hardMax = options . softMax ; } if ( isNumber ( options . ceiling ) ) { axis . max = Math . min ( axis . max as any , options . ceiling ) ; } } if ( softThreshold && defined ( axis . dataMin ) ) { threshold = threshold || ( 0 as any ) ; if ( ! defined ( hardMin ) && ( axis . min as any ) < ( threshold as any ) && ( axis . dataMin as any ) >= ( threshold as any ) ) { axis . min = axis . options . minRange ? Math . min ( threshold as any , ( axis . max as any ) - ( axis . minRange as any ) ) : ( threshold as any ) ; } else if ( ! defined ( hardMax ) && ( axis . max as any ) > ( threshold as any ) && ( axis . dataMax as any ) <= ( threshold as any ) ) { axis . max = axis . options . minRange ? Math . max ( threshold as any , ( axis . min as any ) + ( axis . minRange as any ) ) : ( threshold as any ) ; } } if ( isNumber ( axis . min ) && isNumber ( axis . max ) && ! this . chart . polar && ( axis . min > axis . max ) ) { if ( defined ( axis . options . min ) ) { axis . max = axis . min ; } else if ( defined ( axis . options . max ) ) { axis . min = axis . max ; } } if ( axis . min === axis . max || typeof axis . min === 'undefined' || typeof axis . max === 'undefined' ) { axis . tickInterval = 1 ; } else if ( isLinked && axis . linkedParent && ! tickIntervalOption && tickPixelIntervalOption === axis . linkedParent . options . tickPixelInterval ) { axis . tickInterval = tickIntervalOption = axis . linkedParent . tickInterval ; } else { axis . tickInterval = pick ( tickIntervalOption , this . tickAmount ? ( ( ( axis . max as any ) - ( axis . min as any ) ) / Math . max ( this . tickAmount - 1 , 1 ) ) : void 0 , categories ? 1 : ( ( axis . max as any ) - ( axis . min as any ) ) * tickPixelIntervalOption / Math . max ( axis . len , tickPixelIntervalOption ) ) ; } if ( isXAxis && ! secondPass ) { const hasExtemesChanged = axis . min !== ( axis . old && axis . old . min ) || axis . max !== ( axis . old && axis . old . max ) ; axis . series . forEach ( function ( series ) : void { series . forceCrop = ( series . forceCropping && series . forceCropping ( ) ) ; series . processData ( hasExtemesChanged ) ; } ) ; fireEvent ( this , 'postProcessData' , { hasExtemesChanged } ) ; } axis . setAxisTranslation ( ) ; fireEvent ( this , 'initialAxisTranslation' ) ; if ( axis . pointRange && ! tickIntervalOption ) { axis . tickInterval = Math . max ( axis . pointRange , axis . tickInterval ) ; } const minTickInterval = pick ( options . minTickInterval , axis . dateTime && ! axis . series . some ( ( s ) : boolean | undefined => s . noSharedTooltip ) ? axis . closestPointRange : 0 ) ; if ( ! tickIntervalOption && axis . tickInterval < minTickInterval ) { axis . tickInterval = minTickInterval ; } if ( ! axis . dateTime && ! axis . logarithmic && ! tickIntervalOption ) { axis . tickInterval = normalizeTickInterval ( axis . tickInterval , void 0 , getMagnitude ( axis . tickInterval ) , pick ( options . allowDecimals , axis . tickInterval < 0.5 || this . tickAmount !== void 0 ) , ! ! this . tickAmount ) ; } if ( ! this . tickAmount ) { axis . tickInterval = axis . unsquish ( ) ; } this . setTickPositions ( ) ; } private function emits public setTickPositions ( ) { const axis = this , options = this . options , tickPositionsOption = options . tickPositions , minorTickIntervalOption = this . getMinorTickInterval ( ) , hasVerticalPanning = this . hasVerticalPanning ( ) , isColorAxis = this . coll === 'colorAxis' , startOnTick = ( ( isColorAxis || ! hasVerticalPanning ) && options . startOnTick ) , endOnTick = ( ( isColorAxis || ! hasVerticalPanning ) && options . endOnTick ) ; let tickPositions , tickPositioner = options . tickPositioner ; this . tickmarkOffset = ( this . categories && options . tickmarkPlacement === 'between' && this . tickInterval === 1 ) ? 0.5 : 0 ; this . minorTickInterval = minorTickIntervalOption === 'auto' && this . tickInterval ? this . tickInterval / 5 : ( minorTickIntervalOption as any ) ; this . single = this . min === this . max && defined ( this . min ) && ! this . tickAmount && ( parseInt ( this . min as any , 10 ) === this . min || options . allowDecimals !== false ) ; name type { Highcharts . AxisTickPositionsArray | undefined } this . tickPositions = tickPositions = ( tickPositionsOption && tickPositionsOption . slice ( ) ) as any ; if ( ! tickPositions ) { if ( ( ! axis . ordinal || ! axis . ordinal . positions ) && ( ( ( this . max as any ) - ( this . min as any ) ) / this . tickInterval > Math . max ( 2 * this . len , 200 ) ) ) { tickPositions = [ this . min , this . max ] ; error ( 19 , false , this . chart ) ; } else if ( axis . dateTime ) { tickPositions = ( axis . getTimeTicks as any ) ( axis . dateTime . normalizeTimeTickInterval ( this . tickInterval , options . units ) , this . min , this . max , options . startOfWeek , axis . ordinal && axis . ordinal . positions , this . closestPointRange , true ) ; } else if ( axis . logarithmic ) { tickPositions = axis . logarithmic . getLogTickPositions ( this . tickInterval , this . min as any , this . max as any ) ; } else { tickPositions = this . getLinearTickPositions ( this . tickInterval , this . min as any , this . max as any ) ; } if ( tickPositions . length > this . len ) { tickPositions = [ tickPositions [ 0 ] , tickPositions . pop ( ) ] ; if ( tickPositions [ 0 ] === tickPositions [ 1 ] ) { tickPositions . length = 1 ; } } this . tickPositions = tickPositions ; if ( tickPositioner ) { tickPositioner = tickPositioner . apply ( axis , [ this . min , this . max ] as any ) as any ; if ( tickPositioner ) { this . tickPositions = tickPositions = tickPositioner as any ; } } } this . paddedTicks = tickPositions . slice ( 0 ) ; this . trimTicks ( tickPositions , startOnTick , endOnTick ) ; if ( ! this . isLinked ) { if ( this . single && tickPositions . length < 2 && ! this . categories && ! this . series . some ( ( s ) : boolean => ( s . is ( 'heatmap' ) && s . options . pointPlacement === 'between' ) ) ) { ( this . min as any ) -= 0.5 ; ( this . max as any ) += 0.5 ; } if ( ! tickPositionsOption && ! tickPositioner ) { this . adjustTickAmount ( ) ; } } fireEvent ( this , 'afterSetTickPositions' ) ; } private function param { Array < number > } tickPositions param { boolean } startOnTick param { boolean } endOnTick public trimTicks ( tickPositions , startOnTick ? , endOnTick ? ) { const roundedMin = tickPositions [ 0 ] , roundedMax = tickPositions [ tickPositions . length - 1 ] , minPointOffset = ( ! this . isOrdinal && this . minPointOffset ) || 0 ; fireEvent ( this , 'trimTicks' ) ; if ( ! this . isLinked ) { if ( startOnTick && roundedMin !== - Infinity ) { this . min = roundedMin ; } else { while ( ( this . min as any ) - minPointOffset > tickPositions [ 0 ] ) { tickPositions . shift ( ) ; } } if ( endOnTick ) { this . max = roundedMax ; } else { while ( ( this . max as any ) + minPointOffset < tickPositions [ tickPositions . length - 1 ] ) { tickPositions . pop ( ) ; } } if ( tickPositions . length === 0 && defined ( roundedMin ) && ! this . options . tickPositions ) { tickPositions . push ( ( roundedMax + roundedMin ) / 2 ) ; } } } private function return { boolean | undefined } public alignToOthers ( ) { const axis = this , alignedAxes = [ this ] , options = axis . options , alignThresholds = ( this . coll === 'yAxis' && this . chart . options . chart . alignThresholds ) , thresholdAlignments = [ ] ; let hasOther ; axis . thresholdAlignment = void 0 ; if ( ( ( this . chart . options . chart . alignTicks !== false && options . alignTicks ) || ( alignThresholds ) ) && options . startOnTick !== false && options . endOnTick !== false && ! axis . logarithmic ) { const getKey = ( axis ) : string => { const { horiz , options } = axis ; return [ horiz ? options . left : options . top , options . width , options . height , options . pane ] . join ( ',' ) ; } ; const thisKey = getKey ( this ) ; this . chart [ this . coll as 'xAxis' | 'yAxis' ] . forEach ( function ( otherAxis ) : void { const { series } = otherAxis ; if ( series . length && series . some ( ( s ) : boolean => s . visible ) && otherAxis !== axis && getKey ( otherAxis ) === thisKey ) { hasOther = true ; alignedAxes . push ( otherAxis ) ; } } ) ; } if ( hasOther && alignThresholds ) { alignedAxes . forEach ( ( otherAxis ) : void => { const threshAlign = otherAxis . getThresholdAlignment ( axis ) ; if ( isNumber ( threshAlign ) ) { thresholdAlignments . push ( threshAlign ) ; } } ) ; const thresholdAlignment = thresholdAlignments . length > 1 ? thresholdAlignments . reduce ( ( sum , n ) : number => ( sum += n ) , 0 ) / thresholdAlignments . length : void 0 ; alignedAxes . forEach ( ( axis ) : void => { axis . thresholdAlignment = thresholdAlignment ; } ) ; } return hasOther ; } private function public getThresholdAlignment ( callerAxis ) { if ( ! isNumber ( this . dataMin ) || ( this !== callerAxis && this . series . some ( ( s ) : boolean | undefined => ( s . isDirty || s . isDirtyData ) ) ) ) { this . getSeriesExtremes ( ) ; } if ( isNumber ( this . threshold ) ) { let thresholdAlignment = clamp ( ( ( this . threshold - ( this . dataMin || 0 ) ) / ( ( this . dataMax || 0 ) - ( this . dataMin || 0 ) ) ) , 0 , 1 ) ; if ( this . options . reversed ) { thresholdAlignment = 1 - thresholdAlignment ; } return thresholdAlignment ; } } private function public getTickAmount ( ) { const axis = this , options = this . options , tickPixelInterval = options . tickPixelInterval as any ; let tickAmount = options . tickAmount ; if ( ! defined ( options . tickInterval ) && ! tickAmount && this . len < tickPixelInterval && ! this . isRadial && ! axis . logarithmic && options . startOnTick && options . endOnTick ) { tickAmount = 2 ; } if ( ! tickAmount && this . alignToOthers ( ) ) { tickAmount = Math . ceil ( this . len / ( tickPixelInterval as any ) ) + 1 ; } if ( ( tickAmount as any ) < 4 ) { this . finalTickAmt = tickAmount ; tickAmount = 5 ; } this . tickAmount = ( tickAmount as any ) ; } private function public adjustTickAmount ( ) { const axis = this , { finalTickAmt , max , min , options , tickPositions , tickAmount , thresholdAlignment } = axis , currentTickAmount = tickPositions && tickPositions . length , threshold = pick ( axis . threshold , axis . softThreshold ? 0 : null ) ; let len , i , tickInterval = axis . tickInterval , thresholdTickIndex ; const append = ( ) : number => tickPositions . push ( correctFloat ( tickPositions [ tickPositions . length - 1 ] + tickInterval ) ) , prepend = ( ) : number => tickPositions . unshift ( correctFloat ( tickPositions [ 0 ] - tickInterval ) ) ; if ( isNumber ( thresholdAlignment ) ) { thresholdTickIndex = thresholdAlignment < 0.5 ? Math . ceil ( thresholdAlignment * ( tickAmount - 1 ) ) : Math . floor ( thresholdAlignment * ( tickAmount - 1 ) ) ; if ( options . reversed ) { thresholdTickIndex = tickAmount - 1 - thresholdTickIndex ; } } if ( axis . hasData ( ) && isNumber ( min ) && isNumber ( max ) ) { const adjustExtremes = ( ) : void => { axis . transA *= ( currentTickAmount - 1 ) / ( tickAmount - 1 ) ; axis . min = options . startOnTick ? tickPositions [ 0 ] : Math . min ( min , tickPositions [ 0 ] ) ; axis . max = options . endOnTick ? tickPositions [ tickPositions . length - 1 ] : Math . max ( max , tickPositions [ tickPositions . length - 1 ] ) ; } ; if ( isNumber ( thresholdTickIndex ) && isNumber ( axis . threshold ) ) { while ( tickPositions [ thresholdTickIndex ] !== threshold || tickPositions . length !== tickAmount || tickPositions [ 0 ] > min || tickPositions [ tickPositions . length - 1 ] < max ) { tickPositions . length = 0 ; tickPositions . push ( axis . threshold ) ; while ( tickPositions . length < tickAmount ) { if ( tickPositions [ thresholdTickIndex ] === void 0 || tickPositions [ thresholdTickIndex ] > axis . threshold ) { prepend ( ) ; } else { append ( ) ; } } if ( tickInterval > axis . tickInterval * 8 ) { break ; } tickInterval *= 2 ; } adjustExtremes ( ) ; } else if ( currentTickAmount < tickAmount ) { while ( tickPositions . length < tickAmount ) { if ( tickPositions . length % 2 || min === threshold ) { append ( ) ; } else { prepend ( ) ; } } adjustExtremes ( ) ; } else if ( currentTickAmount > tickAmount ) { axis . tickInterval *= 2 ; axis . setTickPositions ( ) ; } if ( defined ( finalTickAmt ) ) { i = len = tickPositions . length ; while ( i -- ) { if ( ( finalTickAmt === 3 && i % 2 === 1 ) || ( ( finalTickAmt as any ) <= 2 && i > 0 && i < len - 1 ) ) { tickPositions . splice ( i , 1 ) ; } } axis . finalTickAmt = void 0 ; } } } private function emits public setScale ( ) { const axis = this ; let isDirtyData = false , isXAxisDirty = false ; axis . series . forEach ( function ( series ) : void { isDirtyData = isDirtyData || series . isDirtyData || series . isDirty ; isXAxisDirty = ( isXAxisDirty || ( series . xAxis && series . xAxis . isDirty ) || false ) ; } ) ; axis . setAxisSize ( ) ; const isDirtyAxisLength = axis . len !== ( axis . old && axis . old . len ) ; if ( isDirtyAxisLength || isDirtyData || isXAxisDirty || axis . isLinked || axis . forceRedraw || axis . userMin !== ( axis . old && axis . old . userMin ) || axis . userMax !== ( axis . old && axis . old . userMax ) || axis . alignToOthers ( ) ) { if ( axis . stacking ) { axis . stacking . resetStacks ( ) ; } axis . forceRedraw = false ; axis . getSeriesExtremes ( ) ; axis . setTickInterval ( ) ; if ( ! axis . isDirty ) { axis . isDirty = isDirtyAxisLength || axis . min !== ( axis . old && axis . old . min ) || axis . max !== ( axis . old && axis . old . max ) ; } } else if ( axis . stacking ) { axis . stacking . cleanStacks ( ) ; } if ( isDirtyData && axis . panningState ) { axis . panningState . isDirty = true ; } fireEvent ( this , 'afterSetScale' ) ; } sample sample sample sample function param { number } newMin param { number } newMax param { boolean } redraw Whether to redraw the chart or wait for an explicit call to
     *  Highcharts . Chart param { boolean | Partial < Highcharts . AnimationOptionsObject > } animation param { * } eventArguments emits public setExtremes ( newMin ? , newMax ? , redraw ? , animation ? , eventArguments ? ) { const axis = this , chart = axis . chart ; redraw = pick ( redraw , true ) ; axis . series . forEach ( function ( serie ) : void { delete serie . kdTree ; } ) ; eventArguments = extend ( eventArguments , { min : newMin , max : newMax } ) ; fireEvent ( axis , 'setExtremes' , eventArguments , function ( ) : void { axis . userMin = newMin ; axis . userMax = newMax ; axis . eventArgs = eventArguments ; if ( redraw ) { chart . redraw ( animation ) ; } } ) ; } private function public zoom ( newMin , newMax ) { const axis = this , dataMin = this . dataMin , dataMax = this . dataMax , options = this . options , min = Math . min ( dataMin as any , pick ( options . min , dataMin as any ) ) , max = Math . max ( dataMax as any , pick ( options . max , dataMax as any ) ) , evt = { newMin : newMin , newMax : newMax } as AnyRecord ; fireEvent ( this , 'zoom' , evt , function ( e ) : void { let newMin = e . newMin , newMax = e . newMax ; if ( newMin !== axis . min || newMax !== axis . max ) { if ( ! axis . allowZoomOutside ) { if ( defined ( dataMin ) ) { if ( newMin < min ) { newMin = min ; } if ( newMin > max ) { newMin = max ; } } if ( defined ( dataMax ) ) { if ( newMax < min ) { newMax = min ; } if ( newMax > max ) { newMax = max ; } } } axis . displayBtn = ( typeof newMin !== 'undefined' || typeof newMax !== 'undefined' ) ; axis . setExtremes ( newMin , newMax , false , void 0 , { trigger : 'zoom' } ) ; } e . zoomed = true ; } ) ; return evt . zoomed ; } private function public setAxisSize ( ) { const chart = this . chart , options = this . options , offsets = options . offsets || [ 0 , 0 , 0 , 0 ] , horiz = this . horiz , width = this . width = Math . round ( relativeLength ( pick ( options . width , chart . plotWidth - offsets [ 3 ] + offsets [ 1 ] ) , chart . plotWidth ) ) , height = this . height = Math . round ( relativeLength ( pick ( options . height , chart . plotHeight - offsets [ 0 ] + offsets [ 2 ] ) , chart . plotHeight ) ) , top = this . top = Math . round ( relativeLength ( pick ( options . top , chart . plotTop + offsets [ 0 ] ) , chart . plotHeight , chart . plotTop ) ) , left = this . left = Math . round ( relativeLength ( pick ( options . left , chart . plotLeft + offsets [ 3 ] ) , chart . plotWidth , chart . plotLeft ) ) ; this . bottom = ( chart . chartHeight as any ) - height - top ; this . right = ( chart . chartWidth as any ) - width - left ; this . len = Math . max ( horiz ? width : height , 0 ) ; this . pos = horiz ? left : top ; } sample function return { Highcharts . ExtremesObject } public getExtremes ( ) { const axis = this , log = axis . logarithmic ; return { min : log ? correctFloat ( log . lin2log ( axis . min as any ) ) : axis . min as any , max : log ? correctFloat ( log . lin2log ( axis . max as any ) ) : axis . max as any , dataMin : axis . dataMin as any , dataMax : axis . dataMax as any , userMin : axis . userMin as any , userMax : axis . userMax as any } ; } function param { number } threshold return { number | undefined } public getThreshold ( threshold ) { const axis = this , log = axis . logarithmic , realMin = log ? log . lin2log ( axis . min as any ) : axis . min as any , realMax = log ? log . lin2log ( axis . max as any ) : axis . max as any ; if ( threshold === null || threshold === - Infinity ) { threshold = realMin ; } else if ( threshold === Infinity ) { threshold = realMax ; } else if ( realMin > threshold ) { threshold = realMin ; } else if ( realMax < threshold ) { threshold = realMax ; } return axis . translate ( threshold , 0 as any , 1 as any , 0 as any , 1 as any ) ; } private function param { number } rotation return { Highcharts . AlignValue } public autoLabelAlign ( rotation ) { const angle = ( pick ( rotation , 0 ) - ( this . side * 90 ) + 720 ) % 360 , evt = { align : 'center' as AlignValue } ; fireEvent ( this , 'autoLabelAlign' , evt , function ( e ) : void { if ( angle > 15 && angle < 165 ) { e . align = 'right' ; } else if ( angle > 195 && angle < 345 ) { e . align = 'left' ; } } ) ; return evt . align ; } private function param { string } prefix return { Array < number , number > | undefined } public tickSize ( prefix ? ) { const options = this . options , tickWidth = pick ( options [ prefix === 'tick' ? 'tickWidth' : 'minorTickWidth' ] , prefix === 'tick' && this . isXAxis && ! this . categories ? 1 : 0 ) ; let tickLength = options [ prefix === 'tick' ? 'tickLength' : 'minorTickLength' ] , tickSize ; if ( tickWidth && tickLength ) { if ( ( options as any ) [ prefix + 'Position' ] === 'inside' ) { tickLength = - tickLength ; } tickSize = [ tickLength , tickWidth ] ; } const e = { tickSize } ; fireEvent ( this , 'afterTickSize' , e ) ; return e . tickSize ; } private function public labelMetrics ( ) { const index = this . tickPositions && this . tickPositions [ 0 ] || 0 ; return this . chart . renderer . fontMetrics ( this . options . labels . style . fontSize , this . ticks [ index ] && this . ticks [ index ] . label ) ; } private function public unsquish ( ) { const labelOptions = this . options . labels , horiz = this . horiz , tickInterval = this . tickInterval , slotSize = this . len / ( ( ( this . categories ? 1 : 0 ) + ( this . max as any ) - ( this . min as any ) ) / tickInterval ) , rotationOption = labelOptions . rotation , labelMetrics = this . labelMetrics ( ) , range = Math . max ( ( this . max as any ) - ( this . min as any ) , 0 ) , getStep = function ( spaceNeeded ) : number { let step = spaceNeeded / ( slotSize || 1 ) ; step = step > 1 ? Math . ceil ( step ) : 1 ; if ( step * tickInterval > range && spaceNeeded !== Infinity && slotSize !== Infinity && range ) { step = Math . ceil ( range / tickInterval ) ; } return correctFloat ( step * tickInterval ) ; } ; let newTickInterval = tickInterval , rotation , step , bestScore = Number . MAX_VALUE , autoRotation ; if ( horiz ) { if ( ! labelOptions . staggerLines && ! labelOptions . step ) { if ( isNumber ( rotationOption ) ) { autoRotation = [ rotationOption ] ; } else if ( slotSize < labelOptions . autoRotationLimit ) { autoRotation = labelOptions . autoRotation ; } } if ( autoRotation ) { autoRotation . forEach ( function ( rot ) : void { let score ; if ( rot === rotationOption || ( rot && rot >= - 90 && rot <= 90 ) ) { step = getStep ( Math . abs ( labelMetrics . h / Math . sin ( deg2rad * rot ) ) ) ; score = step + Math . abs ( rot / 360 ) ; if ( score < bestScore ) { bestScore = score ; rotation = rot ; newTickInterval = step ; } } } ) ; } } else if ( ! labelOptions . step ) { newTickInterval = getStep ( labelMetrics . h ) ; } this . autoRotation = autoRotation ; this . labelRotation = pick ( rotation , isNumber ( rotationOption ) ? rotationOption : 0 ) ; return newTickInterval ; } private function param { Highcharts . Tick } tick return { number } public getSlotWidth ( tick ? ) { const chart = this . chart , horiz = this . horiz , labelOptions = this . options . labels , slotCount = Math . max ( this . tickPositions . length - ( this . categories ? 0 : 1 ) , 1 ) , marginLeft = chart . margin [ 3 ] ; if ( tick && isNumber ( tick . slotWidth ) ) { return tick . slotWidth ; } if ( horiz && labelOptions . step < 2 ) { if ( labelOptions . rotation ) { return 0 ; } return ( ( this . staggerLines || 1 ) * this . len ) / slotCount ; } if ( ! horiz ) { const cssWidth = labelOptions . style . width ; if ( cssWidth !== void 0 ) { return parseInt ( String ( cssWidth ) , 10 ) ; } if ( marginLeft ) { return marginLeft - chart . spacing [ 3 ] ; } } return chart . chartWidth * 0.33 ; } private function public renderUnsquish ( ) { const chart = this . chart , renderer = chart . renderer , tickPositions = this . tickPositions , ticks = this . ticks , labelOptions = this . options . labels , labelStyleOptions = labelOptions . style , horiz = this . horiz , slotWidth = this . getSlotWidth ( ) , innerWidth = Math . max ( 1 , Math . round ( slotWidth - 2 * labelOptions . padding ) ) , attr = { } , labelMetrics = this . labelMetrics ( ) , textOverflowOption = labelStyleOptions . textOverflow ; let commonWidth , commonTextOverflow , maxLabelLength = 0 , label , i , pos ; if ( ! isString ( labelOptions . rotation ) ) { attr . rotation = labelOptions . rotation || 0 ; } tickPositions . forEach ( function ( tickPosition ) : void { const tick = ticks [ tickPosition ] ; if ( tick . movedLabel ) { tick . replaceMovedLabel ( ) ; } if ( tick && tick . label && tick . label . textPxLength > maxLabelLength ) { maxLabelLength = tick . label . textPxLength ; } } ) ; this . maxLabelLength = maxLabelLength ; if ( this . autoRotation ) { if ( maxLabelLength > innerWidth && maxLabelLength > labelMetrics . h ) { attr . rotation = this . labelRotation ; } else { this . labelRotation = 0 ; } } else if ( slotWidth ) { commonWidth = innerWidth ; if ( ! textOverflowOption ) { commonTextOverflow = 'clip' ; i = tickPositions . length ; while ( ! horiz && i -- ) { pos = tickPositions [ i ] ; label = ticks [ pos ] . label ; if ( label ) { if ( label . styles && label . styles . textOverflow === 'ellipsis' ) { label . css ( { textOverflow : 'clip' } ) ; } else if ( label . textPxLength > slotWidth ) { label . css ( { width : slotWidth + 'px' } ) ; } if ( label . getBBox ( ) . height > ( this . len / tickPositions . length - ( labelMetrics . h - labelMetrics . f ) ) ) { label . specificTextOverflow = 'ellipsis' ; } } } } } if ( attr . rotation ) { commonWidth = ( maxLabelLength > ( chart . chartHeight as any ) * 0.5 ? ( chart . chartHeight as any ) * 0.33 : maxLabelLength ) ; if ( ! textOverflowOption ) { commonTextOverflow = 'ellipsis' ; } } this . labelAlign = labelOptions . align || this . autoLabelAlign ( this . labelRotation as any ) ; if ( this . labelAlign ) { attr . align = this . labelAlign ; } tickPositions . forEach ( function ( pos ) : void { const tick = ticks [ pos ] , label = tick && tick . label , widthOption = labelStyleOptions . width , css = { } ; if ( label ) { label . attr ( attr ) ; if ( tick . shortenLabel ) { tick . shortenLabel ( ) ; } else if ( commonWidth && ! widthOption && labelStyleOptions . whiteSpace !== 'nowrap' && ( commonWidth < label . textPxLength || label . element . tagName === 'SPAN' ) ) { css . width = commonWidth + 'px' ; if ( ! textOverflowOption ) { css . textOverflow = ( label . specificTextOverflow || commonTextOverflow ) ; } label . css ( css ) ; } else if ( label . styles && label . styles . width && ! css . width && ! widthOption ) { label . css ( { width : null as any } ) ; } delete label . specificTextOverflow ; tick . rotation = attr . rotation ; } } , this ) ; this . tickRotCorr = renderer . rotCorr ( labelMetrics . b , this . labelRotation || 0 , this . side !== 0 ) ; } function return { boolean } public hasData ( ) { return this . series . some ( function ( s ) : boolean { return s . hasData ( ) ; } ) || ( this . options . showEmpty && defined ( this . min ) && defined ( this . max ) ) ; } function param { boolean } display public addTitle ( display ? ) { const axis = this , renderer = axis . chart . renderer , horiz = axis . horiz , opposite = axis . opposite , options = axis . options , axisTitleOptions = options . title , styledMode = axis . chart . styledMode ; let textAlign ; if ( ! axis . axisTitle ) { textAlign = axisTitleOptions . textAlign ; if ( ! textAlign ) { textAlign = ( ( horiz ? { low : 'left' , middle : 'center' , high : 'right' } : { low : opposite ? 'right' : 'left' , middle : 'center' , high : opposite ? 'left' : 'right' } ) as Record < string , AlignValue > ) [ axisTitleOptions . align as any ] ; } axis . axisTitle = renderer . text ( axisTitleOptions . text || '' , 0 , 0 , axisTitleOptions . useHTML ) . attr ( { zIndex : 7 , rotation : axisTitleOptions . rotation , align : textAlign } ) . addClass ( 'highcharts-axis-title' ) ; if ( ! styledMode ) { axis . axisTitle . css ( merge ( axisTitleOptions . style ) ) ; } axis . axisTitle . add ( axis . axisGroup ) ; axis . axisTitle . isNew = true ; } if ( ! styledMode && ! axisTitleOptions . style . width && ! axis . isRadial ) { axis . axisTitle . css ( { width : axis . len + 'px' } ) ; } axis . axisTitle [ display ? 'show' : 'hide' ] ( display ) ; } private function param { number } pos param { number } i The index of the tick in  Axis . tickPositions .
      public generateTick ( pos ) { const axis = this , ticks = axis . ticks ; if ( ! ticks [ pos ] ) { ticks [ pos ] = new Tick ( axis , pos ) ; } else { ticks [ pos ] . addLabel ( ) ; } } private function emits public getOffset ( ) { const axis = this , { chart , horiz , options , side , ticks , tickPositions , coll , axisParent } = axis , renderer = chart . renderer , invertedSide = ( chart . inverted && ! axis . isZAxis ? [ 1 , 0 , 3 , 2 ] [ side ] : side ) , hasData = axis . hasData ( ) , axisTitleOptions = options . title , labelOptions = options . labels , axisOffset = chart . axisOffset , clipOffset = chart . clipOffset , directionFactor = [ - 1 , 1 , 1 , - 1 ] [ side ] , className = options . className ; let showAxis , titleOffset = 0 , titleOffsetOption , titleMargin = 0 , labelOffset = 0 , labelOffsetPadded , lineHeightCorrection ; axis . showAxis = showAxis = hasData || options . showEmpty ; axis . staggerLines = ( axis . horiz && labelOptions . staggerLines ) || void 0 ; if ( ! axis . axisGroup ) { const createGroup = ( name , suffix , zIndex ) : SVGElement => renderer . g ( name ) . attr ( { zIndex } ) . addClass ( `highcharts-${ coll . toLowerCase ( ) }${ suffix } ` + ( this . isRadial ? `highcharts-radial-axis${ suffix } ` : '' ) + ( className || '' ) ) . add ( axisParent ) ; axis . gridGroup = createGroup ( 'grid' , '-grid' , options . gridZIndex ) ; axis . axisGroup = createGroup ( 'axis' , '' , options . zIndex ) ; axis . labelGroup = createGroup ( 'axis-labels' , '-labels' , labelOptions . zIndex ) ; } if ( hasData || axis . isLinked ) { tickPositions . forEach ( function ( pos ) : void { axis . generateTick ( pos ) ; } ) ; axis . renderUnsquish ( ) ; axis . reserveSpaceDefault = ( side === 0 || side === 2 || ( { 1 : 'left' , 3 : 'right' } as any ) [ side ] === axis . labelAlign ) ; if ( pick ( labelOptions . reserveSpace , axis . labelAlign === 'center' ? true : null , axis . reserveSpaceDefault ) ) { tickPositions . forEach ( function ( pos ) : void { labelOffset = Math . max ( ticks [ pos ] . getLabelSize ( ) , labelOffset ) ; } ) ; } if ( axis . staggerLines ) { labelOffset *= axis . staggerLines ; } axis . labelOffset = labelOffset * ( axis . opposite ? - 1 : 1 ) ; } else { objectEach ( ticks , function ( tick , n ) : void { tick . destroy ( ) ; delete ticks [ n ] ; } ) ; } if ( axisTitleOptions && axisTitleOptions . text && axisTitleOptions . enabled !== false ) { axis . addTitle ( showAxis ) ; if ( showAxis && axisTitleOptions . reserveSpace !== false ) { axis . titleOffset = titleOffset = ( axis . axisTitle as any ) . getBBox ( ) [ horiz ? 'height' : 'width' ] ; titleOffsetOption = axisTitleOptions . offset ; titleMargin = defined ( titleOffsetOption ) ? 0 : pick ( axisTitleOptions . margin , horiz ? 5 : 10 ) ; } } axis . renderLine ( ) ; axis . offset = directionFactor * pick ( options . offset , axisOffset [ side ] ? axisOffset [ side ] + ( options . margin || 0 ) : 0 ) ; axis . tickRotCorr = axis . tickRotCorr || { x : 0 , y : 0 } ; if ( side === 0 ) { lineHeightCorrection = - axis . labelMetrics ( ) . h ; } else if ( side === 2 ) { lineHeightCorrection = axis . tickRotCorr . y ; } else { lineHeightCorrection = 0 ; } labelOffsetPadded = Math . abs ( labelOffset ) + titleMargin ; if ( labelOffset ) { labelOffsetPadded -= lineHeightCorrection ; labelOffsetPadded += directionFactor * ( horiz ? pick ( labelOptions . y , axis . tickRotCorr . y + directionFactor * 8 ) : labelOptions . x ) ; } axis . axisTitleMargin = pick ( titleOffsetOption , labelOffsetPadded ) ; if ( axis . getMaxLabelDimensions ) { axis . maxLabelDimensions = axis . getMaxLabelDimensions ( ticks , tickPositions ) ; } if ( coll !== 'colorAxis' ) { const tickSize = this . tickSize ( 'tick' ) ; axisOffset [ side ] = Math . max ( axisOffset [ side ] , ( axis . axisTitleMargin || 0 ) + titleOffset + directionFactor * axis . offset , labelOffsetPadded , tickPositions && tickPositions . length && tickSize ? tickSize [ 0 ] + directionFactor * axis . offset : 0 ) ; const clip = ! axis . axisLine || options . offset ? 0 : Math . floor ( axis . axisLine . strokeWidth ( ) / 2 ) * 2 ; ( clipOffset as any ) [ invertedSide ] = Math . max ( ( clipOffset as any ) [ invertedSide ] , clip ) ; } fireEvent ( this , 'afterGetOffset' ) ; } function param { number } lineWidth return { Highcharts . SVGPathArray } public getLinePath ( lineWidth ) { const chart = this . chart , opposite = this . opposite , offset = this . offset , horiz = this . horiz , lineLeft = this . left + ( opposite ? this . width : 0 ) + offset , lineTop = ( chart . chartHeight as any ) - this . bottom - ( opposite ? this . height : 0 ) + offset ; if ( opposite ) { lineWidth *= - 1 ; } return chart . renderer . crispLine ( [ [ 'M' , horiz ? this . left : lineLeft , horiz ? lineTop : this . top ] , [ 'L' , horiz ? ( chart . chartWidth as any ) - this . right : lineLeft , horiz ? lineTop : ( chart . chartHeight as any ) - this . bottom ] ] , lineWidth ) ; } function public renderLine ( ) { if ( ! this . axisLine ) { this . axisLine = this . chart . renderer . path ( ) . addClass ( 'highcharts-axis-line' ) . add ( this . axisGroup ) ; if ( ! this . chart . styledMode ) { this . axisLine . attr ( { stroke : this . options . lineColor , 'stroke-width' : this . options . lineWidth , zIndex : 7 } ) ; } } } private function return { Highcharts . PositionObject } public getTitlePosition ( ) { const horiz = this . horiz , axisLeft = this . left , axisTop = this . top , axisLength = this . len , axisTitleOptions = this . options . title , margin = horiz ? axisLeft : axisTop , opposite = this . opposite , offset = this . offset , xOption = axisTitleOptions . x , yOption = axisTitleOptions . y , axisTitle = this . axisTitle , fontMetrics = this . chart . renderer . fontMetrics ( axisTitleOptions . style . fontSize , axisTitle ) , textHeightOvershoot = Math . max ( ( axisTitle as any ) . getBBox ( null , 0 ) . height - fontMetrics . h - 1 , 0 ) , alongAxis = ( { low : margin + ( horiz ? 0 : axisLength ) , middle : margin + axisLength / 2 , high : margin + ( horiz ? axisLength : 0 ) } as any ) [ axisTitleOptions . align as any ] , offAxis = ( horiz ? axisTop + this . height : axisLeft ) + ( horiz ? 1 : - 1 ) * ( opposite ? - 1 : 1 ) * ( this . axisTitleMargin as any ) + [ - textHeightOvershoot , textHeightOvershoot , fontMetrics . f , - textHeightOvershoot ] [ this . side ] , titlePosition = { x : horiz ? alongAxis + xOption : offAxis + ( opposite ? this . width : 0 ) + offset + xOption , y : horiz ? offAxis + yOption - ( opposite ? this . height : 0 ) + offset : alongAxis + yOption } ; fireEvent ( this , 'afterGetTitlePosition' , { titlePosition : titlePosition } ) ; return titlePosition ; } function param { number } pos param { boolean } slideIn public renderMinorTick ( pos , slideIn ? ) { const axis = this ; const minorTicks = axis . minorTicks ; if ( ! minorTicks [ pos ] ) { minorTicks [ pos ] = new Tick ( axis , pos , 'minor' ) ; } if ( slideIn && minorTicks [ pos ] . isNew ) { minorTicks [ pos ] . render ( null as any , true ) ; } minorTicks [ pos ] . render ( null as any , false , 1 ) ; } function param { number } pos param { number } i param { boolean } slideIn public renderTick ( pos , i , slideIn ? ) { const axis = this , isLinked = axis . isLinked , ticks = axis . ticks ; if ( ! isLinked || ( pos >= ( axis . min as any ) && pos <= ( axis . max as any ) ) || ( axis . grid && axis . grid . isColumn ) ) { if ( ! ticks [ pos ] ) { ticks [ pos ] = new Tick ( axis , pos ) ; } if ( slideIn && ticks [ pos ] . isNew ) { ticks [ pos ] . render ( i , true , - 1 ) ; } ticks [ pos ] . render ( i ) ; } } private function emits public render ( ) { const axis = this , chart = axis . chart , log = axis . logarithmic , renderer = chart . renderer , options = axis . options , isLinked = axis . isLinked , tickPositions = axis . tickPositions , axisTitle = axis . axisTitle , ticks = axis . ticks , minorTicks = axis . minorTicks , alternateBands = axis . alternateBands , stackLabelOptions = ( options as YAxisOptions ) . stackLabels , alternateGridColor = options . alternateGridColor , tickmarkOffset = axis . tickmarkOffset , axisLine = axis . axisLine , showAxis = axis . showAxis , animation = animObject ( renderer . globalAnimation ) ; let from , to ; axis . labelEdge . length = 0 ; axis . overlap = false ; [ ticks , minorTicks , alternateBands ] . forEach ( function ( coll ) : void { objectEach ( coll , function ( tick ) : void { tick . isActive = false ; } ) ; } ) ; if ( axis . hasData ( ) || isLinked ) { const slideInTicks = axis . chart . hasRendered && axis . old && isNumber ( axis . old . min ) ; if ( axis . minorTickInterval && ! axis . categories ) { axis . getMinorTickPositions ( ) . forEach ( function ( pos ) : void { axis . renderMinorTick ( pos , slideInTicks ) ; } ) ; } if ( tickPositions . length ) { tickPositions . forEach ( function ( pos , i ) : void { axis . renderTick ( pos , i , slideInTicks ) ; } ) ; if ( tickmarkOffset && ( axis . min === 0 || axis . single ) ) { if ( ! ticks [ - 1 ] ) { ticks [ - 1 ] = new Tick ( axis , - 1 , null as any , true ) ; } ticks [ - 1 ] . render ( - 1 ) ; } } if ( alternateGridColor ) { tickPositions . forEach ( function ( pos , i ) : void { to = typeof tickPositions [ i + 1 ] !== 'undefined' ? tickPositions [ i + 1 ] + tickmarkOffset : ( axis . max as any ) - tickmarkOffset ; if ( i % 2 === 0 && pos < ( axis . max as any ) && to <= ( axis . max as any ) + ( chart . polar ? - tickmarkOffset : tickmarkOffset ) ) { if ( ! alternateBands [ pos ] ) { alternateBands [ pos ] = new ( H as any ) . PlotLineOrBand ( axis ) ; } from = pos + tickmarkOffset ; alternateBands [ pos ] . options = { from : log ? log . lin2log ( from ) : from , to : log ? log . lin2log ( to ) : to , color : alternateGridColor , className : 'highcharts-alternate-grid' } ; alternateBands [ pos ] . render ( ) ; alternateBands [ pos ] . isActive = true ; } } ) ; } if ( ! axis . _addedPlotLB ) { axis . _addedPlotLB = true ; ( options . plotLines || [ ] ) . concat ( ( options . plotBands as any ) || [ ] ) . forEach ( function ( plotLineOptions ) : void { ( axis as unknown as PlotLineOrBand . Axis ) . addPlotBandOrLine ( plotLineOptions ) ; } ) ; } } [ ticks , minorTicks , alternateBands ] . forEach ( function ( coll ) : void { const forDestruction = [ ] , delay = animation . duration , destroyInactiveItems = function ( ) : void { let i = forDestruction . length ; while ( i -- ) { if ( coll [ forDestruction [ i ] ] && ! coll [ forDestruction [ i ] ] . isActive ) { coll [ forDestruction [ i ] ] . destroy ( ) ; delete coll [ forDestruction [ i ] ] ; } } } ; objectEach ( coll , function ( tick , pos ) : void { if ( ! tick . isActive ) { tick . render ( pos as any , false , 0 ) ; tick . isActive = false ; forDestruction . push ( pos as any ) ; } } ) ; syncTimeout ( destroyInactiveItems , coll === alternateBands || ! chart . hasRendered || ! delay ? 0 : delay ) ; } ) ; if ( axisLine ) { axisLine [ axisLine . isPlaced ? 'animate' : 'attr' ] ( { d : this . getLinePath ( axisLine . strokeWidth ( ) ) } ) ; axisLine . isPlaced = true ; axisLine [ showAxis ? 'show' : 'hide' ] ( showAxis ) ; } if ( axisTitle && showAxis ) { const titleXy = axis . getTitlePosition ( ) ; if ( isNumber ( titleXy . y ) ) { axisTitle [ axisTitle . isNew ? 'attr' : 'animate' ] ( titleXy ) ; axisTitle . isNew = false ; } else { axisTitle . attr ( 'y' , - 9999 as any ) ; axisTitle . isNew = true ; } } if ( stackLabelOptions && stackLabelOptions . enabled && axis . stacking ) { axis . stacking . renderStackTotals ( ) ; } axis . old = { len : axis . len , max : axis . max , min : axis . min , transA : axis . transA , userMax : axis . userMax , userMin : axis . userMin } ; axis . isDirty = false ; fireEvent ( this , 'afterRender' ) ; } private function public redraw ( ) { if ( this . visible ) { this . render ( ) ; this . plotLinesAndBands . forEach ( function ( plotLine ) : void { plotLine . render ( ) ; } ) ; } this . series . forEach ( function ( series ) : void { series . isDirty = true ; } ) ; } private function public getKeepProps ( ) { return ( this . keepProps || Axis . keepProps ) ; } /**
     * Destroys an Axis instance. See  Axis for the API endpoint
     * to fully remove the axis.
     *
     *  private function param { boolean } keepEvents public destroy ( keepEvents ? ) { const axis = this , plotLinesAndBands = axis . plotLinesAndBands , eventOptions = this . eventOptions ; fireEvent ( this , 'destroy' , { keepEvents : keepEvents } ) ; if ( ! keepEvents ) { removeEvent ( axis ) ; } [ axis . ticks , axis . minorTicks , axis . alternateBands ] . forEach ( function ( coll ) : void { destroyObjectProperties ( coll ) ; } ) ; if ( plotLinesAndBands ) { let i = plotLinesAndBands . length ; while ( i -- ) { plotLinesAndBands [ i ] . destroy ( ) ; } } [ 'axisLine' , 'axisTitle' , 'axisGroup' , 'gridGroup' , 'labelGroup' , 'cross' , 'scrollbar' ] . forEach ( function ( prop ) : void { if ( ( axis as any ) [ prop ] ) { ( axis as any ) [ prop ] = ( axis as any ) [ prop ] . destroy ( ) ; } } ) ; for ( const plotGroup in axis . plotLinesAndBandsGroups ) { axis . plotLinesAndBandsGroups [ plotGroup ] = axis . plotLinesAndBandsGroups [ plotGroup ] . destroy ( ) as any ; } objectEach ( axis , function ( val , key ) : void { if ( axis . getKeepProps ( ) . indexOf ( key ) === - 1 ) { delete ( axis as any ) [ key ] ; } } ) ; this . eventOptions = eventOptions ; } function param { Highcharts . PointerEventObject } e param { Highcharts . Point } point emits emits public drawCrosshair ( e ? , point ? ) { const options = this . crosshair , snap = pick ( options && options . snap , true ) , chart = this . chart ; let path , pos , categorized , graphic = this . cross , crossOptions ; fireEvent ( this , 'drawCrosshair' , { e : e , point : point } ) ; if ( ! e ) { e = this . cross && this . cross . e ; } if ( ! options || ( ( defined ( point ) || ! snap ) === false ) ) { this . hideCrosshair ( ) ; } else { if ( ! snap ) { pos = e && ( this . horiz ? e . chartX - ( this . pos as any ) : this . len - e . chartY + ( this . pos as any ) ) ; } else if ( defined ( point ) ) { pos = pick ( this . coll !== 'colorAxis' ? ( point as any ) . crosshairPos : null , this . isXAxis ? ( point as any ) . plotX : this . len - ( point as any ) . plotY ) ; } if ( defined ( pos ) ) { crossOptions = { value : point && ( this . isXAxis ? point . x : pick ( point . stackY , point . y ) ) as any , translatedValue : pos } ; if ( chart . polar ) { extend ( crossOptions , { isCrosshair : true , chartX : e && e . chartX , chartY : e && e . chartY , point : point } ) ; } path = this . getPlotLinePath ( crossOptions ) || null ; } if ( ! defined ( path ) ) { this . hideCrosshair ( ) ; return ; } categorized = this . categories && ! this . isRadial ; if ( ! graphic ) { this . cross = graphic = chart . renderer . path ( ) . addClass ( 'highcharts-crosshair highcharts-crosshair-' + ( categorized ? 'category ' : 'thin ' ) + ( options . className || '' ) ) . attr ( { zIndex : pick ( options . zIndex , 2 ) } ) . add ( ) ; if ( ! chart . styledMode ) { graphic . attr ( { stroke : options . color || ( categorized ? Color . parse ( Palette . highlightColor20 ) . setOpacity ( 0.25 ) . get ( ) : Palette . neutralColor20 ) , 'stroke-width' : pick ( options . width , 1 ) } ) . css ( { 'pointer-events' : 'none' } ) ; if ( options . dashStyle ) { graphic . attr ( { dashstyle : options . dashStyle } ) ; } } } graphic . show ( ) . attr ( { d : path } ) ; if ( categorized && ! ( options as any ) . width ) { graphic . attr ( { 'stroke-width' : this . transA } ) ; } ( this . cross as any ) . e = e ; } fireEvent ( this , 'afterDrawCrosshair' , { e : e , point : point } ) ; } function public hideCrosshair ( ) { if ( this . cross ) { this . cross . hide ( ) ; } fireEvent ( this , 'afterHideCrosshair' ) ; } private function public hasVerticalPanning ( ) { const panningOptions = this . chart . options . chart . panning ; return Boolean ( panningOptions && panningOptions . enabled && /y/ . test ( panningOptions . type ) ) ; } private function param { unknown } value public validatePositiveValue ( value ) { return isNumber ( value ) && value > 0 ; } sample function param { Highcharts . AxisOptions } options param { boolean } redraw Whether to redraw the chart after the axis is altered. If doing more
     * operations on the chart, it is a good idea to set redraw to false and
     * call  Chart after.
      public update ( options , redraw ? ) { const chart = this . chart ; options = merge ( this . userOptions , options ) ; this . destroy ( true ) ; this . init ( chart , options ) ; chart . isDirtyBox = true ; if ( pick ( redraw , true ) ) { chart . redraw ( ) ; } } sample function param { boolean } redraw public remove ( redraw ? ) { const chart = this . chart , key = this . coll , axisSeries = this . series ; let i = axisSeries . length ; while ( i -- ) { if ( axisSeries [ i ] ) { axisSeries [ i ] . remove ( false ) ; } } erase ( chart . axes , this ) ; erase ( ( chart as any ) [ key ] , this ) ; ( chart as any ) [ key ] . forEach ( function ( axis , i ) : void { axis . options . index = axis . userOptions . index = i ; } ) ; this . destroy ( ) ; chart . isDirtyBox = true ; if ( pick ( redraw , true ) ) { chart . redraw ( ) ; } } sample function param { Highcharts . AxisTitleOptions } titleOptions param { boolean } redraw public setTitle ( titleOptions , redraw ? ) { this . update ( { title : titleOptions } , redraw ) ; } sample function param { Array < string > } categories param { boolean } redraw public setCategories ( categories , redraw ? ) { this . update ( { categories : categories } , redraw ) ; } } interface Axis extends AxisComposition , AxisLike { } namespace Axis { export interface ExtremesObject { dataMax : number ; dataMin : number ; max : number ; min : number ; userMax : number ; userMin : number ; } export interface PanningState { startMin : ( number ) ; startMax : ( number ) ; isDirty ? : boolean ; } export interface PlotLinePathOptions { acrossPanes ? : boolean ; force ? : ( boolean | string ) ; lineWidth ? : number ; old ? : boolean ; reverse ? : boolean ; translatedValue ? : number ; value ? : number ; } } export default Axis ; interface name type { number | undefined } name type { number | undefined } name type { string | boolean | undefined } name type { boolean | undefined } name type { boolean | undefined } name type { number | undefined } name type { boolean | undefined } product typedef { Highcharts . XAxisCrosshairOptions | Highcharts . YAxisCrosshairOptions } Highcharts . AxisCrosshairOptions typedef { "navigator" | "pan" | "rangeSelectorButton" | "rangeSelectorInput" | "scrollbar" | "traverseUpButton" | "zoom" } Highcharts . AxisExtremesTriggerValue callback Highcharts . AxisEventCallbackFunction param { Highcharts . Axis } this callback Highcharts . AxisLabelsFormatterCallbackFunction param { Highcharts . AxisLabelsFormatterContextObject } this param { Highcharts . AxisLabelsFormatterContextObject } ctx return { string } interface name type { Highcharts . Axis } name type { Highcharts . Chart } name type { boolean } name type { boolean } name type { number } name type { string } name type { Highcharts . Tick } name type { number | string } typedef { Highcharts . XAxisOptions | Highcharts . YAxisOptions | Highcharts . ZAxisOptions } Highcharts . AxisOptions callback Highcharts . AxisPointBreakEventCallbackFunction param { Highcharts . Axis } this param { Highcharts . AxisPointBreakEventObject } evt interface name type { Highcharts . Dictionary < number > } name type { Highcharts . Point } name type { Function } name type { Highcharts . SVGElement } name type { "pointBreak" | "pointInBreak" } callback Highcharts . AxisSetExtremesEventCallbackFunction param { Highcharts . Axis } this param { Highcharts . AxisSetExtremesEventObject } evt interface extends Highcharts . ExtremesObject name type { Function } name type { Highcharts . SVGElement } name type { Highcharts . AxisExtremesTriggerValue | string } name type { "setExtremes" } callback Highcharts . AxisTickPositionerCallbackFunction param { Highcharts . Axis } this return { Highcharts . AxisTickPositionsArray } interface augments Array < number > typedef { "high" | "low" | "middle" } Highcharts . AxisTitleAlignValue typedef { Highcharts . XAxisTitleOptions | Highcharts . YAxisTitleOptions | Highcharts . ZAxisTitleOptions } Highcharts . AxisTitleOptions typedef { "linear" | "logarithmic" | "datetime" | "category" | "treegrid" } Highcharts . AxisTypeValue /**
 * The returned object literal from the  Highcharts . Axis * function.
 *
 *  interface name type { number } name type { number } name type { number } name type { number } name type { number } name type { number } callback Highcharts . XAxisCrosshairLabelFormatterCallbackFunction param { Highcharts . Axis } this param { number } value return { string } '' ;