private renderMarker()

in src/UXClient/Components/Marker/Marker.ts [152:264]


    private renderMarker () {
        let self = this;
        let marker = d3.select(this.renderTarget).selectAll(`.tsi-markerContainer`)
            .filter((d: any) => d.guid === this.guid)
            .data([{guid: this.guid, timestamp: this.timestampMillis}]);
        this.markerContainer = marker.enter()
            .append('div')
            .attr('class', 'tsi-markerContainer')
            .classed('tsi-isSeriesLabels', this.isSeriesLabels)
            .merge(marker as d3.Selection<HTMLDivElement,{guid: string, timestamp: number},any,unknown>)
            .style('top', `${this.chartMargins.top + this.chartOptions.aggTopMargin}px`)
            .style('height', `${this.chartHeight - (this.chartMargins.top + this.chartMargins.bottom + this.chartOptions.aggTopMargin)}px`)
            .style('left', (d: any) => {
                return `${this.getLeft(d)}px`;
            })
            .classed('tsi-isFlipped', (d) => {
                if (this.isSeriesLabels) {
                    return false;
                }
                return (this.chartOptions.labelSeriesWithMarker && this.x(d.timestamp) > (this.x.range()[1] - MARKERVALUEMAXWIDTH));
            }) 
            .each(function(markerD) {
                if (self.isSeriesLabels) {
                    return;
                }
                if (d3.select(this).selectAll('.tsi-markerLine').empty()) {
                    d3.select(this).append('div')
                        .attr('class', 'tsi-markerLine');
                    self.markerLabel = d3.select(this).append('div')
                        .attr('class', 'tsi-markerLabel')
                        .on('mouseleave', function () {
                            d3.select(this).classed('tsi-markerLabelHovered', false);
                        });

                    self.markerLabel.append('div')
                        .attr('class', 'tsi-markerGrabber')
                        .on('mouseenter', () => {
                            self.bumpMarker();    
                        });

                    self.markerLabel.append('div')
                        .attr('class', 'tsi-markerLabelText')
                        .attr('contenteditable', 'true')
                        .text(self.labelText)
                        .on('keydown', () =>{
                            if (d3.event.keyCode === KeyCodes.Enter && !d3.event.shiftKey) {
                                d3.event.preventDefault();
                                self.closeButton.node().focus();
                            }
                        })
                        .on('input', function () {
                            let didTrim = self.setLabelText(d3.select(this).text());
                            if (didTrim) {
                                d3.select(this).text(self.labelText);
                            }
                        })
                        .on('focus', function () {
                            d3.select(this.parentNode).classed('tsi-markerLabelTextFocused', true);
                        })
                        .on('blur', function () {
                            d3.select(this.parentNode).classed('tsi-markerLabelTextFocused', false);
                            self.onChange(false, false, false);
                        })
                        .on('mousedown', () => {
                            d3.event.stopPropagation();
                        })
                        .on('mouseover', function () {
                            if (!self.isMarkerDragOccuring()) {
                                d3.select(d3.select(this).node().parentNode).classed('tsi-markerLabelHovered', true);
                                self.bumpMarker();    
                            }
                        });
                    
                    self.closeButton = self.markerLabel.append("button")
                        .attr("aria-label", self.getString('Delete marker')) 
                        .classed("tsi-closeButton", true)
                        .on("click", function () {
                            self.onChange(true, false);
                            d3.select((d3.select(this).node() as any).parentNode.parentNode).remove();
                        });
            
                    self.timeLabel = d3.select(this).append("div")
                        .attr('class', 'tsi-markerTimeLabel');
                }
                d3.select(this).selectAll('.tsi-markerTimeLabel,.tsi-markerLine,.tsi-markerLabel')
                    .call(d3.drag()
                        .on('start', function(d: any) {
                            d.isDragging = true;
                            self.markerIsDragging = true;
                            self.bumpMarker();
                        })
                        .on('drag', function (d) {
                            if (d3.select(d3.event.sourceEvent.target).classed('tsi-closeButton')) {
                                return;
                            }
                            let marker = d3.select(<any>d3.select(this).node().parentNode);
                            let startPosition = self.x(new Date(self.timestampMillis));
                            let newPosition = startPosition + d3.event.x;

                            self.timestampMillis = Utils.findClosestTime(self.x.invert(newPosition).valueOf(), self.chartComponentData.timeMap);
                            self.setPositionsAndLabels(self.timestampMillis);
                        })
                        .on('end', function (d: any) {
                            if (!d3.select(d3.event.sourceEvent.target).classed('tsi-closeButton')) {
                                self.onChange(false, false);
                            }
                            d.isDragging = false;
                            self.markerIsDragging = false;
                        })
                    );
            });
        marker.exit().remove();
    }