<div class="gauge-card">
<h3>Server Performance</h3>
<div class="gauge-wrapper">
<svg viewBox="0 0 100 50" class="gauge-svg">
<path class="gauge-bg" d="M 10 50 A 40 40 0 0 1 90 50" fill="none" stroke="#e5e7eb" stroke-width="12" stroke-linecap="round"></path>
<path id="gauge-fill" class="gauge-fill" d="M 10 50 A 40 40 0 0 1 90 50" fill="none" stroke="#3b82f6" stroke-width="12" stroke-linecap="round"></path>
</svg>
<div class="gauge-center">
<span id="gauge-text" class="gauge-text">0%</span>
<span class="gauge-label">Load</span>
</div>
</div>
<button id="update-gauge" class="update-btn">Simulate Load</button>
</div>
*, *::before, *::after {
box-sizing: border-box;
}
body {
font-family: system-ui, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
background: #f9fafb;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
margin: 0;
padding: 20px;
}
.gauge-card {
background: #ffffff;
padding: 30px;
border-radius: 16px;
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1);
text-align: center;
width: 100%;
max-width: 350px;
}
.gauge-card h3 {
margin: 0 0 24px 0;
color: #111827;
}
.gauge-wrapper {
position: relative;
width: 100%;
margin-bottom: 24px;
}
.gauge-svg {
width: 100%;
height: auto;
overflow: visible;
}
.gauge-fill {
stroke-dasharray: 126;
stroke-dashoffset: 126;
transition: stroke-dashoffset 1s cubic-bezier(0.4, 0, 0.2, 1), stroke 1s ease;
}
.gauge-center {
position: absolute;
bottom: 0;
left: 0;
width: 100%;
display: flex;
flex-direction: column;
align-items: center;
}
.gauge-text {
font-size: 2.5rem;
font-weight: 700;
color: #111827;
line-height: 1;
}
.gauge-label {
color: #6b7280;
font-weight: 500;
margin-top: 4px;
}
.update-btn {
background: #f3f4f6;
color: #374151;
border: none;
padding: 10px 20px;
border-radius: 8px;
font-weight: 600;
cursor: pointer;
transition: background 0.2s;
}
.update-btn:hover {
background: #e5e7eb;
}
const gaugeFill = document.getElementById("gauge-fill");
const gaugeText = document.getElementById("gauge-text");
const updateBtn = document.getElementById("update-gauge");
// Total length of the SVG path is approx 126
const pathLength = 126;
function setGauge(percentage) {
// Calculate how much of the stroke to offset
const offset = pathLength - (percentage / 100) * pathLength;
gaugeFill.style.strokeDashoffset = offset;
// Animate the numbers going up
let currentVal = parseInt(gaugeText.innerText);
const diff = percentage - currentVal;
const steps = 30;
let step = 0;
const counter = setInterval(function() {
step++;
const newVal = Math.round(currentVal + (diff * (step / steps)));
gaugeText.innerText = newVal + "%";
if (step >= steps) {
clearInterval(counter);
}
}, 30);
// Change color based on severity
if (percentage > 85) {
gaugeFill.style.stroke = "#ef4444";
} else if (percentage > 60) {
gaugeFill.style.stroke = "#f59e0b";
} else {
gaugeFill.style.stroke = "#3b82f6";
}
}
// Initial animation
setTimeout(function() {
setGauge(65);
}, 500);
updateBtn.addEventListener("click", function() {
const randomValue = Math.floor(Math.random() * 100);
setGauge(randomValue);
});