# All files / components AnnotationLine.tsx

41.18% Statements 7/17
0% Branches 0/14
0% Functions 0/1
58.33% Lines 7/12

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
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    1281x

    1x

    1x
    1x
    1x

    1x

    1x
     import React, {FunctionComponent, createElement} from 'react'
    import {AnnotationDimension, AnnotationPinType} from '../types'

    import styles from './AnnotationLine.scss'

    interface AnnotationLineProps {
      dimension: AnnotationDimension
      color: string
      strokeWidth: number
      startValue: number
      stopValue: number
      length: number
      pin: AnnotationPinType
      id: string
    }

    // These could become configurable values
    const PIN_CIRCLE_RADIUS = 4
    const PIN_TRIANGLE_HEIGHT = 8
    const PIN_TRIANGLE_WIDTH = 6

    export const AnnotationLine: FunctionComponent<AnnotationLineProps> = props => {
      const {dimension, color, strokeWidth, startValue, length, pin} = props

      // This prevents blurry sub-pixel rendering as well as clipped lines
      // If the line is at the edge of the canvas the stroke will be half obscured
      // because the stroke is centered on the line. Giving a minimum value
      // prevents the line from being clipped
      const clampedStart = Math.max(1, Math.round(startValue))

      if (dimension === 'y') {
        return (
          <>
            <line
              x1="0"
              x2={length}
              y1={clampedStart}
              y2={clampedStart}
              stroke={color}
              strokeWidth={strokeWidth}
              id={props.id}
              className={`${styles['giraffe-annotation-hover']} giraffe-annotation-line`}
            />
            {pin === 'circle' &&
              createElement('circle', {
                r: PIN_CIRCLE_RADIUS,
                fill: color,
                cx: length - PIN_CIRCLE_RADIUS,
                cy: clampedStart,
              })}
            {pin === 'start' &&
              createElement('polygon', {
                points: `${length - PIN_TRIANGLE_HEIGHT}, ${clampedStart} ${length -
                  PIN_TRIANGLE_HEIGHT / 2}, ${clampedStart +
                  PIN_TRIANGLE_WIDTH} ${length}, ${clampedStart}`,
                fill: color,
                style: {cursor: 'pointer'},
                id: props.id,
                className: 'giraffe-annotation-click-target',
              })}
            {pin === 'stop' &&
              createElement('polygon', {
                points: `${length - PIN_TRIANGLE_HEIGHT}, ${clampedStart} ${length -
                  PIN_TRIANGLE_HEIGHT / 2}, ${clampedStart -
                  PIN_TRIANGLE_WIDTH} ${length}, ${clampedStart}`,
                fill: color,
              })}
          </>
        )
      }

      return (
        // a separate line layer on the annotation line is required on top,
        // because the dashed line doesnt allow for a continuous click-able target
        // this top layer has an opacity of 0 so is not visible.
        <>
          <line
            x1={clampedStart}
            x2={clampedStart}
            y1="0"
            y2={length}
            stroke={color}
            strokeOpacity={0}
            strokeWidth={strokeWidth}
            id={props.id}
            className={`${styles['giraffe-annotation-hover']} giraffe-annotation-line`}
          />
          <line
            x1={clampedStart}
            x2={clampedStart}
            y1="0"
            y2={length}
            stroke={color}
            strokeWidth={strokeWidth}
            id={props.id}
            className={`${styles['giraffe-annotation-hover']} giraffe-annotation-line`}
            strokeDasharray={'4'}
          />
          {pin === 'circle' &&
            createElement('circle', {
              r: PIN_CIRCLE_RADIUS,
              fill: color,
              cx: clampedStart,
              cy: PIN_CIRCLE_RADIUS,
            })}
          {pin === 'start' &&
            createElement('polygon', {
              points: `${clampedStart - PIN_TRIANGLE_WIDTH}, 0
              ${clampedStart + PIN_TRIANGLE_WIDTH}, 0
              ${clampedStart}, ${PIN_TRIANGLE_HEIGHT}`,
              fill: color,
              style: {cursor: 'pointer'},
              id: props.id,
              className: 'giraffe-annotation-click-target',
            })}
          {pin === 'stop' &&
            createElement('polygon', {
              points: `${clampedStart}, 0 ${clampedStart -
                PIN_TRIANGLE_WIDTH}, ${PIN_TRIANGLE_HEIGHT /
                2} ${clampedStart}, ${PIN_TRIANGLE_HEIGHT}`,
              fill: color,
            })}
        </>
      )
    }

    export default AnnotationLine