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();
}