import { extent } from 'd3-array' ; import { ScaleType } from '../scales/constants' ; import { DomainPaddingUnit , YDomainRange } from '../specs' ; public export type OrdinalDomain = ( number | string ) [ ] ; public export type ContinuousDomain = [ min : number , max : number ] ; public export type Range = [ min : number , max : number ] ; function constrainPadding ( start , end , newStart , newEnd , constrain = true ) { return constrain ? start < end ? [ newStart >= 0 || start < 0 ? newStart : 0 , newEnd <= 0 || end > 0 ? newEnd : 0 ] : [ newEnd >= 0 || end < 0 ? newEnd : 0 , newStart <= 0 || start > 0 ? newStart : 0 ] : [ newStart , newEnd ] ; } internal export function computeOrdinalDataDomain < T > ( data , sorted , removeNull ) { const uniqueValues = [ ... new Set ( removeNull ? data . filter ( ( d ) => d !== null ) : data ) ] ; return sorted ? uniqueValues . sort ( ( a , b ) => `${ a }` . localeCompare ( `${ b }` ) ) : uniqueValues ; } function getPaddedDomain ( start , end , domainOptions ) { const { padding , paddingUnit = DomainPaddingUnit . Domain } = domainOptions ; if ( ! padding || paddingUnit === DomainPaddingUnit . Pixel ) return [ start , end ] ; const computedPadding = Math . abs ( padding * ( paddingUnit === DomainPaddingUnit . Domain ? 1 : end - start ) ) ; return constrainPadding ( start , end , start - computedPadding , end + computedPadding , domainOptions . constrainPadding ) ; } internal export function computeDomainExtent ( domain , domainOptions ) { if ( domain [ 0 ] === undefined ) return [ 0 , 0 ] ; const inverted = domain [ 0 ] > domain [ 1 ] ; const paddedDomain = ( ( [ start , end ] ) : Range => { const [ paddedStart , paddedEnd ] = getPaddedDomain ( start , end , domainOptions ) ; if ( paddedStart >= 0 && paddedEnd >= 0 ) return domainOptions . fit ? [ paddedStart , paddedEnd ] : [ 0 , paddedEnd ] ; if ( paddedStart < 0 && paddedEnd < 0 ) return domainOptions . fit ? [ paddedStart , paddedEnd ] : [ paddedStart , 0 ] ; return [ paddedStart , paddedEnd ] ; } ) ( inverted ? [ domain [ 1 ] , domain [ 0 ] ] : domain ) ; return inverted ? [ paddedDomain [ 1 ] , paddedDomain [ 0 ] ] : paddedDomain ; } internal export function computeContinuousDataDomain ( data , scaleType , domainOptions ) { const filteredData = domainOptions ?. fit && scaleType === ScaleType . Log ? data . filter ( ( d ) => d !== 0 ) : data ; const range = extent < number , number > ( filteredData , ( d ) => d ) ; return domainOptions === undefined ? [ range [ 0 ] ?? 0 , range [ 1 ] ?? 0 ] : computeDomainExtent ( range , domainOptions ) ; }