# All files / components LineLayer.tsx

93.94% Statements 31/33
50% Branches 7/14
100% Functions 3/3
93.94% Lines 31/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
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    1071x

    1x
    1x
    1x
    1x
    1x
    1x

    1x

    7x
    7x
    7x
    7x
    7x
    7x
    7x
    7x
    7x

    7x

    7x
    3x

    7x

    7x

    6x

    7x
    7x
    7x

    7x

    7x

    7x

    7x

    1x
     import React, {FunctionComponent, RefObject, useMemo} from 'react'

    import {LayerProps, LineLayerSpec, LineLayerConfig} from '../types'
    import {LineHoverLayer} from './LineHoverLayer'
    import {simplifyLineData} from '../utils/lineData'
    import {useCanvas} from '../utils/useCanvas'
    import {drawLines} from '../utils/drawLines'
    import {useHoverPointIndices} from '../utils/useHoverPointIndices'
    import {FILL} from '../constants/columnKeys'

    export interface Props extends LayerProps {
      spec: LineLayerSpec
      config: LineLayerConfig
      canvasRef: RefObject<HTMLCanvasElement>
    }

    export const LineLayer: FunctionComponent<Props> = props => {
      const {
        config,
        spec,
        width,
        height,
        xScale,
        yScale,
        hoverX,
        hoverY,
        canvasRef,
      } = props
      const {position} = config

      const simplifiedLineData = useMemo(
        () => simplifyLineData(spec.lineData, xScale, yScale),
        [spec.lineData, xScale, yScale]
      )

      const drawLinesOptions = {
        lineData: simplifiedLineData,
        interpolation: config.interpolation,
        lineWidth: config.lineWidth,
        shadeBelow: config.shadeBelow,
        shadeBelowOpacity: config.shadeBelowOpacity,
        shadeAboveY: height,
      }

      useCanvas(
        canvasRef,
        width,
        height,
        context => drawLines({context, ...drawLinesOptions}),
        Object.values(drawLinesOptions)
      )

      let hoverDimension: 'x' | 'y' | 'xy'

      Eif (config.hoverDimension === 'auto') {
        hoverDimension = 'x'
        Iif (Object.keys(spec.lineData).length > config.maxTooltipRows) {
          hoverDimension = 'xy'
        }
      } else {
        hoverDimension = config.hoverDimension
      }

      const hoverYColumnData =
        position === 'stacked'
          ? spec.stackedDomainValueColumn
          : spec.table.getColumn(config.y, 'number')
      const hoverRowIndices = useHoverPointIndices(
        hoverDimension,
        hoverX,
        hoverY,
        spec.table.getColumn(config.x, 'number'),
        hoverYColumnData,
        spec.table.getColumn(FILL, 'number'),
        xScale,
        yScale,
        width,
        height
      )

      const hasHoverData = hoverRowIndices && hoverRowIndices.length > 0

      return (
        <>
          <canvas
            className="giraffe-layer giraffe-layer-line"
            ref={canvasRef}
            style={{
              position: 'absolute',
              opacity: hoverDimension === 'xy' && hasHoverData ? 0.4 : 1,
            }}
            data-testid="giraffe-layer-line"
          />
          {hasHoverData && (
            <LineHoverLayer
              {...props}
              rowIndices={hoverRowIndices}
              dimension={hoverDimension}
              simplifiedLineData={simplifiedLineData}
            />
          )}
        </>
      )
    }

    LineLayer.displayName = 'LineLayer'