diff --git a/src/app/charts/donut-chart/donut-chart.component.ts b/src/app/charts/donut-chart/donut-chart.component.ts index e75adf556..296075141 100644 --- a/src/app/charts/donut-chart/donut-chart.component.ts +++ b/src/app/charts/donut-chart/donut-chart.component.ts @@ -1,6 +1,6 @@ import { Component, Input } from '@angular/core'; import { Chart } from 'chart.js' -import { LabelOptions } from '@angular/material/core'; +import { tooltip } from '../tooltip' @Component({ selector: 'app-donut-chart', @@ -71,6 +71,11 @@ export class DonutChartComponent { responsive: false, legend: { display: false + }, + tooltips: { + // Disable the on-canvas tooltip + enabled: false, + custom: tooltip(), } } }); diff --git a/src/app/charts/tooltip.ts b/src/app/charts/tooltip.ts new file mode 100644 index 000000000..d46e33848 --- /dev/null +++ b/src/app/charts/tooltip.ts @@ -0,0 +1,62 @@ +// Adapted from https://www.chartjs.org/samples/latest/tooltips/custom-pie.html +export let tooltip: () => (tooltip: any) => void = + function (): (tooltip: any) => void { + return function (tooltip: any): void { + // Tooltip Element + const tooltipEl = document.getElementById('chartjs-tooltip'); + + // Hide if no tooltip + if (tooltip.opacity === 0) { + tooltipEl.style.opacity = '0'; + return; + } + + // Set caret Position + tooltipEl.classList.remove('above', 'below', 'no-transform'); + if (tooltip.yAlign) { + tooltipEl.classList.add(tooltip.yAlign); + } else { + tooltipEl.classList.add('no-transform'); + } + + function getBody(bodyItem) { + return bodyItem.lines; + } + + // Set Text + if (tooltip.body) { + let titleLines = tooltip.title || []; + const bodyLines = tooltip.body.map(getBody); + + let innerHtml = ''; + + titleLines.forEach(function (title) { + innerHtml += '' + title + ''; + }); + innerHtml += ''; + + bodyLines.forEach(function (body, i) { + let colors = tooltip.labelColors[i]; + let style = 'background:' + colors.backgroundColor; + style += '; border-color:' + colors.borderColor; + style += '; border-width: 2px'; + let span = ''; + innerHtml += '' + span + body + ''; + }); + innerHtml += ''; + + let tableRoot = tooltipEl.querySelector('table'); + tableRoot.innerHTML = innerHtml; + } + + var position = this._chart.canvas.getBoundingClientRect(); + + // Display, position, and set styles for font + tooltipEl.style.opacity = '1'; + tooltipEl.style.position = 'absolute'; + tooltipEl.style.left = position.left + window.pageXOffset + tooltip.caretX + 'px'; + tooltipEl.style.top = position.top + window.pageYOffset + tooltip.caretY + 'px'; + tooltipEl.style.padding = tooltip.yPadding + 'px ' + tooltip.xPadding + 'px'; + tooltipEl.style.pointerEvents = 'none'; + } + }; \ No newline at end of file diff --git a/src/index.html b/src/index.html index 86438a1d6..fc77e57e2 100644 --- a/src/index.html +++ b/src/index.html @@ -11,6 +11,9 @@ +
+
+
diff --git a/src/styles.scss b/src/styles.scss index 638ff235e..ac9d610ad 100644 --- a/src/styles.scss +++ b/src/styles.scss @@ -1,3 +1,27 @@ +// Chart.js styles +#chartjs-tooltip { + /* max z-index value */ + z-index: 2147483647; + opacity: 0; + position: absolute; + background: rgba(0, 0, 0, .7); + color: white; + border-radius: 3px; + -webkit-transition: opacity .3s ease; + transition: opacity .3s ease; + pointer-events: none; + -webkit-transform: translate(-50%, 0); + transform: translate(-50%, 0); +} + +.chartjs-tooltip-key { + display: inline-block; + width: 10px; + height: 10px; + margin-right: 10px; +} + + // Custom Theming for Angular Material // For more information: https://material.angular.io/guide/theming @import '~@angular/material/theming';