All files / owid-grapher/grapher/color ColorScaleBin.ts

100% Statements 88/88
87.5% Branches 14/16
100% Functions 11/11
100% Lines 88/88

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 1211x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 276x 276x 1x 72x 72x 1x 6x 6x 1x 1x 1x 1x 24x 24x 1x 24x 24x 1x 6x 6x 6x 1x 2x 2x 2x 1x 6x 6x 1x 2x 2x 1x 1x 18x 18x 18x 18x 18x 18x 18x 18x 18x 18x 18x 18x 18x 18x 7x 18x 11x 11x 18x 1x 1x 3x 3x 1x 1x 3x 3x 1x                                                                  
import { Color, CoreValueType } from "../../coreTable/CoreTableConstants"
 
interface BinProps {
    color: Color
    label?: string
}
 
interface NumericBinProps extends BinProps {
    isFirst: boolean
    isOpenLeft: boolean
    isOpenRight: boolean
    min: number
    max: number
    displayMin: string
    displayMax: string
}
 
interface CategoricalBinProps extends BinProps {
    index: number
    value: string
    label: string
    isHidden?: boolean
}
 
abstract class AbstractColorScaleBin<T extends BinProps> {
    props: T
    constructor(props: T) {
        this.props = props
    }
    get color(): string {
        return this.props.color
    }
    get label(): string | undefined {
        return this.props.label
    }
}
 
export class NumericBin extends AbstractColorScaleBin<NumericBinProps> {
    get min(): number {
        return this.props.min
    }
    get max(): number {
        return this.props.max
    }
    get minText(): string {
        if (this.props.isOpenLeft) return ""
        return this.props.displayMin
    }
    get maxText(): string {
        if (this.props.isOpenRight) return ""
        return this.props.displayMax
    }
    get text(): string {
        return this.props.label || ""
    }
    get isHidden(): boolean {
        return false
    }
 
    contains(value: CoreValueType | undefined): boolean {
        if (value === undefined) return false
 
        // In looking at this code, it is important to realise that `isOpenLeft`, `isOpenRight`,
        // and `isFirst` are _not_ mutually exclusive.
        // For example, if both `isOpenRight` and `isFirst` are set, then we effectively want `value >= min`.
 
        // If the bin is left-open, we just need to check the right side
        if (this.props.isOpenLeft && value <= this.max) return true
 
        // If the bin is right-open, we just need to check the left side
        if (this.props.isOpenRight && value > this.min) return true
 
        // If this is the first bin of the chart, we want to include the `min` value and thus use greater-equals
        if (this.props.isFirst) {
            return value >= this.min && value <= this.max
        } else {
            return value > this.min && value <= this.max
        }
    }
 
    equals(other: ColorScaleBin): boolean {
        return (
            other instanceof NumericBin &&
            this.min === other.min &&
            this.max === other.max
        )
    }
}
 
export class CategoricalBin extends AbstractColorScaleBin<CategoricalBinProps> {
    get index(): number {
        return this.props.index
    }
    get value(): string {
        return this.props.value
    }
    get isHidden(): boolean | undefined {
        return this.props.isHidden
    }
 
    get text(): string {
        return this.props.label || this.props.value
    }
 
    contains(value: CoreValueType | undefined): boolean {
        return (
            (value === undefined && this.props.value === "No data") ||
            (value !== undefined && value === this.props.value)
        )
    }
 
    equals(other: ColorScaleBin): boolean {
        return (
            other instanceof CategoricalBin &&
            this.props.index === other.props.index
        )
    }
}
 
export type ColorScaleBin = CategoricalBin | NumericBin