import { Theme } from '@thematic/core' ; import { Axis } from 'd3-axis' ; import { Selection } from 'd3-selection' ; import { svg as svgCall , rect as rectCall , line as lineCall , text as textCall , } from './svg' ; export interface SelectionOptions { /**
     * This is a map of event handlers to apply to the selection.
     */ on ? : { [ key ] : any ; } ; /**
     * This is a map of ad-hoc attrs to apply to the selection.
     */ attr ? : { [ key ] : any ; } ; /**
     * Map of ad-hoc classes to add or remove from the selection.
     */ classed ? : { [ key ] : any ; } ; /**
     * Map of ad-hoc styles to add or remove from the selection.
     */ style ? : { [ key ] : any ; } ; } export interface ChartOptions extends SelectionOptions { width ? : number ; height ? : number ; } export interface PlotAreaOptions extends ChartOptions { marginTop ? : number ; marginBottom ? : number ; marginLeft ? : number ; marginRight ? : number ; } function getSelectionOptions ( selection , options ? ) { const _on = ( options && options . on ) || { } ; const _attr = ( options && options . attr ) || { } ; const _classed = ( options && options . classed ) || { } ; const _style = ( options && options . style ) || { } ; return { on : _on , attr : _attr , classed : _classed , style : _style } ; } function getChartOptions ( selection , options ? ) { const w = options && options . width ; const h = options && options . height ; const width = w || + selection . attr ( 'width' ) || 0 ; const height = h || + selection . attr ( 'height' ) || 0 ; const sOpts = getSelectionOptions ( selection , options ) ; return { on : sOpts . on , attr : { width , height , ... sOpts . attr , } , classed : sOpts . classed , style : sOpts . style , } ; } function getPlotAreaOptions ( selection , options ? ) { const marginTop = ( options && options . marginTop ) || 0 ; const marginBottom = ( options && options . marginBottom ) || 0 ; const marginLeft = ( options && options . marginLeft ) || 0 ; const marginRight = ( options && options . marginRight ) || 0 ; const w = options && options . width ; const h = options && options . height ; const parent = selection . select ( function ( this ) { return this . parentNode ; } as any ) ; const pw = ( parent && + parent . attr ( 'width' ) ) || 0 ; const ph = ( parent && + parent . attr ( 'height' ) ) || 0 ; const width = w || pw - marginLeft - marginRight ; const height = h || ph - marginTop - marginBottom ; const sOpts = getSelectionOptions ( selection , options ) ; return { width , height , marginTop , marginBottom , marginLeft , marginRight , on : sOpts . on , attr : { width , height , ... sOpts . attr , } , classed : sOpts . classed , style : sOpts . style , } ; } param selection param attrs export function attr ( selection , attrs ? ) { let ret = selection ; Object . entries ( attrs || { } ) . forEach ( entry => { const [ key , value ] = entry ; ret = selection . attr ( key , value as any ) ; } ) ; return ret ; } param selection param ons export function on ( selection , ons ? ) { let ret = selection ; Object . entries ( ons || { } ) . forEach ( entry => { const [ key , value ] = entry ; ret = selection . on ( key , value as any ) ; } ) ; return ret ; } param selection param classes export function classed ( selection , classes ? ) { let ret = selection ; Object . entries ( classes || { } ) . forEach ( entry => { const [ key , value ] = entry ; ret = selection . classed ( key , value as any ) ; } ) ; return ret ; } param selection param styles export function style ( selection , styles ? ) { let ret = selection ; Object . entries ( styles || { } ) . forEach ( entry => { const [ key , value ] = entry ; ret = selection . style ( key , value as any ) ; } ) ; return ret ; } function applyBaseOptions ( selection , options ? ) { return selection . call ( on , options ?. on ) . call ( attr , options ?. attr ) . call ( classed , options ?. classed ) . call ( style , options ?. style ) ; } param svg param theme export function chart ( svg , theme , options ? ) { const opts = getChartOptions ( svg , options ) ; return svg . classed ( 'thematic-chart' , true ) . call ( svgCall , theme . chart ( ) ) . call ( applyBaseOptions , opts ) ; } param group param theme param options export function plotArea ( group , theme , options ? ) { const p = theme . plotArea ( ) ; const opts = getPlotAreaOptions ( group , options ) ; const { marginTop , marginLeft } = opts ; group . classed ( 'thematic-plot-area' , true ) . attr ( 'transform' , `translate(${ marginLeft },${ marginTop })` ) ; group . append ( 'rect' ) . classed ( 'thematic-plot-area-background' , true ) . call ( rectCall as any , p ) . call ( applyBaseOptions as any , opts ) ; return group ; } param group param theme param axisGenerator param options export function axis ( group , theme , axisGenerator , options ? ) { const opts = getSelectionOptions ( group , options ) ; const ticks = theme . axisTicks ( ) ; axisGenerator . tickSizeInner ( ticks . innerSize ( ) ) ; axisGenerator . tickSizeOuter ( ticks . outerSize ( ) ) ; group . call ( axisGenerator as any ) . call ( g => g . select ( '.domain' ) . call ( lineCall as any , theme . axisLine ( ) ) ) . call ( g => g . selectAll ( '.tick > line' ) . call ( lineCall as any , ticks ) ) . call ( g => g . selectAll ( '.tick > text' ) . call ( textCall as any , theme . axisTickLabels ( ) ) ) . call ( applyBaseOptions , opts ) ; return group ; }