# All files / utils textMetrics.ts

67.64% Statements 23/34
50% Branches 2/4
66.66% Functions 2/3
66.66% Lines 22/33

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
    2x

    2x
    15x
    3x

    12x
    12x

    12x
    30x
    30x
    12x

    12x

    2x
    15x
    15x

    15x

    15x

    15x

    15x

    15x

    15x

    15x

    2x

     import {TextMetrics} from '../types'
    import {STATIC_LEGEND_COLUMN_CLASSNAME} from '../constants'

    const addPaddingToSampleText = (text: string): string => {
      if (typeof text !== 'string') {
        return text
      }

      const skinnyCharacters = ['-', '1', '|', 'i', 'l', 'I', 't']
      let sample = text

      for (let index = 0; index < text.length; index += 1) {
        const char = text.charAt(index)
        if (skinnyCharacters.includes(char)) {
          sample += char
        }
      }
      return sample
    }

    export const getTextMetrics = (font: string, text: string): TextMetrics => {
      const div = document.createElement('div')
      const span = document.createElement('span')

      div.appendChild(span)

      // Translate offscreen
      div.setAttribute(
        'style',
        `font: ${font}; display: inline; position: fixed; transform: translate(-9999px, -9999px);`
      )

      document.body.appendChild(div)

      // Text with the same number of characters:
      //   when it includes a skinny character (defined above), it tends to be skinnier than
      //   a positive number because the skinny character is not as wide as a single digit (most of the time).
      //   Add padding when text has a skinny character by making them twice as wide.
      span.innerText = addPaddingToSampleText(text)

      const metrics = {
        width: span.offsetWidth,
        height: span.offsetHeight,
      }

      document.body.removeChild(div)

      return metrics
    }

    interface StaticLegendTextMetrics {
      headerTextMetrics: TextMetrics
      sampleTextMetrics: TextMetrics
    }

    export const getStaticLegendTexMetrics = (): StaticLegendTextMetrics => {
      const sampleHeader = document.querySelector(
        `.${STATIC_LEGEND_COLUMN_CLASSNAME}-header`
      ) as HTMLElement

      const sampleValue = document.querySelector(
        `.${STATIC_LEGEND_COLUMN_CLASSNAME}-value`
      ) as HTMLElement

      const headerTextMetrics: TextMetrics = {height: 0, width: 0}
      const sampleTextMetrics: TextMetrics = {height: 0, width: 0}

      Iif (sampleHeader) {
        headerTextMetrics.height = sampleHeader.offsetHeight
        headerTextMetrics.width = sampleHeader.offsetWidth
      }

      Iif (sampleValue) {
        sampleTextMetrics.height = sampleValue.offsetHeight
        sampleTextMetrics.width = sampleValue.offsetWidth
      }

      return {
        headerTextMetrics,
        sampleTextMetrics,
      }
    }