# All files / utils drawMosaic.ts

5.77% Statements 3/52
0% Branches 0/10
0% Functions 0/1
6.25% Lines 3/48

Press n or j to go to the next uncovered block, b, p or k for the previous block.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    851x

    1x

    1x

     import {color} from 'd3-color'

    import {Table, Scale, ColumnType} from '../types'
    import {X_MIN, X_MAX, FILL, SERIES} from '../constants/columnKeys'

    interface DrawMosaicOptions {
      context: CanvasRenderingContext2D
      table: Table
      xScale: Scale<number, number>
      yScale: Scale<number, number>
      fillScale: Scale<number, string>
      hoveredRowIndices: number[]
      strokeWidth: number
      strokePadding: number
      strokeOpacity: number
      fillOpacity: number
      yColumnType: ColumnType
    }

    export const drawMosaic = ({
      context,
      table,
      xScale,
      yScale,
      fillScale,
      hoveredRowIndices,
      strokeWidth,
      strokePadding,
      strokeOpacity,
      fillOpacity,
    }: DrawMosaicOptions): void => {
      const xMinCol = table.getColumn(X_MIN, 'number')
      const xMaxCol = table.getColumn(X_MAX, 'number')
      const valueCol = table.getColumn(FILL, 'string')
      const yCol = table.getColumn(SERIES, 'string')
      context.globalAlpha = fillOpacity

      const yValMap = new Map()
      // if key isn't in map yet, add it & increment number
      let i = 0
      for (const key of yCol) {
        if (!yValMap.has(key)) {
          yValMap.set(key, i)
          i++
        }
      }

      for (let i = 0; i < xMaxCol.length; i++) {
        const x = xScale(xMinCol[i])

        const yVal = yValMap.get(yCol[i])
        const y = yScale(yVal)

        const width = xScale(xMaxCol[i]) - x - strokePadding
        const height = yScale(yValMap.size + 1)
        let fill = fillScale((valueCol[i] as unknown) as number)

        if (hoveredRowIndices && hoveredRowIndices.includes(i)) {
          fill = color(fill)
            .brighter(1)
            .hex()
        }

        if (strokeWidth || strokeOpacity) {
          // See https://stackoverflow.com/a/45125187
          context.beginPath()
          context.rect(x, y, width, height)
          context.save()
          context.clip()
          context.lineWidth = strokeWidth * 2

          context.fillStyle = fill
          context.fill()
          context.strokeStyle = fill
          context.stroke()
          context.restore()
        } else {
          context.fillStyle = fill
          context.beginPath()
          context.rect(x, y, width, height)
          context.fill()
        }
      }
    }