Concepts 🚀 Project 🧮 Labs
📚 Learn / Mini Projects / Mini Metrics Dashboard (chart + API)

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 files

Project files

📄 main.py python
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)
📄 index.html html
<!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>
📄 run.sh bash
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
🔍 Where this is used in OpenBenchML OpenBenchML's dashboard + leaderboard use this pattern. The leaderboard polls /api/leaderboard every 30s (or receives WS pushes) and re-renders the table.