private brushEnd()

in src/UXClient/Components/LineChart/LineChart.ts [881:984]


    private brushEnd (mouseEvent) {
        if (this.isClearingBrush) {
            this.isClearingBrush = false;
            if (this.brushContextMenu) {
                this.brushContextMenu.hide();
            }
            return;
        }
        if (d3.event && d3.event.selection == null && d3.event.sourceEvent && d3.event.sourceEvent.type == "mouseup" && this.chartOptions.minBrushWidth == 0) {
            if (this.brushContextMenu) {
                this.brushContextMenu.hide();
            }
            const [mx, my] = d3.mouse(mouseEvent);
            var site: any = this.voronoiDiagram.find(mx, my);
            let isClearingBrush = (this.brushStartPosition !== null) && (this.brushEndPosition !== null);
            if (this.chartComponentData.stickiedKey !== null && !this.isDroppingMarker && !isClearingBrush) {
                this.chartComponentData.stickiedKey = null;
                (<any>this.legendObject.legendElement.selectAll('.tsi-splitByLabel')).classed("stickied", false);
                // recompute voronoi with no sticky
                this.voronoiDiagram = this.voronoi(this.getFilteredAndSticky(this.chartComponentData.allValues));
                site = this.voronoiDiagram.find(mx, my);
                this.voronoiMousemove(site.data);
                this.chartOptions.onUnsticky(site.data.aggregateKey, site.data.splitBy);
                return;
            }

            this.brushStartTime = null;
            this.brushEndTime = null;
            this.brushStartPosition = null;
            this.brushEndPosition = null;

            if (!this.isDroppingMarker && !isClearingBrush && !(this.contextMenu && this.contextMenu.contextMenuVisible)) {
                this.stickySeries(site.data.aggregateKey, site.data.splitBy);
            } else {
                this.isDroppingMarker = false;
            }
            return;
        }

        if (d3.event.selection == null) {
            if (!this.chartOptions.brushClearable) {
                d3.select(mouseEvent).transition().call(d3.event.target.move, [this.x(this.brushStartTime), this.x(this.brushEndTime)]);
            }
            return;
        }
        var transformCall = null; //if the brush needs to be transformed due to snap brush or it being too small, this is envoked
        var isZeroWidth = false; //clear the brush context menu if the brush has 0 width
        if (this.chartOptions.snapBrush) {
            //find the closest possible value and set to that
            if (this.possibleTimesArray.length > 0) {
                var findClosestTime = (rawXValue): Date => {
                    var closestDate = null;
                    this.possibleTimesArray.reduce((prev, curr) => {
                        var prospectiveDiff = Math.abs(rawXValue - this.x(curr));
                        var currBestDiff = Math.abs(rawXValue - prev);
                        if (prospectiveDiff < currBestDiff) {
                            closestDate = curr;
                            return this.x(curr)
                        }
                        return prev;
                    }, Infinity);
                    return closestDate;
                }
                var newBrushStartTime = findClosestTime(d3.event.selection[0]);
                var newBrushEndTime = findClosestTime(d3.event.selection[1]);
                if (newBrushStartTime != this.brushStartTime || newBrushEndTime != this.brushEndTime) {
                    this.brushStartTime = newBrushStartTime;
                    this.brushEndTime = newBrushEndTime;
                    this.brushStartPosition = this.x(this.brushStartTime);
                    this.brushEndPosition = this.x(this.brushEndTime);
                    transformCall = () => d3.select(mouseEvent).transition().call(d3.event.target.move, [this.x(this.brushStartTime), this.x(this.brushEndTime)]);
                    isZeroWidth = this.x(this.brushStartTime) == this.x(this.brushEndTime);
                }
            }
        }
        if (d3.event.selection[1] - d3.event.selection[0] < this.minBrushWidth) {
            let rightSide = Math.min(d3.event.selection[0] + this.minBrushWidth, this.x.range()[1]);
            transformCall = () => d3.select(mouseEvent).transition().call(d3.event.target.move, [rightSide - this.minBrushWidth, rightSide]);
            isZeroWidth = (rightSide - this.minBrushWidth == rightSide);
        }
        if (this.chartOptions.brushMoveEndAction && (d3.event.sourceEvent && d3.event.sourceEvent.type == 'mouseup')) {
            this.chartOptions.brushMoveEndAction(this.brushStartTime, this.brushEndTime);
        }
        if (this.chartOptions.brushContextMenuActions && this.chartOptions.autoTriggerBrushContextMenu && 
            (d3.event.sourceEvent && d3.event.sourceEvent.type == 'mouseup')) {
            if (!this.chartOptions.brushContextMenuActions || this.chartOptions.brushContextMenuActions.length == 0)
                return;
            var mousePosition = d3.mouse(<any>this.targetElement.node());
            //constrain the mouse position to the renderTarget
            var boundingCRect = this.targetElement.node().getBoundingClientRect();
            var correctedMousePositionX = Math.min(boundingCRect.width, Math.max(mousePosition[0], 0));
            var correctedMousePositionY = Math.min(boundingCRect.height, Math.max(mousePosition[1], 0));
            var correctedMousePosition = [correctedMousePositionX, correctedMousePositionY];
            
            this.brushContextMenu.draw(this.chartComponentData, this.renderTarget, this.chartOptions, 
                                correctedMousePosition, null, null, null, this.brushStartTime, this.brushEndTime);
        }
        if (transformCall) {
            transformCall();
            if (this.brushContextMenu && isZeroWidth) {
                this.brushContextMenu.hide();
            } 
        }
    }