import { timeFormat , timeParse } from 'd3-time-format' ; import { ISequence , equal , IEventListener } from '../internal' ; import { Category , dialogAddons , toolbar } from './annotations' ; import Column , { dirty , dirtyCaches , dirtyHeader , dirtyValues , groupRendererChanged , labelChanged , metaDataChanged , rendererTypeChanged , summaryRendererChanged , visibilityChanged , widthChanged , DEFAULT_COLOR , } from './Column' ; import type { IDateColumn , IDateDesc , IDateFilter , IDateGrouper } from './IDateColumn' ; import { defaultGroup , IDataRow , IGroup , ECompareValueType , IValueColumnDesc , ITypeFactory } from './interfaces' ; import { isMissingValue , isUnknown , missingGroup } from './missing' ; import type { dataLoaded } from './ValueColumn' ; import ValueColumn from './ValueColumn' ; import { noDateFilter , defaultDateGrouper , isDummyDateFilter , isDefaultDateGrouper , restoreDateFilter , isEqualDateFilter , isDateIncluded , toDateGroup , chooseAggregatedDate , } from './internalDate' ; import { integrateDefaults } from './internal' ; export declare type IDateColumnDesc = IValueColumnDesc < Date > & IDateDesc ; asMemberOf event export declare function filterChanged_DC ( previous , current ) ; asMemberOf event export declare function groupingChanged_DC ( previous , current ) ; @ toolbar ( 'rename' , 'clone' , 'sort' , 'sortBy' , 'groupBy' , 'sortGroupBy' , 'filterDate' ) @ dialogAddons ( 'group' , 'groupDate' ) @ Category ( 'date' ) export default class DateColumn extends ValueColumn < Date > implements IDateColumn { static readonly EVENT_FILTER_CHANGED = 'filterChanged' ; static readonly EVENT_GROUPING_CHANGED = 'groupingChanged' ; static readonly DEFAULT_DATE_FORMAT = '%x' ; private readonly format : ( date : Date | null ) => string ; private readonly parse : ( date : string ) => Date | null ; type { { min : number , max : number } } private private currentFilter : IDateFilter = noDateFilter ( ) ; private currentGrouper : IDateGrouper = defaultDateGrouper ( ) ; constructor ( id , desc ) { super ( id , integrateDefaults ( desc , { groupRenderer : 'datehistogram' , summaryRenderer : 'datehistogram' , } ) ) ; const f = timeFormat ( desc . dateFormat || DateColumn . DEFAULT_DATE_FORMAT ) ; this . format = ( v ) => ( v instanceof Date ? f ( v ) : '' ) ; this . parse = desc . dateParse ? timeParse ( desc . dateParse ) : timeParse ( desc . dateFormat || DateColumn . DEFAULT_DATE_FORMAT ) ; } getFormatter ( ) { return this . format ; } dump ( toDescRef ) { const r = super . dump ( toDescRef ) ; r . filter = isDummyDateFilter ( this . currentFilter ) ? null : this . currentFilter ; if ( this . currentGrouper && ! isDefaultDateGrouper ( this . currentGrouper ) ) { r . grouper = this . currentGrouper ; } return r ; } restore ( dump , factory ) { super . restore ( dump , factory ) ; if ( dump . filter ) { this . currentFilter = restoreDateFilter ( dump . filter ) ; } if ( dump . grouper ) { this . currentGrouper = dump . grouper ; } } protected createEventList ( ) { return super . createEventList ( ) . concat ( [ DateColumn . EVENT_FILTER_CHANGED , DateColumn . EVENT_GROUPING_CHANGED ] ) ; } on ( type , listener ) ; on ( type , listener ) ; on ( type , listener ) ; on ( type , listener ) ; on ( type , listener ) ; on ( type , listener ) ; on ( type , listener ) ; on ( type , listener ) ; on ( type , listener ) ; on ( type , listener ) ; on ( type , listener ) ; on ( type , listener ) ; on ( type , listener ) ; on ( type , listener ) ; on ( type , listener ) ; on ( type , listener ) { return super . on ( type as any , listener ) ; } getValue ( row ) { return this . getDate ( row ) ; } getDate ( row ) { const v = super . getValue ( row ) ; if ( isMissingValue ( v ) ) { return null ; } if ( v instanceof Date ) { return v ; } return this . parse ( String ( v ) ) ; } iterDate ( row ) { return [ this . getDate ( row ) ] ; } getLabel ( row ) { const v = this . getValue ( row ) ; return this . format ( v ) ; } isFiltered ( ) { return ! isDummyDateFilter ( this . currentFilter ) ; } clearFilter ( ) { const was = this . isFiltered ( ) ; this . setFilter ( null ) ; return was ; } getFilter ( ) { return Object . assign ( { } , this . currentFilter ) ; } setFilter ( value ) { value = value || { min : Number . NEGATIVE_INFINITY , max : Number . POSITIVE_INFINITY , filterMissing : false } ; if ( isEqualDateFilter ( value , this . currentFilter ) ) { return ; } const bak = this . getFilter ( ) ; this . currentFilter . min = isUnknown ( value . min ) ? Number . NEGATIVE_INFINITY : value . min ; this . currentFilter . max = isUnknown ( value . max ) ? Number . POSITIVE_INFINITY : value . max ; this . currentFilter . filterMissing = value . filterMissing ; this . fire ( [ DateColumn . EVENT_FILTER_CHANGED , Column . EVENT_DIRTY_VALUES , Column . EVENT_DIRTY ] , bak , this . getFilter ( ) ) ; } param row returns { boolean } filter ( row , valueCache ? ) { return isDateIncluded ( this . currentFilter , valueCache !== undefined ? valueCache : this . getDate ( row ) ) ; } toCompareValue ( row , valueCache ? ) { const v = valueCache !== undefined ? valueCache : this . getValue ( row ) ; if ( ! ( v instanceof Date ) ) { return NaN ; } return v . getTime ( ) ; } toCompareValueType ( ) { return ECompareValueType . DOUBLE_ASC ; } getDateGrouper ( ) { return Object . assign ( { } , this . currentGrouper ) ; } setDateGrouper ( value ) { if ( equal ( this . currentGrouper , value ) ) { return ; } const bak = this . getDateGrouper ( ) ; this . currentGrouper = Object . assign ( { } , value ) ; this . fire ( [ DateColumn . EVENT_GROUPING_CHANGED , Column . EVENT_DIRTY_VALUES , Column . EVENT_DIRTY ] , bak , value ) ; } group ( row , valueCache ? ) { const v = valueCache !== undefined ? valueCache : this . getDate ( row ) ; if ( ! v || ! ( v instanceof Date ) ) { return Object . assign ( { } , missingGroup ) ; } if ( ! this . currentGrouper ) { return Object . assign ( { } , defaultGroup ) ; } const g = toDateGroup ( this . currentGrouper , v ) ; return { name : g . name , color : DEFAULT_COLOR , } ; } toCompareGroupValue ( rows , _group , valueCache ? ) { const v = chooseAggregatedDate ( rows , this . currentGrouper , this , valueCache ) . value ; return v == null ? NaN : v ; } toCompareGroupValueType ( ) { return ECompareValueType . DOUBLE_ASC ; } }