Mini Metrics Dashboard (chart + API)
A dashboard that fetches metrics from FastAPI and renders a live bar chart with vanilla JS + SVG. No chart library.
🚀 Mini Project · 3 filesProject files
from fastapi import FastAPI
from fastapi.responses import HTMLResponse
from fastapi.middleware.cors import CORSMiddleware
import random, uvicorn
app = FastAPI()
app.add_middleware(CORSMiddleware, allow_origins=['*'], allow_methods=['*'])
@app.get('/metrics')
async def metrics():
# In real life, read from a DB
return {
'cpu': random.uniform(10, 90),
'memory': random.uniform(20, 80),
'disk': random.uniform(30, 70),
'network': random.uniform(5, 95),
}
if __name__ == '__main__':
uvicorn.run(app, host='0.0.0.0', port=8000)
<!DOCTYPE html>
<html>
<head>
<title>Dashboard</title>
<style>
body { font-family: sans-serif; margin: 2rem; }
.chart { display: flex; gap: 1rem; align-items: flex-end;
height: 240px; border-bottom: 2px solid #333; padding: 1rem; }
.bar { width: 60px; background: #a0c000; border-radius: 4px 4px 0 0;
position: relative; transition: height 0.5s; }
.bar .label { position: absolute; top: -1.5rem; left: 0; right: 0;
text-align: center; font-size: 0.8rem; }
.bar .val { position: absolute; bottom: 0.5rem; left: 0; right: 0;
text-align: center; color: #fff; font-weight: bold; }
</style>
</head>
<body>
<h1>Live Metrics</h1>
<div class='chart' id='chart'></div>
<script>
const METRICS = ['cpu', 'memory', 'disk', 'network'];
function render(data) {
const chart = document.getElementById('chart');
chart.innerHTML = METRICS.map(k => {
const v = data[k].toFixed(1);
return `<div class='bar' style='height:${v * 2.5}px'>
<div class='label'>${k}</div>
<div class='val'>${v}%</div>
</div>`;
}).join('');
}
async function refresh() {
const res = await fetch('http://localhost:8000/metrics');
const data = await res.json();
render(data);
}
refresh(); // initial paint
setInterval(refresh, 2000); // refresh every 2s
</script>
</body>
</html>
pip install fastapi uvicorn python main.py & # Open index.html in a browser # Bars update every 2 seconds with new random metrics
How it works
A dashboard has 3 pieces: (1) An API endpoint that returns the current metric values as JSON. (2) A render function that turns JSON into visual bars — here we use plain divs with height: value px. The CSS transition: height 0.5s makes the bars animate smoothly when the value changes. (3) A refresh loop: setInterval(refresh, 2000) calls the API and re-renders every 2 seconds. For a real dashboard you'd use a charting library (Chart.js, ECharts, D3) but the pattern is the same: fetch JSON → render → refresh on a timer. To make it real-time instead of polled, swap setInterval for a WebSocket — the server pushes new values the instant they change, no polling lag.
⚡ Open in Notebook