import { MIN_LABEL_WIDTH } from '../constants' ; import { Column , IArrayColumn , IDataRow , ICategoricalLikeColumn , isMapAbleColumn , DEFAULT_COLOR } from '../model' ; import { hsl } from 'd3-color' ; import { cssClass } from '../styles' ; import type { ISequence } from '../internal' ; import type { IRenderContext } from './interfaces' ; internal export function noop ( ) { } export const noRenderer = { template : `<div></div>` , update : noop as ( ) => void , } ; internal export function setText < T extends Node > ( node , text ? ) { if ( text === undefined ) { return node ; } if ( node . textContent !== text ) { node . textContent = text ; } return node ; } param node param selector param callback internal export function forEach < T extends Element > ( node , selector , callback ) { Array . from ( node . querySelectorAll < T > ( selector ) ) . forEach ( callback ) ; } internal export function forEachChild < T extends Element > ( node , callback ) { ( Array . from ( node . children ) as T [ ] ) . forEach ( callback ) ; } param { HTMLElement } node param columns internal export function matchColumns ( node , columns , ctx ) { if ( node . childElementCount === 0 ) { node . innerHTML = columns . map ( ( c ) => c . template ) . join ( '' ) ; const children = Array . from ( node . children ) ; columns . forEach ( ( col , i ) => { const childNode = children [ i ] as HTMLElement ; childNode . dataset . columnId = col . column . id ; childNode . dataset . renderer = col . rendererId ; childNode . classList . add ( cssClass ( `renderer-${ col . rendererId }` ) ) ; } ) ; return ; } function matches ( c , i ) { const n = node . children [ i ] as HTMLElement ; return n != null && n . dataset . columnId === c . column . id && n . dataset . renderer === c . rendererId ; } if ( columns . every ( matches ) ) { return ; } const idsAndRenderer = new Set ( columns . map ( ( c ) => `${ c . column . id }@${ c . rendererId }` ) ) ; forEachChild ( node , ( n ) => { const id = n . dataset . columnId ; const renderer = n . dataset . renderer ; const idAndRenderer = `${ id }@${ renderer }` ; if ( ! idsAndRenderer . has ( idAndRenderer ) ) { node . removeChild ( n ) ; } } ) ; columns . forEach ( ( col ) => { let childNode = node . querySelector < HTMLElement > ( `[data-column-id="${ col . column . id }"]` ) ; if ( ! childNode ) { childNode = ctx . asElement ( col . template ) ; childNode . dataset . columnId = col . column . id ; childNode . dataset . renderer = col . rendererId ; childNode . classList . add ( cssClass ( `renderer-${ col . rendererId }` ) ) ; } node . appendChild ( childNode ) ; } ) ; } export function wideEnough ( col , length = col . labels . length ) { const w = col . getWidth ( ) ; return w / length > MIN_LABEL_WIDTH ; } export function wideEnoughCat ( col ) { const w = col . getWidth ( ) ; return w / col . categories . length > MIN_LABEL_WIDTH ; } const adaptColorCache = { } ; param { string } bgColor returns { string } export function adaptTextColorToBgColor ( bgColor ) { const bak = adaptColorCache [ bgColor ] ; if ( bak ) { return bak ; } return ( adaptColorCache [ bgColor ] = hsl ( bgColor ) . l > 0.5 ? 'black' : 'white' ) ; } param { HTMLElement } node param { string } bgColor param { string } title param { number } width export function adaptDynamicColorToBgColor ( node , bgColor , title , width ) { const adapt = adaptTextColorToBgColor ( bgColor ) ; if ( width <= 0.05 || adapt === 'black' || width > 0.9 ) { node . style . color = adapt === 'black' || width <= 0.05 ? null : adapt ; return ; } node . style . color = null ; node . innerText = title ; const span = node . ownerDocument ! . createElement ( 'span' ) ; span . classList . add ( cssClass ( 'gradient-text' ) ) ; span . style . color = adapt ; span . innerText = title ; node . appendChild ( span ) ; } internal export const uniqueId = ( function ( ) { let idCounter = 0 ; return ( prefix ) => `${ prefix }${ ( idCounter ++ ) . toString ( 36 ) }` ; } ) ( ) ; const NUM_EXAMPLE_VALUES = 5 ; internal export function exampleText ( col , rows ) { const examples = [ ] ; rows . every ( ( row ) => { if ( col . getValue ( row ) == null ) { return true ; } const v = col . getLabel ( row ) ; examples . push ( v ) ; return examples . length < NUM_EXAMPLE_VALUES ; } ) ; if ( examples . length === 0 ) { return '' ; } return `${ examples . join ( ', ' ) }${ examples . length < rows . length ? ', ...' : '' }` ; } internal export function multiLevelGridCSSClass ( idPrefix , column ) { return cssClass ( `stacked-${ idPrefix }-${ column . id }` ) ; } internal export function colorOf ( col ) { if ( isMapAbleColumn ( col ) ) { return col . getColorMapping ( ) . apply ( 0 ) ; } return DEFAULT_COLOR ; }