All files / app/codeCharta/ui/ribbonBar/colorSettingsPanel/metricColorRangeSlider metricColorRangeSlider.component.ts

84.61% Statements 44/52
100% Branches 7/7
77.77% Functions 7/9
84.31% Lines 43/51

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 128 129 130 131 132 133 134 135 136 137 138 1394x 4x 4x 4x 4x 4x                       4x                 16x             16x 16x       16x     16x 16x             16x 16x   16x 16x           4x 4x   2x 2x 2x 2x 2x     2x 2x 2x 2x 2x       16x 4x 4x 4x 4x   4x     16x                                     16x                                       2x 2x 2x         2x 2x 2x        
import { Component, ElementRef, Input, OnChanges, SimpleChanges, ViewChild } from "@angular/core"
import { calculateSliderRangePosition, SliderRangePosition, updateLeftThumb, updateRightThumb } from "./utils/SliderRangePosition"
import { parseNumberInput } from "../../../../util/parseNumberInput"
import { MatFormField } from "@angular/material/form-field"
import { MatInput } from "@angular/material/input"
import { RangeSliderLabelsComponent } from "./rangeSliderLabels/rangeSliderLabels.component"
 
export type HandleValueChange = (changedValue: { newLeftValue?: number; newRightValue?: number }) => void
export type CurrentlySliding = undefined | "leftThumb" | "rightThumb"
 
@Component({
    selector: "cc-metric-color-range-slider",
    templateUrl: "./metricColorRangeSlider.component.html",
    styleUrls: ["./metricColorRangeSlider.component.scss"],
    standalone: true,
    imports: [MatFormField, MatInput, RangeSliderLabelsComponent]
})
export class MetricColorRangeSliderComponent implements OnChanges {
    @Input() minValue: number
    @Input() maxValue: number
    @Input() currentLeftValue: number
    @Input() currentRightValue: number
    @Input() leftColor: string
    @Input() middleColor: string
    @Input() rightColor: string
    @Input() handleValueChange: HandleValueChange
    @Input() sliderWidth = 150
    @Input() isAttributeDirectionInversed: boolean
 
    @ViewChild("rangeSliderContainer") sliderContainer: ElementRef<HTMLDivElement>
    @ViewChild("leftThumb") leftThumb: ElementRef<HTMLDivElement>
    @ViewChild("rightThumb") rightThumb: ElementRef<HTMLDivElement>
 
    sliderRangePosition: SliderRangePosition = { leftEnd: 0, rightStart: 0 }
    thumbRadius = 7
    upcomingLeftValue: number
    upcomingRightValue: number
 
    private currentlySliding: CurrentlySliding = undefined
 
    ngOnChanges(changes: SimpleChanges) {
        if (!this.currentlySliding) {
            this.sliderRangePosition = calculateSliderRangePosition({
                minValue: this.minValue,
                maxValue: this.maxValue,
                currentLeftValue: this.currentLeftValue,
                currentRightValue: this.currentRightValue,
                sliderWidth: this.sliderWidth
            })
            if (changes.currentLeftValue) {
                this.upcomingLeftValue = this.currentLeftValue
            }
            if (changes.currentRightValue) {
                this.upcomingRightValue = this.currentRightValue
            }
        }
    }
 
    setCurrentlySliding(currentlySliding: CurrentlySliding) {
        this.currentlySliding = currentlySliding
        switch (this.currentlySliding) {
            case "leftThumb":
                document.addEventListener("mousemove", this.handleLeftThumbMoved)
                this.rightThumb.nativeElement.style.zIndex = "0"
                this.leftThumb.nativeElement.style.zIndex = "1"
                this.resetCurrentlySlidingOnNextMouseUp(this.handleLeftThumbMoved)
                break
 
            case "rightThumb":
                document.addEventListener("mousemove", this.handleRightThumbMoved)
                this.leftThumb.nativeElement.style.zIndex = "0"
                this.rightThumb.nativeElement.style.zIndex = "1"
                this.resetCurrentlySlidingOnNextMouseUp(this.handleRightThumbMoved)
                break
        }
    }
 
    resetCurrentlySlidingOnNextMouseUp = (handler: (event: MouseEvent) => void) => {
        const mouseUpHandler = () => {
            this.currentlySliding = undefined
            document.removeEventListener("mouseup", mouseUpHandler)
            document.removeEventListener("mousemove", handler)
        }
        document.addEventListener("mouseup", mouseUpHandler)
    }
 
    handleLeftThumbMoved = (event: MouseEvent) => {
        const updates = updateLeftThumb({
            deltaX: event.movementX,
            thumbScreenX: this.leftThumb.nativeElement.getBoundingClientRect().x,
            thumbRadius: this.thumbRadius,
            otherThumbScreenX: this.rightThumb.nativeElement.getBoundingClientRect().x,
            sliderBoundingClientRectX: this.sliderContainer.nativeElement.getBoundingClientRect().x,
            sliderWidth: this.sliderWidth,
            minValue: this.minValue,
            maxValue: this.maxValue
        })
        this.sliderRangePosition = {
            leftEnd: updates.updatedThumbX,
            rightStart: this.sliderRangePosition.rightStart
        }
        this.upcomingLeftValue = updates.upcomingValue
        this.handleValueChange({ newLeftValue: updates.upcomingValue })
    }
 
    handleRightThumbMoved = (event: MouseEvent) => {
        const updates = updateRightThumb({
            deltaX: event.movementX,
            thumbScreenX: this.rightThumb.nativeElement.getBoundingClientRect().x,
            thumbRadius: this.thumbRadius,
            otherThumbScreenX: this.leftThumb.nativeElement.getBoundingClientRect().x,
            sliderBoundingClientRectX: this.sliderContainer.nativeElement.getBoundingClientRect().x,
            sliderWidth: this.sliderWidth,
            minValue: this.minValue,
            maxValue: this.maxValue
        })
        this.sliderRangePosition = {
            leftEnd: this.sliderRangePosition.leftEnd,
            rightStart: updates.updatedThumbX
        }
        this.upcomingRightValue = updates.upcomingValue
        this.handleValueChange({ newRightValue: updates.upcomingValue })
    }
 
    handleCurrentLeftInputChanged($event: Event) {
        const newLeftValue = parseNumberInput($event, this.minValue, this.currentRightValue)
        if (newLeftValue !== this.currentLeftValue) {
            this.handleValueChange({ newLeftValue })
        }
    }
 
    handleCurrentRightInputChanged($event: Event) {
        const newRightValue = parseNumberInput($event, this.currentLeftValue, this.maxValue)
        if (newRightValue !== this.currentRightValue) {
            this.handleValueChange({ newRightValue })
        }
    }
}