import { ScaleCreationContext } from '@chart-parts/interfaces' ; import { extent } from 'd3-array' ; import { scaleQuantize , ScaleQuantize } from 'd3-scale' ; import { DomainRangeScale } from './DomainRangeScale' ; import { QuantitativeValue } from './quantitative/QuantitativeScale' ; import { optionalArgument } from './util' ; export class QuantizeScale < DomainValue extends QuantitativeValue , RangeValue extends QuantitativeValue > extends DomainRangeScale < [ DomainValue , DomainValue ] , RangeValue [ ] , any > { protected niceValue ? : number | boolean ; protected zeroValue ? : boolean ; public handleRangeBind ( ) { throw new Error ( 'cannot use range binding on Quantize scale' ) ; } /**
     * Extends the domain so that it starts and ends on nice round values.
     */ public nice ( value ? ) { this . niceValue = optionalArgument ( value , arguments . length , true , false ) ; return this ; } /**
     * Boolean flag indicating if the scale domain should include zero.
     * The default value is true for linear, sqrt and pow, and false otherwise.
     */ public zero ( value ? ) { this . zeroValue = optionalArgument ( value , arguments . length , true , false ) ; return this ; } public createScale ( args ) { const domain = this . getDomain ( args ) ; const range = this . getRange ( args ) ; const scale = scaleQuantize ( ) . domain ( domain ) . range ( range as any ) as ScaleQuantize < RangeValue > ; this . applyNice ( scale ) ; if ( ! this . nameValue ) { throw new Error ( 'scale name must be defined' ) ; } return { [ this . nameValue ] : scale , } ; } protected processDomainValues ( values ) { const result = extent ( values as any [ ] ) as [ DomainValue , DomainValue ] ; if ( this . zeroValue && ! this . domainContainsZero ( result ) ) { const [ min , max ] = result ; const zero = 0 as DomainValue ; return 0 < min ? [ zero , max ] : [ min , zero ] ; } return result ; } protected domainContainsZero ( domain ) { return 0 >= domain [ 0 ] && 0 <= domain [ 1 ] ; } private applyNice ( scale ) { const v = this . niceValue ; if ( v != null ) { if ( v === true ) { scale . nice ( ) ; } else if ( typeof v === 'number' ) { scale . nice ( v ) ; } } } }