display account resource usage in charts
This commit is contained in:
parent
d02a585665
commit
53c8da841d
13
account.html
13
account.html
@ -9,6 +9,7 @@
|
|||||||
<link rel="stylesheet" href="css/style.css">
|
<link rel="stylesheet" href="css/style.css">
|
||||||
<link rel="stylesheet" href="css/nav.css">
|
<link rel="stylesheet" href="css/nav.css">
|
||||||
<script src="scripts/account.js" type="module"></script>
|
<script src="scripts/account.js" type="module"></script>
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/chart.js" type="module"></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<header>
|
<header>
|
||||||
@ -34,17 +35,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="w3-card w3-padding">
|
<div class="w3-card w3-padding">
|
||||||
<h3>Cluster Resources</h3>
|
<h3>Cluster Resources</h3>
|
||||||
<table id="resource-table" class="w3-table w3-table-all w3-mobile" style="overflow-x: auto; margin-bottom: 1em;">
|
<div id="resource-container" style="display: flex; flex-direction: row; flex-wrap: wrap; column-gap: 10px; row-gap: 10px;"></div>
|
||||||
<thead>
|
|
||||||
<tr class="w3-black">
|
|
||||||
<th>Resource</th>
|
|
||||||
<th>Used</th>
|
|
||||||
<th>Free</th>
|
|
||||||
<th>Total</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody></tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</main>
|
</main>
|
||||||
|
@ -32,42 +32,75 @@ async function init () {
|
|||||||
document.querySelector("#pool").innerText = `Pool: ${instances.pool}`;
|
document.querySelector("#pool").innerText = `Pool: ${instances.pool}`;
|
||||||
document.querySelector("#vmid").innerText = `VMID Range: ${instances.vmid.min} - ${instances.vmid.max}`;
|
document.querySelector("#vmid").innerText = `VMID Range: ${instances.vmid.min} - ${instances.vmid.max}`;
|
||||||
document.querySelector("#nodes").innerText = `Nodes: ${nodes.toString()}`;
|
document.querySelector("#nodes").innerText = `Nodes: ${nodes.toString()}`;
|
||||||
buildResourceTable(resources, "#resource-table");
|
buildResourceTable("#resource-container", resources);
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildResourceTable (resources, tableid) {
|
function buildResourceTable (containerID, resources) {
|
||||||
if (resources instanceof Object) {
|
if (resources instanceof Object) {
|
||||||
const table = document.querySelector(tableid);
|
const container = document.querySelector(containerID);
|
||||||
const tbody = table.querySelector("tbody");
|
|
||||||
Object.keys(resources.resources).forEach((element) => {
|
Object.keys(resources.resources).forEach((element) => {
|
||||||
if (resources.resources[element].display) {
|
if (resources.resources[element].display) {
|
||||||
if (resources.resources[element].type === "list") {
|
if (resources.resources[element].type === "list") {
|
||||||
const row = tbody.insertRow();
|
|
||||||
const key = row.insertCell();
|
|
||||||
key.innerHTML = `${element}`;
|
|
||||||
const used = row.insertCell();
|
|
||||||
parseList(used, resources.used[element]);
|
|
||||||
const avail = row.insertCell();
|
|
||||||
parseList(avail, resources.avail[element]);
|
|
||||||
const total = row.insertCell();
|
|
||||||
parseList(total, resources.max[element]);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
const row = tbody.insertRow();
|
const chart = createResourceUsageChart(resources.resources[element].title, resources.avail[element], resources.used[element], resources.max[element], resources.resources[element]);
|
||||||
const key = row.insertCell();
|
container.append(chart);
|
||||||
key.innerText = `${element}`;
|
|
||||||
const used = row.insertCell();
|
|
||||||
used.innerText = `${parseNumber(resources.used[element], resources.resources[element])}`;
|
|
||||||
const val = row.insertCell();
|
|
||||||
val.innerText = `${parseNumber(resources.avail[element], resources.resources[element])}`;
|
|
||||||
const total = row.insertCell();
|
|
||||||
total.innerText = `${parseNumber(resources.max[element], resources.resources[element])}`;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function createResourceUsageChart (resourceName, resourceAvail, resourceUsed, resourceMax, resourceUnitData) {
|
||||||
|
const container = document.createElement("div");
|
||||||
|
// layout fits 6 resources per row on large screens
|
||||||
|
// max width = (100% [parent] - 50px [5 flexbox col gap]) / 6
|
||||||
|
container.style = "position: relative; min-width: 200px; width: 100%; max-width: calc((100% - 50px) / 6); aspect-ratio: 1;";
|
||||||
|
const canvas = document.createElement("canvas");
|
||||||
|
container.append(canvas);
|
||||||
|
const maxStr = parseNumber(resourceMax, resourceUnitData);
|
||||||
|
const usedStr = parseNumber(resourceUsed, resourceUnitData);
|
||||||
|
const usedRatio = resourceUsed / resourceMax;
|
||||||
|
const R = Math.min(usedRatio * 510, 255);
|
||||||
|
const G = Math.min((1 - usedRatio) * 510, 255);
|
||||||
|
const usedColor = `rgb(${R}, ${G}, 0)`;
|
||||||
|
new Chart(canvas, {
|
||||||
|
type: "pie",
|
||||||
|
data: {
|
||||||
|
labels: [
|
||||||
|
"Used",
|
||||||
|
"Available"
|
||||||
|
],
|
||||||
|
datasets: [{
|
||||||
|
label: resourceName,
|
||||||
|
data: [resourceUsed, resourceAvail],
|
||||||
|
backgroundColor: [
|
||||||
|
usedColor,
|
||||||
|
"rgb(140, 140, 140)"
|
||||||
|
],
|
||||||
|
borderWidth: 0,
|
||||||
|
hoverOffset: 4
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
plugins: {
|
||||||
|
title: {
|
||||||
|
display: true,
|
||||||
|
position: "bottom",
|
||||||
|
text: [resourceName, `Used ${usedStr} of ${maxStr}`],
|
||||||
|
color: "white"
|
||||||
|
},
|
||||||
|
legend: {
|
||||||
|
display: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
canvas.role = "img";
|
||||||
|
canvas.ariaLabel = `${resourceName} used ${usedStr} of ${maxStr}`;
|
||||||
|
return container;
|
||||||
|
}
|
||||||
|
|
||||||
function parseNumber (value, unitData) {
|
function parseNumber (value, unitData) {
|
||||||
const compact = unitData.compact;
|
const compact = unitData.compact;
|
||||||
const multiplier = unitData.multiplier;
|
const multiplier = unitData.multiplier;
|
||||||
@ -87,14 +120,3 @@ function parseNumber (value, unitData) {
|
|||||||
return `${value} ${unit}`;
|
return `${value} ${unit}`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function parseList (cell, list) {
|
|
||||||
const listElem = document.createElement("ul");
|
|
||||||
listElem.style = "list-style-type: none; padding: 0; margin: 0;";
|
|
||||||
for (const item of list) {
|
|
||||||
const itemElem = document.createElement("li");
|
|
||||||
itemElem.innerText = item;
|
|
||||||
listElem.append(itemElem);
|
|
||||||
}
|
|
||||||
cell.append(listElem);
|
|
||||||
}
|
|
||||||
|
Loading…
Reference in New Issue
Block a user