Skip to content

Commit

Permalink
improved chart visuals and added tooltip with additional information
Browse files Browse the repository at this point in the history
Changes in detail:
- show load in percent
- pined chart y max to 100%
- added units to chart y-Axis
- added small (by default) blue box to CPU load legend (like the one that was in the RAM legend)
- added hover text to the "Load average: XX.X % (X.XX) last minute" that displays the load averages for 1, 5 and 15 minutes
- added tooltip to both charts that display the cpu load / ram usage at the time where the cursor hovers.

Signed-off-by: Malex14 <[email protected]>
  • Loading branch information
Malex14 committed Nov 16, 2024
1 parent 0835426 commit 8bb2ea6
Show file tree
Hide file tree
Showing 9 changed files with 123 additions and 44 deletions.
21 changes: 18 additions & 3 deletions css/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,16 @@
margin-top: 0;
}

.rambox {
.rambox, .cpubox {
height: 10px;
width: 10px;
background-color: #555;
background-color: var(--color-primary-element);
}

.swapbox {
height: 10px;
width: 10px;
background-color: #222;
background-color: var(--color-background-darker);
}

.info {
Expand Down Expand Up @@ -291,3 +291,18 @@
.active-users-box .info {
font-size: 2rem;
}

.smoothie-chart-tooltip {
display: flex;
flex-wrap: nowrap;
align-items: center;
padding: 16px;
margin: 0 0.25rem;
background-color: var(--color-main-background);
border: 2px solid var(--color-border);
border-radius: var(--border-radius-large);
}

.cpu-wrapper {
width: 100%;
}
107 changes: 68 additions & 39 deletions js/script.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,21 @@
memoryUsageLine,
swapUsageLine,
cpuLoadChart,
cpuLoadLine,
activeUsersChart,
sharesChart;

$(document).ready(function () {
var rambox = document.getElementById('rambox');
rambox.style.backgroundColor = OCA.Theming ? OCA.Theming.color : 'rgb(54, 129, 195)';

var swapbox = document.getElementById('swapbox');
swapbox.style.backgroundColor = 'rgba(100, 100, 100, 0.8)';
cpuLoadLine

const chartOptions = {
millisPerPixel: 100,
minValue: 0,
grid: {fillStyle: 'rgba(0,0,0,0)', strokeStyle: 'transparent'},
labels: {fillStyle: getThemedPassiveColor(), fontSize: 12, precision: 1},
responsive: true,
tooltip: true,
tooltipLine: {
strokeStyle: getThemedPassiveColor()
}
};

$(function () {
initDiskCharts();

setHumanReadableSizeToElement("databaseSize");
Expand All @@ -37,7 +41,7 @@

$.get(url)
.done(function (response) {
updateCPUStatistics(response.system.cpuload)
updateCPUStatistics(response.system.cpuload, response.system.cpunum)
updateMemoryStatistics(response.system.mem_total, response.system.mem_free, response.system.swap_total, response.system.swap_free)
})
.always(function () {
Expand All @@ -63,10 +67,10 @@
* Reset all canvas widths on window resize so canvas is responsive
*/
function resizeSystemCharts() {
var cpuCanvas = $("#cpuloadcanvas"),
cpuCanvasWidth = cpuCanvas.parents('.infobox').width() - 30,
let cpuCanvas = $("#cpuloadcanvas"),
cpuCanvasWidth = cpuCanvas.parents('.infobox').width(),
memCanvas = $("#memorycanvas"),
memCanvasWidth = memCanvas.parents('.infobox').width() - 30;
memCanvasWidth = memCanvas.parents('.infobox').width();


// We have to set css width AND attribute width
Expand All @@ -76,9 +80,14 @@
memCanvas.attr('width', memCanvasWidth);
}

function updateCPUStatistics(cpuload) {
var $cpuFooterInfo = $('#cpuFooterInfo');
var $cpuLoadCanvas = $('#cpuloadcanvas');
function updateCPUStatistics(cpuload, numCpus) {
let $cpuFooterInfo = $('#cpuFooterInfo');
let $cpuLoadCanvas = $('#cpuloadcanvas');

// We need to stop touch events here, since they cause the tooltip to open, but never close again
$cpuLoadCanvas[0].addEventListener('touchstart', (e) => {
e.preventDefault();
})

if (cpuload === 'N/A') {
$cpuFooterInfo.text(t('serverinfo', 'CPU info not available'));
Expand All @@ -89,30 +98,43 @@
$cpuLoadCanvas.removeClass('hidden');
}

var cpu1 = cpuload[0],
cpu2 = cpuload[1],
cpu3 = cpuload[2];
let cpuloadFixed = cpuload.map((load) => load.toFixed(2));
let cpuloadPercentageFixed = cpuload.map((load) => ((load / numCpus) * 100).toFixed(1));

if (typeof cpuLoadChart === 'undefined') {
cpuLoadChart = new SmoothieChart(
{
millisPerPixel: 100,
minValue: 0,
grid: {fillStyle: 'rgba(0,0,0,0)', strokeStyle: 'transparent'},
labels: {fillStyle: 'rgba(0,0,0,0.4)', fontSize: 12},
responsive: true
});
const percentageFormatter = (val, precision) => val.toFixed(precision) + " %";

cpuLoadChart = new SmoothieChart({
...chartOptions,
yMinFormatter: percentageFormatter,
yMaxFormatter: percentageFormatter,
maxValue: 100
});
cpuLoadChart.streamTo(document.getElementById("cpuloadcanvas"), 1000/*delay*/);
cpuLoadLine = new TimeSeries();
cpuLoadChart.addTimeSeries(cpuLoadLine, {
lineWidth: 1,
strokeStyle: getThemedPassiveColor(),
fillStyle: getThemedPrimaryColor()
fillStyle: getThemedPrimaryColor(),
tooltipLabel: t('serverinfo', 'CPU Usage:')
});
}

$cpuFooterInfo.text(t('serverinfo', 'Load average: {cpu} (last minute)', { cpu: cpu1.toFixed(2) }));
cpuLoadLine.append(new Date().getTime(), cpu1);
$cpuFooterInfo.text(t('serverinfo', 'Load average: {percentage} % ({cpu}) last minute', { percentage: cpuloadPercentageFixed[0], cpu: cpuloadFixed[0] }));
$cpuFooterInfo[0].title = t(
'serverinfo',
'{lastMinutePercentage} % ({lastMinute}) last Minute\n{last5MinutesPercentage} % ({last5Minutes}) last 5 Minutes\n{last15MinutesPercentage} % ({last15Minutes}) last 15 Minutes',
{
lastMinute: cpuloadFixed[0],
lastMinutePercentage: cpuloadPercentageFixed[0],
last5Minutes: cpuloadFixed[1],
last5MinutesPercentage: cpuloadPercentageFixed[1],
last15Minutes: cpuloadFixed[2],
last15MinutesPercentage: cpuloadPercentageFixed[2]
}
);

cpuLoadLine.append(new Date().getTime(), cpuload[0]);
}

function isMemoryStat(memTotal, memFree) {
Expand All @@ -136,6 +158,11 @@
var $swapFooterInfo = $('#swapFooterInfo');
var $memoryCanvas = $('#memorycanvas');

// We need to stop touch events here, since they cause the tooltip to open, but never close again
$memoryCanvas[0].addEventListener('touchstart', (e) => {
e.preventDefault();
})

var memTotalBytes = memTotal * 1024,
memUsageBytes = (memTotal - memFree) * 1024,
memTotalGB = memTotal / (1024 * 1024),
Expand All @@ -152,27 +179,29 @@
}

if (typeof memoryUsageChart === 'undefined') {
const gbFormatter = (val, precision) => val.toFixed(precision) + " GB";

memoryUsageChart = new SmoothieChart(
{
millisPerPixel: 100,
...chartOptions,
maxValue: maxValueOfChart,
minValue: 0,
grid: {fillStyle: 'rgba(0,0,0,0)', strokeStyle: 'transparent'},
labels: {fillStyle: 'rgba(0,0,0,0.4)', fontSize: 12},
responsive: true
yMinFormatter: gbFormatter,
yMaxFormatter: gbFormatter
});
memoryUsageChart.streamTo(document.getElementById("memorycanvas"), 1000/*delay*/);
memoryUsageLine = new TimeSeries();
memoryUsageChart.addTimeSeries(memoryUsageLine, {
lineWidth: 1,
strokeStyle: getThemedPassiveColor(),
fillStyle: getThemedPrimaryColor()
fillStyle: getThemedPrimaryColor(),
tooltipLabel: t('serverinfo', 'RAM Usage:')
});
swapUsageLine = new TimeSeries();
memoryUsageChart.addTimeSeries(swapUsageLine, {
lineWidth: 1,
strokeStyle: 'rgb(100, 100, 100)',
fillStyle: 'rgba(100, 100, 100, 0.2)'
strokeStyle: getThemedPassiveColor(),
fillStyle: 'rgba(100, 100, 100, 0.2)',
tooltipLabel: t('serverinfo', 'SWAP Usage:')
});
}

Expand Down
2 changes: 1 addition & 1 deletion js/smoothie.js
Original file line number Diff line number Diff line change
Expand Up @@ -658,7 +658,7 @@
}
var el = this.getTooltipEl();
el.style.top = Math.round(this.mousePageY) + 'px';
el.style.left = Math.round(this.mousePageX) + 'px';
el.style.right = `calc(100vw - ${Math.round(this.mousePageX)}px)`;
this.updateTooltip();
};

Expand Down
11 changes: 11 additions & 0 deletions lib/OperatingSystems/FreeBSD.php
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,16 @@ public function getCpuName(): string {
return $data;
}

public function getCpuCount(): int {
$numCpu = 1; // this should be a save default

try {
$numCpu = intval($this->executeCommand('sysctl -n hw.ncpu')); //TODO: this should be tested if it actually works on FreeBSD
} catch (RuntimeException) {}

return $numCpu;
}

public function getTime(): string {
try {
return $this->executeCommand('date');
Expand Down Expand Up @@ -247,4 +257,5 @@ protected function getNetInterfaces(): array {
}
return $data;
}

}
7 changes: 7 additions & 0 deletions lib/OperatingSystems/IOperatingSystem.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,13 @@ public function supported(): bool;
*/
public function getCpuName(): string;

/**
* Get number of processors (threads).
*
* @return int
*/
public function getCpuCount(): int;

/**
* Get disk info returns a list of Disk objects. Used and Available in bytes.
*
Expand Down
11 changes: 11 additions & 0 deletions lib/OperatingSystems/Linux.php
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,17 @@ public function getCpuName(): string {
return $data;
}

public function getCpuCount(): int
{
$numCpu = 1; // this should be a save default

try {
$numCpu = intval($this->executeCommand('nproc --all'));
} catch (RuntimeException) {}

return $numCpu;
}

public function getTime(): string {
try {
return $this->executeCommand('date');
Expand Down
4 changes: 4 additions & 0 deletions lib/Os.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ public function getCpuName(): string {
return $this->backend->getCpuName();
}

public function getCpuCount(): int {
return $this->backend->getCpuCount();
}

public function getTime(): string {
return $this->backend->getTime();
}
Expand Down
2 changes: 2 additions & 0 deletions lib/SystemStatistics.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ public function __construct(IConfig $config, IAppManager $appManager, Installer
public function getSystemStatistics(bool $skipApps = false, bool $skipUpdate = true): array {
$processorUsage = $this->getProcessorUsage();
$memoryUsage = $this->os->getMemory();
$numCPU = $this->os->getCpuCount();

$data = [
'version' => $this->config->getSystemValue('version'),
Expand All @@ -52,6 +53,7 @@ public function getSystemStatistics(bool $skipApps = false, bool $skipUpdate = t
'debug' => $this->config->getSystemValue('debug', false) ? 'yes' : 'no',
'freespace' => $this->getFreeSpace(),
'cpuload' => $processorUsage['loadavg'],
'cpunum' => $numCPU,
'mem_total' => $memoryUsage->getMemTotal() * 1024,
'mem_free' => $memoryUsage->getMemAvailable() * 1024,
'swap_total' => $memoryUsage->getSwapTotal() * 1024,
Expand Down
2 changes: 1 addition & 1 deletion templates/settings-admin.php
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ function FormatMegabytes(int $byte): string {
<canvas id="cpuloadcanvas" style="width:100%; height:200px" width="600" height="200"></canvas>
</div>
</div>
<p><em id="cpuFooterInfo"></em></p>
<p><span class="cpubox" id="cpubox">&nbsp;&nbsp;</span>&nbsp;&nbsp;<em id="cpuFooterInfo"></em></p>
</div>

<div class="col col-6 col-l-12">
Expand Down

0 comments on commit 8bb2ea6

Please sign in to comment.