diff --git a/dashboard/src/components/GraphItem.vue b/dashboard/src/components/GraphItem.vue index bda163683..fefd274a0 100644 --- a/dashboard/src/components/GraphItem.vue +++ b/dashboard/src/components/GraphItem.vue @@ -30,6 +30,51 @@ const props = defineProps({ highMarkLabel: String, }); +function renderTooltip(context) { + // console.log(context); { chart, tooltip } tooltip has { title, body } + if (!tooltipElem.value) return; + + const { /*chart, */ tooltip } = context; + + if (tooltip.opacity === 0) { + tooltipElem.value.style.opacity = 0; + return; + } + + const { title, body, labelColors } = tooltip; // these were computed in the "callback" in tooltip configuration + if (body) { + const titleLines = title || []; + const bodyLines = body.map(item => item.lines); + + let innerHtml = `
${titleLines[0]}
`; + + bodyLines.forEach(function(body, i) { + const colors = labelColors[i]; + innerHtml += `
${body}
`; + }); + + tooltipElem.value.innerHTML = innerHtml; + } + + tooltipElem.value.style.opacity = 1; + tooltipElem.value.style.position = 'absolute'; + + tooltipElem.value.classList.remove('graphs-tooltip-caret-left', 'graphs-tooltip-caret-right'); + + if (tooltip.chart.width/2 < tooltip.caretX) { + tooltipElem.value.style.right = (tooltip.chart.width - tooltip.caretX) + 'px'; + tooltipElem.value.style.left = 'unset'; + tooltipElem.value.classList.add('graphs-tooltip-caret-right'); + } else { + tooltipElem.value.style.right = 'unset'; + tooltipElem.value.style.left = tooltip.caretX + 'px'; + tooltipElem.value.classList.add('graphs-tooltip-caret-left'); + } + + tooltipElem.value.style.top = '0px'; + tooltipElem.value.style.height = '100%'; +} + function createGraphOptions({ yscale, period, highMark }) { let startTime, endTime, stepSize, count; // x axis configuration values @@ -54,56 +99,14 @@ function createGraphOptions({ yscale, period, highMark }) { }, tooltip: { enabled: false, - external: function(context) { - if (!tooltipElem.value) return; - - const tooltipModel = context.tooltip; - if (tooltipModel.opacity === 0) { - tooltipElem.value.style.opacity = 0; - return; - } - - // Set Text - if (tooltipModel.body) { - const titleLines = tooltipModel.title || []; - const bodyLines = tooltipModel.body.map(item => item.lines); - - let innerHtml = `
${titleLines[0]}
`; - - bodyLines.forEach(function(body, i) { - const colors = tooltipModel.labelColors[i]; - innerHtml += `
${body}
`; - }); - - tooltipElem.value.innerHTML = innerHtml; - } - - - tooltipElem.value.style.opacity = 1; - tooltipElem.value.style.position = 'absolute'; - - tooltipElem.value.classList.remove('graphs-tooltip-caret-left', 'graphs-tooltip-caret-right'); - - if (tooltipModel.chart.width/2 < tooltipModel.caretX) { - tooltipElem.value.style.right = (tooltipModel.chart.width - tooltipModel.caretX) + 'px'; - tooltipElem.value.style.left = 'unset'; - tooltipElem.value.classList.add('graphs-tooltip-caret-right'); - } else { - tooltipElem.value.style.right = 'unset'; - tooltipElem.value.style.left = tooltipModel.caretX + 'px'; - tooltipElem.value.classList.add('graphs-tooltip-caret-left'); - } - - tooltipElem.value.style.top = 0 + 'px'; - tooltipElem.value.style.height = '100%'; - }, - callbacks: { + callbacks: { // passed as title,body to the tooltip renderer title: (tooltipItem) => period.tooltipFormat === 'long' ? prettyLongDate(tooltipItem[0].raw.x) : prettyShortDate(tooltipItem[0].raw.x), label: (tooltipItem) => { const datasetLabel = tooltipItem.chart.data.datasets[tooltipItem.datasetIndex].label; - return `${yscale.ticks.callback(tooltipItem.raw.y)}: ${datasetLabel}`; + return `${datasetLabel}: ${yscale.ticks.callback(tooltipItem.raw.y)}`; } - } + }, + external: renderTooltip, }, annotation: { annotations: { @@ -116,7 +119,7 @@ function createGraphOptions({ yscale, period, highMark }) { borderWidth: 0.5, label: { display: true, - content: props.highMarkLabel, + content: `Max ${props.title}`, position: 'end', // 'start', 'center', or 'end' backgroundColor: 'transparent', color: 'rgb(139, 0, 0)', @@ -341,6 +344,7 @@ defineExpose({ } .footer { + margin-top: 10px; text-align: center; font-weight: bold; font-size: 12px; @@ -365,13 +369,8 @@ defineExpose({ border-right: 1px var(--pankow-color-primary) solid; } -.graphs-tooltip-title { - font-weight: bold; -} - .graphs-tooltip-item { padding: 2px 0px; - -webkit-text-stroke: 0.2px gray; } diff --git a/dashboard/src/components/app/Graphs.vue b/dashboard/src/components/app/Graphs.vue index 25b16d4ca..c3ee1e2a1 100644 --- a/dashboard/src/components/app/Graphs.vue +++ b/dashboard/src/components/app/Graphs.vue @@ -6,7 +6,7 @@ const t = i18n.t; import { ref, onMounted, useTemplateRef, nextTick, onUnmounted } from 'vue'; import AppsModel from '../../models/AppsModel.js'; -import { prettyBinarySize, prettyDecimalSize } from '@cloudron/pankow/utils'; +import { prettyDecimalSize } from '@cloudron/pankow/utils'; import SystemModel from '../../models/SystemModel.js'; import { SingleSelect } from '@cloudron/pankow'; import GraphItem from '../GraphItem.vue'; @@ -144,7 +144,6 @@ onUnmounted(async () => { yscale="cpu" :cpu-count="systemCpus.length" :high-mark="systemCpus.length * app.cpuQuota/100" - high-mark-label="Max CPU" > @@ -154,7 +153,6 @@ onUnmounted(async () => { yscale="memory" :memory="appMemory" :high-mark="appMemory" - high-mark-label="Max Memory" >