{"version":3,"file":"deja-js-component-circular-picker.mjs","sources":["../../../../projects/deja-js/component/circular-picker/circular-picker.component.ts","../../../../projects/deja-js/component/circular-picker/circular-picker.component.html","../../../../projects/deja-js/component/circular-picker/index.ts","../../../../projects/deja-js/component/circular-picker/deja-js-component-circular-picker.ts"],"sourcesContent":["/*\n *  @license\n *  Copyright Hôpitaux Universitaires de Genève. All Rights Reserved.\n *\n *  Use of this source code is governed by an Apache-2.0 license that can be\n *  found in the LICENSE file at https://github.com/DSI-HUG/dejajs-components/blob/master/LICENSE\n */\n\nimport { BooleanInput, coerceBooleanProperty } from '@angular/cdk/coercion';\nimport { ChangeDetectionStrategy, ChangeDetectorRef, Component, ContentChild, ElementRef, Input, OnInit, Optional, Self, TemplateRef, ViewChild } from '@angular/core';\nimport { ControlValueAccessor, NgControl } from '@angular/forms';\nimport { Destroy } from '@deja-js/component/core';\nimport { Circle, Position } from '@deja-js/component/core/graphics';\nimport { debounceTime, filter, fromEvent, mergeWith, sampleTime, Subject, switchMap, take, takeUntil, tap } from 'rxjs';\n\nexport enum ClockwiseFactorEnum {\n    // eslint-disable-next-line @typescript-eslint/naming-convention\n    clockwise = -1,\n    // eslint-disable-next-line @typescript-eslint/naming-convention\n    counterClockwise = 1,\n}\n\nexport interface ICircularValue {\n    position: Position;\n    value: number;\n}\n\n/**\n * Circular-picker component for Angular\n */\n@Component({\n    changeDetection: ChangeDetectionStrategy.OnPush,\n    selector: 'deja-circular-picker',\n    styleUrls: ['./circular-picker.component.scss'],\n    templateUrl: './circular-picker.component.html'\n})\nexport class DejaCircularPickerComponent extends Destroy implements OnInit, ControlValueAccessor {\n    /** ClockwiseFactor allows user to choose rotation direction of picker */\n    @Input() public clockwiseFactor: ClockwiseFactorEnum = ClockwiseFactorEnum.clockwise;\n    /** Diameter of circular picker in pixels. Default 310px */\n    @Input() public fullDiameter = 310;\n    /** Diameter of labels on circular picker */\n    @Input() public labelsDiameter = 43;\n\n    /** Ranges of circular picker */\n    @Input() public ranges: ICircularRange[];\n\n    /** Template for labels inside picker. Use it to customize labels */\n    @ContentChild('labelTemplate') public labelTemplate: TemplateRef<unknown>;\n    /** template for cursor inside picker. Use it to customize labels */\n    @ContentChild('cursorTemplate') public cursorTemplate: TemplateRef<unknown>;\n\n    @ViewChild('picker', { static: true }) private picker: ElementRef;\n\n    private _outerLabels = false;\n\n    /**\n     * Allows user to choose labels position. If outerLabels is true, labels will come outside the circular picker\n     *\n     * With outerLabels = true, and ranges.length > 1, labels will go outwards.\n     * With outerLabels = false, and ranges.length > 1, labels will go inwards.\n     */\n    @Input()\n    public set outerLabels(value: BooleanInput) {\n        this._outerLabels = coerceBooleanProperty(value) || null;\n    }\n\n    public get outerLabels(): BooleanInput {\n        return this._outerLabels;\n    }\n\n    /** disabled property setter. Can be string or empty so you can use it like : <circular-picker disabled></circular-picker> */\n    @Input()\n    public set disabled(value: BooleanInput) {\n        this._disabled = coerceBooleanProperty(value);\n        this.changeDetectorRef.markForCheck();\n    }\n\n    /** To get disabled attribute. */\n    public get disabled(): BooleanInput {\n        return this._disabled;\n    }\n\n    private _disabled = false;\n\n    private _value: number;\n    private twoPi = Math.PI * 2;\n\n    private _radius = 0;\n    private configs: IConfig[] = [];\n    private selectedConfig: IConfig;\n\n    private _circularValues: ICircularValue[] = [];\n\n    private _cursor: ICircularValue;\n    private _cursorHand: {\n        width: number;\n        angle: number;\n    };\n\n    private cursorElement: HTMLElement;\n\n    private clickedTime: number;\n\n    public get cursorHand(): { width: number; angle: number } {\n        return this._cursorHand;\n    }\n\n    public get cursor(): ICircularValue {\n        return this._cursor;\n    }\n\n    public get radius(): number {\n        return this._radius;\n    }\n\n    public get circularValues(): ICircularValue[] {\n        return this._circularValues;\n    }\n\n    /**\n     * Constructor.\n     * Create MouseDown & mouseMove Observables needed inside this control.\n     */\n    public constructor(elementRef: ElementRef, private changeDetectorRef: ChangeDetectorRef, @Self() @Optional() public control: NgControl) {\n        super();\n\n        const element = elementRef.nativeElement as HTMLElement;\n\n        if (this.control) {\n            this.control.valueAccessor = this;\n        }\n\n        const mouseUpEvent$ = fromEvent<MouseEvent>(element.ownerDocument, 'mouseup');\n        const mouseDownEvent$ = fromEvent<MouseEvent>(element, 'mousedown');\n        mouseDownEvent$.pipe(\n            filter(event => !this.disabled && event.buttons === 1),\n            debounceTime(100),\n            filter(mouseEvent => {\n                this.clickedTime = Date.now();\n                const cursorElement = this.getHtmlElement(mouseEvent.target as HTMLElement, 'cursor');\n                const valueElement = this.getHtmlElement(mouseEvent.target as HTMLElement, 'value');\n                if (cursorElement) {\n                    this.cursorElement = cursorElement;\n                } else if (valueElement) {\n                    this.value = +valueElement.getAttribute('value');\n                }\n\n                return !!cursorElement || !!valueElement;\n            }),\n            switchMap(() => {\n                const moveUp$ = new Subject<void>();\n\n                // eslint-disable-next-line @typescript-eslint/prefer-regexp-exec\n                if (!element.ownerDocument.body.className.match(/noselect/)) {\n                    element.ownerDocument.body.classList.add('noselect');\n                }\n\n                const cancelMouse$ = moveUp$.pipe(\n                    mergeWith(mouseUpEvent$),\n                    take(1),\n                    tap(() => {\n                        delete this.cursorElement;\n                        delete this.clickedTime;\n                        element.ownerDocument.body.className = element.ownerDocument.body.className.replace(/\\bnoselect\\b/, '');\n                    }));\n\n                const pickerElem = this.picker.nativeElement as HTMLElement;\n                const clientRect = pickerElem.getBoundingClientRect();\n\n                const mouseMoveEvent$ = fromEvent<MouseEvent>(element.ownerDocument, 'mousemove');\n                return mouseMoveEvent$.pipe(\n                    // eslint-disable-next-line rxjs/no-unsafe-takeuntil\n                    takeUntil(cancelMouse$),\n                    sampleTime(10),\n                    tap(moveEvent => {\n                        if (moveEvent.buttons !== 1) {\n                            moveUp$.next();\n                            return;\n                        }\n\n                        let circle = Circle.fromOuterRect(clientRect);\n                        let contains = false;\n                        if (this.outerLabels) {\n                            circle = circle.inflate(this.labelsDiameter);\n\n                            // eslint-disable-next-line no-loops/no-loops\n                            for (const conf of this.configs) {\n                                contains = circle.containsPoint(new Position(moveEvent.pageX, moveEvent.pageY));\n                                if (contains) {\n                                    this.selectedConfig = conf;\n                                    break;\n                                } else {\n                                    circle = circle.inflate(this.labelsDiameter);\n                                }\n                            }\n                        } else {\n                            const x = this.labelsDiameter * (this.configs.length - 1);\n                            circle = circle.inflate(-x);\n                            // eslint-disable-next-line no-loops/no-loops\n                            for (let i = this.configs.length; i > 0; i--) {\n                                contains = circle.containsPoint(new Position(moveEvent.pageX, moveEvent.pageY));\n                                if (contains) {\n                                    this.selectedConfig = this.configs[i - 1];\n                                    break;\n                                } else {\n                                    circle = circle.inflate(this.labelsDiameter);\n                                }\n                            }\n                        }\n\n                        const newValue = this.pointToValue(moveEvent.pageX - clientRect.left, moveEvent.pageY - clientRect.top, this.selectedConfig);\n                        if (newValue !== this.value) {\n                            this.value = newValue;\n                        }\n                    })\n                );\n            }),\n            takeUntil(this.destroyed$)\n        ).subscribe();\n    }\n\n    /**\n     * Init circular-picker configuration\n     */\n    public ngOnInit(): void {\n        /* max - width */\n        const diameter = this.fullDiameter - this.labelsDiameter; // Material standard button size\n        this._radius = diameter / 2;\n\n        this.ranges.forEach(range => {\n            range.interval = (range.interval) ? range.interval : 1;\n            range.labelInterval = (range.labelInterval) ? range.labelInterval : 1;\n            range.beginOffset = (range.beginOffset) ? range.beginOffset : Math.PI / 2;\n            this.configs.push({\n                range: range,\n                stepAngle: this.twoPi / Math.floor((range.max - range.min + 1) / range.interval),\n                steps: Math.floor((range.max - range.min + 1) / range.interval)\n            });\n        });\n\n        this.selectedConfig = this.configs[0];\n\n        this.bind();\n        this.updateCursor();\n    }\n\n    // ************* ControlValueAccessor Implementation **************\n    /** set accessor including call the onchange callback */\n    public set value(v: number) {\n        if (v !== this._value) {\n            this.writeValue(v);\n            this.onChangeCallback(v);\n        }\n    }\n\n    /** get accessor */\n    public get value(): number {\n        return this._value;\n    }\n\n    /** From ControlValueAccessor interface */\n    public writeValue(value: number): void {\n        if (value !== this._value) {\n            this._value = value;\n            this.updateCursor();\n        }\n    }\n\n    /** From ControlValueAccessor interface */\n    public registerOnChange(fn: (_a: unknown) => void): void {\n        this.onChangeCallback = fn;\n    }\n\n    /** From ControlValueAccessor interface */\n    public registerOnTouched(fn: () => void): void {\n        this.onTouchedCallback = fn;\n    }\n\n    public setDisabledState(isDisabled: boolean): void {\n        this.disabled = isDisabled;\n    }\n    // ************* End of ControlValueAccessor Implementation **************\n\n    protected onChangeCallback = (_a: unknown): void => undefined;\n    protected onTouchedCallback = (): void => undefined;\n\n    /**\n     * Take a point in parameter and return corresponding value\n     *\n     * @param x xPos of point\n     * @param y yPos of point\n     * @param config config where the point is located\n     *\n     * @return value\n     */\n    protected pointToValue(x: number, y: number, config: IConfig): number {\n        const angleAtPoint: number = this.pointToAngle(x - this._radius, y - this._radius, config);\n        let circleSegmentIndexAtPoint: number = config.steps - Math.ceil(angleAtPoint / config.stepAngle);\n        // By having pointToAngle() to compute using a half step below the actual angle,\n        // we can use Math.ceil() to get the upper circleSegmentIndex. We're working in\n        // counter-clockwise direction, thus we finally get a -1 index when we're just\n        // below the first circle segment. We can now simply wrap it to the 0 index,\n        // resulting in the user-expected behavior.\n        if (circleSegmentIndexAtPoint < 0) {\n            circleSegmentIndexAtPoint = config.steps;\n        }\n        return config.range.min + circleSegmentIndexAtPoint * config.range.interval;\n    }\n\n    /**\n     * Take velue and returns its position\n     * @param value value to check\n     * @param radiusOffset Radius to ckeck (if outerLabels are on, the radius offset = fullDiameter + labelsDiameter)\n     * @param config the config where to check\n     *\n     * @return the position of value\n     */\n    protected valueToPoint(value: number, radiusOffset: number, config: IConfig): Position {\n        const position = new Position();\n        const valueAngle: number = this.valueToAngle(value, config);\n\n        position.left = this._radius + (this._radius + radiusOffset) * Math.cos(valueAngle);\n        position.top = this._radius - (this._radius + radiusOffset) * Math.sin(valueAngle); // y axis is reversed in display\n\n        return position;\n    }\n\n    private pointToAngle(x: number, y: number, config: IConfig): number {\n        return (\n            -Math.atan2(y, x) // Math.atan2() returns between -Ï€ and +Ï€, but in inverted trigonometrical order...\n            - config.range.beginOffset\t// Correct the configured offset to compute in 'natural' trigonometrical circle\n            - (config.stepAngle / 2)\t// Remove half a step angle to match value from both sides\n            + this.twoPi // We want the returned value to be between 0 and 2Ï€ => (x + 2Ï€) % 2Ï€\n        ) % this.twoPi;\n    }\n\n    private valueToAngle(value: number, config: IConfig): number {\n        const circleSegmentIndex: number = Math.floor((value - config.range.min) / config.range.interval);\n        return (circleSegmentIndex * config.stepAngle * this.clockwiseFactor) + config.range.beginOffset;\n    }\n\n    private bind(): void {\n        this._circularValues = [];\n        this.configs.forEach((config: IConfig, configNumber: number) => {\n            // eslint-disable-next-line no-loops/no-loops\n            for (let i = config.range.min; i <= config.range.max; i += (config.range.labelInterval * config.range.interval)) {\n                const val = { value: i } as ICircularValue;\n                const labelRadius = this.labelsDiameter / 2;\n                const configOffset = this.labelsDiameter * configNumber;\n                const labelPosition = this.valueToPoint(i, (this.outerLabels ? labelRadius + configOffset : -labelRadius - configOffset), config);\n\n                val.position = new Position((labelPosition.left - labelRadius), (labelPosition.top - labelRadius));\n                this._circularValues.push(val);\n            }\n        });\n    }\n\n    private updateCursor(): void {\n        if (!this._circularValues || !this._circularValues.length) {\n            return;\n        }\n        if (this._value === undefined || this._value === null) {\n            this._value = this._circularValues[0].value;\n        }\n        this.selectedConfig = this.configs.find((conf: IConfig) => this._value >= conf.range.min && this._value <= conf.range.max);\n        if (!this.selectedConfig) {\n            this.selectedConfig = this.configs[0];\n        }\n        const selectedConfigIndex = this.configs.indexOf(this.selectedConfig);\n        const cursorRadius: number = this.labelsDiameter / 2;\n\n        const cursorCenter = this.valueToPoint(this._value, (this.outerLabels ? cursorRadius + (this.labelsDiameter * selectedConfigIndex) : -cursorRadius - (this.labelsDiameter * selectedConfigIndex)), this.selectedConfig);\n        this._cursor = {\n            position: new Position((cursorCenter.left - cursorRadius), (cursorCenter.top - cursorRadius)),\n            value: this._value\n        };\n\n        this._cursorHand = {\n            angle: this.valueToAngle(this._value, this.selectedConfig),\n            width: (this.outerLabels) ? this._radius + (this.labelsDiameter * selectedConfigIndex) : this._radius - this.labelsDiameter - (this.labelsDiameter * selectedConfigIndex)\n        };\n\n        this.changeDetectorRef.markForCheck();\n    }\n\n    private getHtmlElement(element: HTMLElement, attr: string): HTMLElement {\n        let parentElement = element;\n\n        // eslint-disable-next-line no-loops/no-loops\n        while (parentElement && !parentElement.hasAttribute(attr)) {\n            parentElement = parentElement.parentElement;\n        }\n\n        if (!parentElement) {\n            return undefined;\n        }\n\n        return parentElement;\n    }\n}\n\nexport interface IConfig {\n    range: ICircularRange;\n    steps: number;\n    stepAngle: number;\n}\n\nexport interface ICircularRange {\n    min: number;\n    max: number;\n    interval?: number;\n    labelInterval?: number; // x*interval\n    beginOffset?: number;\n}\n","\t<div class=\"circular-picker\" #picker [style.width.px]=\"radius*2\" [style.height.px]=\"radius*2\" [class.disabled]=\"disabled\">\n\t    <!--FOR TEST ONLY-->\n\t    <!-- div *ngIf=\"circle\" class=\"test\"\n\t\t\t\t[style.position]=\"'fixed'\"\n\t\t\t\t[style.background]=\"'red'\"\n\t\t\t\t[style.opacity]=\"0.6\"\n\t\t\t\t[style.top.px]=\"circle.center.top - circle.radius\"\n\t\t\t\t[style.left.px]=\"circle.center.left - circle.radius\"\n\t\t\t\t[style.width.px]=\"circle.radius * 2\"\n\t\t\t\t[style.height.px]=\"circle.radius * 2\"\n        ></div-->\n\t    <div class=\"cursor-container\">\n\t        <div class=\"cursor\" cursor *ngIf=\"cursor.value !== undefined\" [style.top.px]=\"cursor.position.top\" [style.left.px]=\"cursor.position.left\">\n\t            <ng-template *ngIf=\"cursorTemplate else valueTemplate\" [ngTemplateOutlet]=\"cursorTemplate\" [ngTemplateOutletContext]=\"{ $implicit: cursor.value }\"></ng-template>\n\t            <ng-template #valueTemplate>\n\t                <span>{{cursor.value}}</span>\n\t            </ng-template>\n\t        </div>\n\t        <div class=\"cursorHand\" [ngStyle]=\"{'transform':'translateY(-50%) rotate('+(-cursorHand.angle)+'rad)'}\" [style.width.px]=\"cursorHand.width+2\"></div>\n\t    </div>\n\t    <div class=\"value\" [attr.value]=\"val.value\" *ngFor=\"let val of circularValues; let index=index\" [style.top.px]=\"val.position.top\" [style.left.px]=\"val.position.left\">\n\t        <ng-template *ngIf=\"labelTemplate\" [ngTemplateOutlet]=\"labelTemplate\" [ngTemplateOutletContext]=\"{ $implicit: val.value, index: index }\"></ng-template>\n\t        <span *ngIf=\"!labelTemplate\">{{val.value}}</span>\n\t    </div>\n\t</div>","/*\n *  @license\n *  Copyright Hôpitaux Universitaires de Genève. All Rights Reserved.\n *\n *  Use of this source code is governed by an Apache-2.0 license that can be\n *  found in the LICENSE file at https://github.com/DSI-HUG/dejajs-components/blob/master/LICENSE\n */\n\nimport { CommonModule } from '@angular/common';\nimport { NgModule } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\n\nimport { DejaCircularPickerComponent } from './circular-picker.component';\n\n@NgModule({\n    declarations: [DejaCircularPickerComponent],\n    exports: [DejaCircularPickerComponent],\n    imports: [\n        CommonModule,\n        FormsModule\n    ]\n})\nexport class DejaCircularPickerModule { }\n\nexport * from './circular-picker.component';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}