diff --git a/dashboard/src/components/GraphItem.vue b/dashboard/src/components/GraphItem.vue
index dc23e3f2b..fb5927b43 100644
--- a/dashboard/src/components/GraphItem.vue
+++ b/dashboard/src/components/GraphItem.vue
@@ -4,7 +4,7 @@
import moment from 'moment-timezone';
import { onMounted, onUnmounted, useTemplateRef, watch } from 'vue';
import Chart from 'chart.js/auto';
-import { prettyDecimalSize } from '@cloudron/pankow/utils';
+import { prettyDecimalSize, prettyLongDate, prettyShortDate } from '@cloudron/pankow/utils';
import annotationPlugin from 'chartjs-plugin-annotation';
Chart.register(annotationPlugin);
@@ -12,6 +12,7 @@ Chart.register(annotationPlugin);
const LIVE_REFRESH_INTERVAL_MSECS = 1000; // for realtime graphs, the time (x axis) advances at this pace
const graphNode = useTemplateRef('graphNode');
+const tooltipElem = useTemplateRef('tooltipElem');
let graph = null;
let liveRefreshIntervalId = null;
@@ -50,11 +51,40 @@ function createGraphOptions({ yscale, period, highMark }) {
position: 'bottom' // not used, hidden since color code is shown in tooltip
},
tooltip: {
+ enabled: false,
+ external: function(context) {
+ 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.style.left = tooltipModel.caretX + 'px';
+ tooltipElem.value.style.top = 0 + 'px';
+ tooltipElem.value.style.height = '100%';
+ },
callbacks: {
- title: (tooltipItem) => moment(tooltipItem[0].raw.x).format(period.tooltipFormat),
+ 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 `${datasetLabel}: ${yscale.ticks.callback(tooltipItem.raw.y)}`;
+ return `${yscale.ticks.callback(tooltipItem.raw.y)}: ${datasetLabel}`;
}
}
},
@@ -260,6 +290,7 @@ defineExpose({
@@ -277,3 +308,23 @@ defineExpose({
}
+
+
diff --git a/dashboard/src/components/SystemMetrics.vue b/dashboard/src/components/SystemMetrics.vue
index 11fa03139..aeb3a7e12 100644
--- a/dashboard/src/components/SystemMetrics.vue
+++ b/dashboard/src/components/SystemMetrics.vue
@@ -16,13 +16,13 @@ const systemModel = SystemModel.create();
const appsModel = AppsModel.create();
const periods = [
- { hours: 0, label: t('app.graphs.period.live'), tickFormat: 'hh:mm A', tooltipFormat: 'hh:mm:ss A' },
- { hours: 1, intervalSecs: 20, label: t('app.graphs.period.1h'), tickFormat: 'hh:mm A', tooltipFormat: 'hh:mm:ss A' }, // 180 points
- { hours: 6, intervalSecs: 60, label: t('app.graphs.period.6h'), tickFormat: 'hh:mm A', tooltipFormat: 'hh:mm A' },
- { hours: 12, intervalSecs: 240, label: t('app.graphs.period.12h'), tickFormat: 'hh:mm A', tooltipFormat: 'hh:mm A' },
- { hours: 24, intervalSecs: 480, label: t('app.graphs.period.24h'), tickFormat: 'hh:mm A', tooltipFormat: 'hh:mm A' },
- { hours: 24*7, intervalSecs: 960, label: t('app.graphs.period.7d'), tickFormat: 'DD MMM', tooltipFormat: 'DD MMM hh:mm A' },
- { hours: 24*30, intervalSecs: 960, label: t('app.graphs.period.30d'), tickFormat: 'DD MMM', tooltipFormat: 'DD MMM hh:mm A' }, // 2700 points
+ { hours: 0, label: t('app.graphs.period.live'), tickFormat: 'hh:mm A', tooltipFormat: 'short' },
+ { hours: 1, intervalSecs: 20, label: t('app.graphs.period.1h'), tickFormat: 'hh:mm A', tooltipFormat: 'short' }, // 180 points
+ { hours: 6, intervalSecs: 60, label: t('app.graphs.period.6h'), tickFormat: 'hh:mm A', tooltipFormat: 'short' },
+ { hours: 12, intervalSecs: 240, label: t('app.graphs.period.12h'), tickFormat: 'hh:mm A', tooltipFormat: 'short' },
+ { hours: 24, intervalSecs: 480, label: t('app.graphs.period.24h'), tickFormat: 'hh:mm A', tooltipFormat: 'short' },
+ { hours: 24*7, intervalSecs: 960, label: t('app.graphs.period.7d'), tickFormat: 'DD MMM', tooltipFormat: 'long' },
+ { hours: 24*30, intervalSecs: 960, label: t('app.graphs.period.30d'), tickFormat: 'DD MMM', tooltipFormat: 'long' }, // 2700 points
];
const busy = ref(true);