diff options
Diffstat (limited to 'src/pybind/mgr/dashboard/frontend/src/app/shared/models/chart-tooltip.ts')
-rw-r--r-- | src/pybind/mgr/dashboard/frontend/src/app/shared/models/chart-tooltip.ts | 115 |
1 files changed, 115 insertions, 0 deletions
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/models/chart-tooltip.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/models/chart-tooltip.ts new file mode 100644 index 000000000..93a259e79 --- /dev/null +++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/models/chart-tooltip.ts @@ -0,0 +1,115 @@ +import { ElementRef } from '@angular/core'; + +export class ChartTooltip { + tooltipEl: any; + chartEl: any; + getStyleLeft: Function; + getStyleTop: Function; + customColors: Record<string, any> = { + backgroundColor: undefined, + borderColor: undefined + }; + checkOffset = false; + + /** + * Creates an instance of ChartTooltip. + * @param {ElementRef} chartCanvas Canvas Element + * @param {ElementRef} chartTooltip Tooltip Element + * @param {Function} getStyleLeft Function that calculates the value of Left + * @param {Function} getStyleTop Function that calculates the value of Top + * @memberof ChartTooltip + */ + constructor( + chartCanvas: ElementRef, + chartTooltip: ElementRef, + getStyleLeft: Function, + getStyleTop: Function + ) { + this.chartEl = chartCanvas.nativeElement; + this.getStyleLeft = getStyleLeft; + this.getStyleTop = getStyleTop; + this.tooltipEl = chartTooltip.nativeElement; + } + + /** + * Implementation of a ChartJS custom tooltip function. + * + * @param {any} tooltip + * @memberof ChartTooltip + */ + customTooltips(tooltip: any) { + // Hide if no tooltip + if (tooltip.opacity === 0) { + this.tooltipEl.style.opacity = 0; + return; + } + + // Set caret Position + this.tooltipEl.classList.remove('above', 'below', 'no-transform'); + if (tooltip.yAlign) { + this.tooltipEl.classList.add(tooltip.yAlign); + } else { + this.tooltipEl.classList.add('no-transform'); + } + + // Set Text + if (tooltip.body) { + const titleLines = tooltip.title || []; + const bodyLines = tooltip.body.map((bodyItem: any) => { + return bodyItem.lines; + }); + + let innerHtml = '<thead>'; + + titleLines.forEach((title: string) => { + innerHtml += '<tr><th>' + this.getTitle(title) + '</th></tr>'; + }); + innerHtml += '</thead><tbody>'; + + bodyLines.forEach((body: string, i: number) => { + const colors = tooltip.labelColors[i]; + let style = 'background:' + (this.customColors.backgroundColor || colors.backgroundColor); + style += '; border-color:' + (this.customColors.borderColor || colors.borderColor); + style += '; border-width: 2px'; + const span = '<span class="chartjs-tooltip-key" style="' + style + '"></span>'; + innerHtml += '<tr><td nowrap>' + span + this.getBody(body) + '</td></tr>'; + }); + innerHtml += '</tbody>'; + + const tableRoot = this.tooltipEl.querySelector('table'); + tableRoot.innerHTML = innerHtml; + } + + const positionY = this.chartEl.offsetTop; + const positionX = this.chartEl.offsetLeft; + + // Display, position, and set styles for font + if (this.checkOffset) { + const halfWidth = tooltip.width / 2; + this.tooltipEl.classList.remove('transform-left'); + this.tooltipEl.classList.remove('transform-right'); + if (tooltip.caretX - halfWidth < 0) { + this.tooltipEl.classList.add('transform-left'); + } else if (tooltip.caretX + halfWidth > this.chartEl.width) { + this.tooltipEl.classList.add('transform-right'); + } + } + + this.tooltipEl.style.left = this.getStyleLeft(tooltip, positionX); + this.tooltipEl.style.top = this.getStyleTop(tooltip, positionY); + + this.tooltipEl.style.opacity = 1; + this.tooltipEl.style.fontFamily = tooltip._fontFamily; + this.tooltipEl.style.fontSize = tooltip.fontSize; + this.tooltipEl.style.fontStyle = tooltip._fontStyle; + this.tooltipEl.style.padding = tooltip.yPadding + 'px ' + tooltip.xPadding + 'px'; + } + + getBody(body: string) { + return body; + } + + getTitle(title: string) { + return title; + } +} |