import { Color , Colors } from '../../../../common/colors' ; import { Font } from '../../../../common/text_utils' ; import { clearCanvas , renderLayers , withContext } from '../../../../renderers/canvas' ; import { renderMultiLine } from '../../../xy_chart/renderer/canvas/primitives/line' ; import { renderRect } from '../../../xy_chart/renderer/canvas/primitives/rect' ; import { renderText , wrapLines } from '../../../xy_chart/renderer/canvas/primitives/text' ; import { ShapeViewModel } from '../../layout/types/viewmodel_types' ; import { ChartElementSizes } from '../../state/selectors/compute_chart_dimensions' ; internal export function renderCanvas2d ( ctx , dpr , { theme , heatmapViewModel } , background , elementSizes , debug ) { withContext ( ctx , ( ) => { ctx . scale ( dpr , dpr ) ; ctx . textAlign = 'center' ; ctx . textBaseline = 'middle' ; const filteredCells = heatmapViewModel . cells . filter ( ( cell ) => cell . yIndex < heatmapViewModel . pageSize ) ; const filteredYValues = heatmapViewModel . yValues . filter ( ( value , yIndex ) => yIndex < heatmapViewModel . pageSize ) ; renderLayers ( ctx , [ ( ) => clearCanvas ( ctx , background ) , ( ) => debug && withContext ( ctx , ( ) => { ctx . strokeStyle = 'black' ; ctx . strokeRect ( elementSizes . grid . left , elementSizes . grid . top , elementSizes . grid . width , elementSizes . grid . height ) ; ctx . strokeStyle = 'red' ; ctx . strokeRect ( elementSizes . xAxis . left , elementSizes . xAxis . top , elementSizes . xAxis . width , elementSizes . xAxis . height ) ; ctx . strokeStyle = 'violet' ; ctx . strokeRect ( elementSizes . yAxis . left , elementSizes . yAxis . top , elementSizes . yAxis . width , elementSizes . yAxis . height ) ; } ) , ( ) => { withContext ( ctx , ( ) => { renderMultiLine ( ctx , heatmapViewModel . gridLines . x , heatmapViewModel . gridLines . stroke ) ; renderMultiLine ( ctx , heatmapViewModel . gridLines . y , heatmapViewModel . gridLines . stroke ) ; } ) ; } , ( ) => withContext ( ctx , ( ) => { const { x , y } = heatmapViewModel . gridOrigin ; ctx . translate ( x , y ) ; filteredCells . forEach ( ( cell ) => { if ( cell . visible ) renderRect ( ctx , cell , cell . fill , cell . stroke ) ; } ) ; } ) , ( ) => theme . cell . label . visible && withContext ( ctx , ( ) => { const { x , y } = heatmapViewModel . gridOrigin ; ctx . translate ( x , y ) ; filteredCells . forEach ( ( cell ) => { const fontSize = heatmapViewModel . cellFontSize ( cell ) ; if ( cell . visible && Number . isFinite ( fontSize ) ) renderText ( ctx , { x : cell . x + cell . width / 2 , y : cell . y + cell . height / 2 } , cell . formatted , { ... theme . cell . label , fontSize , align : 'center' , baseline : 'middle' , textColor : cell . textColor , } ) ; } ) ; } ) , ( ) => theme . yAxisLabel . visible && withContext ( ctx , ( ) => { ctx . translate ( elementSizes . yAxis . left + elementSizes . yAxis . width , elementSizes . yAxis . top ) ; filteredYValues . forEach ( ( yValue ) => { const font = { fontFamily : theme . yAxisLabel . fontFamily , fontStyle : theme . yAxisLabel . fontStyle ? theme . yAxisLabel . fontStyle : 'normal' , fontVariant : 'normal' , fontWeight : 'normal' , textColor : Colors . Black . keyword , } ; const { padding } = theme . yAxisLabel ; const horizontalPadding = typeof padding === 'number' ? padding * 2 : ( padding . left ?? 0 ) + ( padding . right ?? 0 ) ; const [ resultText ] = wrapLines ( ctx , yValue . text , font , theme . yAxisLabel . fontSize , heatmapViewModel . gridOrigin . x - horizontalPadding , 16 , { shouldAddEllipsis : true , wrapAtWord : false } ) . lines ; renderText ( ctx , { x : yValue . x , y : yValue . y } , resultText , { ... theme . yAxisLabel , align : 'right' } ) ; } ) ; } ) , ( ) => theme . xAxisLabel . visible && withContext ( ctx , ( ) => { ctx . translate ( elementSizes . xAxis . left , elementSizes . xAxis . top ) ; heatmapViewModel . xValues . forEach ( ( xValue ) => renderText ( ctx , { x : xValue . x , y : xValue . y } , xValue . text , theme . xAxisLabel ) ) ; } ) , ( ) => withContext ( ctx , ( ) => { heatmapViewModel . titles . filter ( ( t ) => t . visible && t . text !== '' ) . forEach ( ( title ) => { renderText ( ctx , title . origin , title . text , { ... title , baseline : 'middle' , align : 'center' , } , title . rotation ) ; } ) ; } ) , ] ) ; } ) ; }