graphs: switch to time type graphs
the default one is bound on data. when data is not available, it appears buggy. it's better to show no data and always show the correct time line in the x-axis
This commit is contained in:
@@ -11,10 +11,13 @@ import { SingleSelect, Spinner } from 'pankow';
|
||||
import Section from './Section.vue';
|
||||
import SystemModel from '../models/SystemModel.js';
|
||||
|
||||
import 'chartjs-adapter-moment'; // https://www.chartjs.org/docs/latest/axes/cartesian/time.html#date-adapters
|
||||
|
||||
const systemModel = SystemModel.create();
|
||||
|
||||
function trKeyFromPeriod(period) {
|
||||
if (period === 0) return 'app.graphs.period.live';
|
||||
if (period === 1) return 'app.graphs.period.1h';
|
||||
if (period === 6) return 'app.graphs.period.6h';
|
||||
if (period === 12) return 'app.graphs.period.12h';
|
||||
if (period === 24) return 'app.graphs.period.24h';
|
||||
@@ -26,6 +29,7 @@ function trKeyFromPeriod(period) {
|
||||
|
||||
const periods = [
|
||||
{ id: 0, label: t(trKeyFromPeriod(0)) },
|
||||
{ id: 1, label: t(trKeyFromPeriod(1)) },
|
||||
{ id: 6, label: t(trKeyFromPeriod(6)) },
|
||||
{ id: 12, label: t(trKeyFromPeriod(12)) },
|
||||
{ id: 24, label: t(trKeyFromPeriod(24)) },
|
||||
@@ -34,7 +38,7 @@ const periods = [
|
||||
];
|
||||
|
||||
const busy = ref(false);
|
||||
const period = ref(0);
|
||||
const period = ref(24*7);
|
||||
const cpuGraphNode = useTemplateRef('cpuGraphNode');
|
||||
const memoryGraphNode = useTemplateRef('memoryGraphNode');
|
||||
|
||||
@@ -70,11 +74,8 @@ async function refresh() {
|
||||
const [error, result] = await systemModel.getMetrics({ fromSecs: (period.value || 0.1) * 60 * 60, intervalSecs: 300 });
|
||||
if (error) return console.error(error);
|
||||
|
||||
// cpu
|
||||
const cpuLabels = result.cpu.map(v => {
|
||||
return moment(v[1]*1000).format('hh:mm');
|
||||
});
|
||||
|
||||
const now = Date.now();
|
||||
const cpuLabels = result.cpu.map(v => v[1]*1000); // convert to msecs
|
||||
const cpuData = result.cpu.map(v => v[0]); // already scaled to cpu*100
|
||||
|
||||
const cpuGraphData = {
|
||||
@@ -97,23 +98,25 @@ async function refresh() {
|
||||
},
|
||||
scales: {
|
||||
x: {
|
||||
type: 'time',
|
||||
bounds: 'ticks', // otherwise data bound. https://www.chartjs.org/docs/latest/axes/cartesian/time.html#changing-the-scale-type-from-time-scale-to-logarithmic-linear-scale
|
||||
min: now - 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
|
||||
maxTicksLimit: 15, // max tick labels to show
|
||||
},
|
||||
grid: {
|
||||
drawOnChartArea: false,
|
||||
},
|
||||
}
|
||||
},
|
||||
y: {
|
||||
type: 'linear',
|
||||
min: 0,
|
||||
max: result.cpuCount * 100,
|
||||
ticks: {
|
||||
callback: (value) => `${value}%`,
|
||||
maxTicksLimit: 6 // max tick labels to show
|
||||
},
|
||||
min: 0,
|
||||
max: result.cpuCount * 100,
|
||||
beginAtZero: true,
|
||||
grid: {
|
||||
drawOnChartArea: false,
|
||||
@@ -130,22 +133,14 @@ async function refresh() {
|
||||
if (cpuGraph) cpuGraph.destroy();
|
||||
cpuGraph = new Chart(cpuGraphNode.value, { type: 'line', data: cpuGraphData, options: cpuGraphOptions });
|
||||
|
||||
const memoryLabels = result.memory.map(v => {
|
||||
return moment(v[1]*1000).format('hh:mm');
|
||||
});
|
||||
|
||||
const memoryData = result.memory.map(v => {
|
||||
return (v[0] / 1024 / 1024 / 1024).toFixed(2);
|
||||
});
|
||||
|
||||
const swapData = result.swap.map(v => { // assume that there is 1:1 timeline for swap and memory
|
||||
return (v[0] / 1024 / 1024 / 1024).toFixed(2);
|
||||
});
|
||||
const memoryLabels = result.memory.map(v => v[1]*1000); // convert to msecs
|
||||
const memoryData = result.memory.map(v => (v[0] / 1024 / 1024 / 1024).toFixed(2));
|
||||
// assume that there is 1:1 timeline for swap and memory data
|
||||
const swapData = result.swap.map(v => (v[0] / 1024 / 1024 / 1024).toFixed(2));
|
||||
|
||||
const giB = 1024 * 1024 * 1024;
|
||||
const quarterGiB = 0.25 * giB;
|
||||
const roundedMemory = Math.round(systemMemory.memory / quarterGiB) * quarterGiB;
|
||||
const roundedSwap = Math.round(systemMemory.swap / quarterGiB) * quarterGiB;
|
||||
const roundedMemory = Math.ceil(systemMemory.memory / giB) * giB; // we have to scale up so that the graph can show the data!
|
||||
const roundedSwap = Math.ceil(systemMemory.swap / giB) * giB;
|
||||
|
||||
const memoryGraphData = {
|
||||
labels: memoryLabels,
|
||||
@@ -184,27 +179,28 @@ async function refresh() {
|
||||
},
|
||||
scales: {
|
||||
x: {
|
||||
type: 'time',
|
||||
bounds: 'ticks', // otherwise data bound. https://www.chartjs.org/docs/latest/axes/cartesian/time.html#changing-the-scale-type-from-time-scale-to-logarithmic-linear-scale
|
||||
min: now - 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
|
||||
maxTicksLimit: 15, // max tick labels to show
|
||||
},
|
||||
grid: {
|
||||
drawOnChartArea: false,
|
||||
},
|
||||
}
|
||||
},
|
||||
y: {
|
||||
ticks: {
|
||||
callback: (value) => `${value} GiB`,
|
||||
color: (value /* ,index, ticks */) => {
|
||||
const tickValue = parseFloat(value['tick']['value']);
|
||||
return ((tickValue * 1024 * 1024 * 1024) > roundedMemory) ? '#ff7d98' : '#46a9ec';
|
||||
},
|
||||
maxTicksLimit: 6 // max tick labels to show
|
||||
},
|
||||
type: 'linear',
|
||||
min: 0,
|
||||
max: ((roundedMemory + roundedSwap)/ giB).toFixed(2), // string
|
||||
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,
|
||||
grid: {
|
||||
|
||||
Reference in New Issue
Block a user