# All files / utils drawBands.ts

10.29% Statements 7/68
0% Branches 0/16
0% Functions 0/14
12.73% Lines 7/55

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
    85
    86
    87
    88
    89
    90
    91
    921x
    1x

    1x
    1x
    1x

    1x

    1x

     import {line, curveLinear, area} from 'd3-shape'
    import {range} from 'd3-array'

    import {BandLineMap, LineData, LineInterpolation} from '../types'
    import {CURVES} from '../constants'
    import {LOWER, UPPER} from '../constants/columnKeys'
    import {isDefined} from '../utils/isDefined'

    import {getBands} from '../transforms/band'

    interface DrawBandsOptions {
      bandLineMap: BandLineMap
      context: CanvasRenderingContext2D
      interpolation: LineInterpolation
      lineData: LineData
      lineWidth: number
      lineOpacity: number
      shadeOpacity: number
    }

    export const drawBands = ({
      bandLineMap,
      context,
      interpolation,
      lineData,
      lineWidth,
      lineOpacity,
      shadeOpacity,
    }: DrawBandsOptions): void => {
      const bands = getBands(lineData, bandLineMap)

      // draw shading
      for (const band of bands) {
        const lower = band[LOWER]
        const upper = band[UPPER]
        if (lower) {
          const {xs: xs_min, ys: ys_min} = lower
          const minAreaGenerator = area<number>()
            .y1((i: any) => band.ys[i])
            .y0((i: any) => ys_min[i])
            .x1((i: any) => band.xs[i])
            .x0((i: any) => xs_min[i])
            .context(context)
            .defined((i: any) => isDefined(xs_min[i]) && isDefined(ys_min[i]))
            .curve(CURVES[interpolation] || curveLinear)

          context.fillStyle = lower.fill
          context.globalAlpha = shadeOpacity
          context.beginPath()
          minAreaGenerator(range(0, xs_min.length))
          context.fill()
        }

        if (upper) {
          const {xs: xs_max, ys: ys_max} = upper
          const maxAreaGenerator = area<number>()
            .y1((i: any) => ys_max[i])
            .y0((i: any) => band.ys[i])
            .x1((i: any) => xs_max[i])
            .x0((i: any) => band.xs[i])
            .context(context)
            .defined((i: any) => isDefined(xs_max[i]) && isDefined(ys_max[i]))
            .curve(CURVES[interpolation] || curveLinear)

          context.fillStyle = upper.fill
          context.globalAlpha = shadeOpacity
          context.beginPath()
          maxAreaGenerator(range(0, xs_max.length))
          context.fill()
        }
      }

      context.lineWidth = lineWidth
      context.globalAlpha = lineOpacity

      // draw lines
      for (const {xs, ys, fill} of bands) {
        const lineGenerator = line<number>()
          .context(context)
          .y((i: any) => ys[i])
          .x((i: any) => xs[i])
          .context(context)
          .defined((i: any) => isDefined(xs[i]) && isDefined(ys[i]))
          .curve(CURVES[interpolation] || curveLinear)

        context.strokeStyle = fill
        context.beginPath()
        lineGenerator(range(0, xs.length))
        context.stroke()
      }
    }