diff --git a/dashboard/src/components/SystemMetrics.vue b/dashboard/src/components/SystemMetrics.vue index 7753b9dac..c10a3cd1b 100644 --- a/dashboard/src/components/SystemMetrics.vue +++ b/dashboard/src/components/SystemMetrics.vue @@ -112,24 +112,10 @@ async function getMetrics(hours) { return { cpuData, memoryData, swapData }; } -async function refresh() { +function createGraphOptions({ yscale, realtime }) { const now = Date.now(); - const { cpuData, memoryData, swapData } = await getMetrics(period.value); - const cpuGraphData = { - datasets: [{ - label: 'CPU', - data: cpuData, - pointRadius: 0, - // https://www.chartjs.org/docs/latest/charts/line.html#line-styling - borderWidth: 1, - tension: 0.4, - showLine: true, - fill: true - }] - }; - - const cpuGraphOptions = { + return { maintainAspectRatio: false, plugins: { legend: { @@ -155,22 +141,14 @@ async function refresh() { callback: function (value) { if (period.value === 0) return `${5-(value-this.min)/60000}min`; return moment(value).format(periods.find((p) => p.id === period.value).format); - } + }, + stepSize: realtime ? 60*1000 : null // // for realtime graph, generate steps of 1min and appropriate tick text }, grid: { drawOnChartArea: false, }, }, - y: { - type: 'linear', - min: 0, - max: systemCpus.length * 100, - ticks: { - callback: (value) => `${value}%`, - maxTicksLimit: 6 // max tick labels to show - }, - beginAtZero: true, - }, + y: yscale, }, interaction: { intersect: false, @@ -178,11 +156,35 @@ async function refresh() { axis: 'x' } }; +} - if (period.value === 0) { - // for realtime graph, generate steps of 1min and appropriate tick text - cpuGraphOptions.scales.x.ticks.stepSize = 60*1000; // 1min - } +async function refresh() { + const { cpuData, memoryData, swapData } = await getMetrics(period.value); + + const cpuGraphData = { + datasets: [{ + label: 'CPU', + data: cpuData, + pointRadius: 0, + // https://www.chartjs.org/docs/latest/charts/line.html#line-styling + borderWidth: 1, + tension: 0.4, + showLine: true, + fill: true + }] + }; + + const cpuYscale = { + type: 'linear', + min: 0, + max: systemCpus.length * 100, + ticks: { + callback: (value) => `${value}%`, + maxTicksLimit: 6 // max tick labels to show + }, + beginAtZero: true, + }; + const cpuGraphOptions = createGraphOptions({ yscale: cpuYscale, realtime: period.value === 0 }); if (!cpuGraph) { cpuGraph = new Chart(cpuGraphNode.value, { type: 'line', data: cpuGraphData, options: cpuGraphOptions }); @@ -222,64 +224,22 @@ async function refresh() { }] }; - const memoryGraphOptions = { - maintainAspectRatio: false, - plugins: { - legend: { - display: false - }, - tooltip: { - callbacks: { - title: (tooltipItem) => moment(tooltipItem[0].raw.x).format(periods.find((p) => p.id === period.value).tooltipFormat) - } - } + const memoryYscale = { + type: 'linear', + min: 0, + max: (roundedMemory + roundedSwap)/ giB, + ticks: { + stepSize: 1, + autoSkip: true, // skip tick labels as needed + autoSkipPadding: 20, // padding between ticks + callback: (value) => `${value} GiB`, + maxTicksLimit: 8 // max tick labels to show }, - scales: { - x: { - // we used to use 'time' type but it relies on the data to generate ticks. we may not have data for our time periods - type: 'linear', - min: now - (period.value === 0 ? LIVE_REFRESH_HISTORY_MSECS : period.value*60*60*1000), - max: now, - ticks: { - autoSkip: true, // skip tick labels as needed - autoSkipPadding: 20, // padding between ticks - maxRotation: 0, // don't rotate the labels - count: 7, // tick labels to show. anything more than 7 will not work for "7 days" - callback: function (value) { - if (period.value === 0) return `${5-(value-this.min)/60000}min`; - return moment(value).format(periods.find((p) => p.id === period.value).format); - } - }, - grid: { - drawOnChartArea: false, - }, - }, - y: { - type: 'linear', - min: 0, - max: (roundedMemory + roundedSwap)/ giB, - ticks: { - stepSize: 1, - autoSkip: true, // skip tick labels as needed - autoSkipPadding: 20, // padding between ticks - callback: (value) => `${value} GiB`, - maxTicksLimit: 8 // max tick labels to show - }, - beginAtZero: true, - stacked: true, - } - }, - interaction: { - intersect: false, - mode: 'nearest', - axis: 'x' - } + beginAtZero: true, + stacked: true, }; - if (period.value === 0) { - // for realtime graph, generate steps of 1min and appropriate tick text - memoryGraphOptions.scales.x.ticks.stepSize = 60*1000; // 1min - } + const memoryGraphOptions = createGraphOptions({ yscale: memoryYscale, realtime: period.value === 0 }); if (!memoryGraph) { memoryGraph = new Chart(memoryGraphNode.value, { type: 'line', data: memoryGraphData, options: memoryGraphOptions });