Web Technologies in Industry: Modern Monitoring Dashboards
Why Web Technologies in Factories?
Years ago, industrial monitoring dashboards were heavy desktop applications -- requiring installation on every machine, running only on Windows, and painful to update. Today, web-based monitoring dashboards have changed everything: open them from any browser, on any device, from anywhere.
Imagine a factory manager opening their phone and seeing every machine's status in real time -- temperatures, alarms, production efficiency. That is exactly what you build with web technologies.
HTML: The Page Structure
HTML (HyperText Markup Language) is the skeleton of any web page. It defines what exists on the page: headings, tables, buttons, and data containers.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Factory Monitoring Dashboard</title>
<link rel="stylesheet" href="dashboard.css">
</head>
<body>
<header>
<h1>Production Line 3 - Monitoring</h1>
<span id="clock">--:--:--</span>
</header>
<main>
<!-- Machine status cards -->
<section class="machine-cards">
<div class="card" id="machine-42">
<h2>CNC Lathe #42</h2>
<div class="status running">Running</div>
<div class="readings">
<div class="reading">
<span class="label">Temp</span>
<span class="value" id="temp-42">--</span>
<span class="unit">C</span>
</div>
<div class="reading">
<span class="label">Vibration</span>
<span class="value" id="vib-42">--</span>
<span class="unit">mm/s</span>
</div>
<div class="reading">
<span class="label">Power</span>
<span class="value" id="power-42">--</span>
<span class="unit">kW</span>
</div>
</div>
</div>
</section>
<!-- Active alarms table -->
<section class="alarms">
<h2>Active Alarms</h2>
<table>
<thead>
<tr>
<th>Time</th>
<th>Machine</th>
<th>Severity</th>
<th>Message</th>
</tr>
</thead>
<tbody id="alarm-table">
<!-- Populated dynamically by JavaScript -->
</tbody>
</table>
</section>
</main>
<script src="dashboard.js"></script>
</body>
</html>
Key HTML Elements for Dashboards
| Element | Use Case |
|---|---|
<div> |
General container for grouping elements |
<span> |
Inline text (sensor values) |
<table> |
Tabular data (alarms, logs) |
<canvas> |
Custom charts and graphs |
<progress> |
Progress bar (production percentage) |
<meter> |
Gauge (tank level) |
CSS: Appearance and Layout
CSS (Cascading Style Sheets) controls how the page looks: colors, sizes, layout, and animations.
/* dashboard.css */
/* Color variables -- easy to customize */
:root {
--bg-primary: #0f172a;
--bg-card: #1e293b;
--text-primary: #f1f5f9;
--text-secondary: #94a3b8;
--status-running: #22c55e;
--status-stopped: #ef4444;
--status-warning: #f59e0b;
--accent: #3b82f6;
}
body {
margin: 0;
font-family: 'Segoe UI', Tahoma, sans-serif;
background: var(--bg-primary);
color: var(--text-primary);
}
/* Machine card grid */
.machine-cards {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
gap: 1rem;
padding: 1rem;
}
.card {
background: var(--bg-card);
border-radius: 12px;
padding: 1.5rem;
border: 1px solid rgba(255, 255, 255, 0.1);
transition: transform 0.2s, box-shadow 0.2s;
}
.card:hover {
transform: translateY(-2px);
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.3);
}
/* Machine status badges */
.status {
display: inline-block;
padding: 0.25rem 0.75rem;
border-radius: 20px;
font-size: 0.85rem;
font-weight: 600;
}
.status.running { background: var(--status-running); color: #000; }
.status.stopped { background: var(--status-stopped); color: #fff; }
.status.warning { background: var(--status-warning); color: #000; }
/* Sensor readings */
.readings {
display: flex;
justify-content: space-between;
margin-top: 1rem;
}
.reading .value {
font-size: 2rem;
font-weight: 700;
color: var(--accent);
}
.reading .unit {
font-size: 0.8rem;
color: var(--text-secondary);
}
/* High value alert */
.reading .value.high {
color: var(--status-stopped);
animation: pulse 1s infinite;
}
@keyframes pulse {
0%, 100% { opacity: 1; }
50% { opacity: 0.5; }
}
Responsive Design: Every Screen Size
An engineer monitors from a large screen in the control room while a manager checks from their phone. Responsive design ensures the dashboard works on all sizes.
/* Small screens (phones) */
@media (max-width: 768px) {
.machine-cards {
grid-template-columns: 1fr;
}
.readings {
flex-direction: column;
gap: 0.5rem;
}
.reading .value {
font-size: 1.5rem;
}
}
/* Medium screens (tablets) */
@media (min-width: 769px) and (max-width: 1024px) {
.machine-cards {
grid-template-columns: repeat(2, 1fr);
}
}
/* Large screens (control room displays) */
@media (min-width: 1025px) {
.machine-cards {
grid-template-columns: repeat(4, 1fr);
}
}
JavaScript: Bringing the Dashboard to Life
JavaScript transforms a static page into a live control panel -- it fetches data, updates numbers, and triggers alarms.
Updating Data via REST API
// Fetch machine data every 5 seconds
async function fetchMachineData() {
try {
const response = await fetch('/api/machines', {
headers: { 'X-API-Key': 'sk_prod_abc123' }
});
const machines = await response.json();
machines.forEach(machine => {
updateCard(machine);
});
} catch (error) {
console.error('Failed to fetch data:', error);
showConnectionError();
}
}
function updateCard(machine) {
const tempEl = document.getElementById(`temp-${machine.id}`);
const vibEl = document.getElementById(`vib-${machine.id}`);
const powerEl = document.getElementById(`power-${machine.id}`);
tempEl.textContent = machine.temperature_c.toFixed(1);
vibEl.textContent = machine.vibration_mm_s.toFixed(1);
powerEl.textContent = machine.power_kw.toFixed(1);
// Highlight high values
tempEl.classList.toggle('high', machine.temperature_c > 80);
vibEl.classList.toggle('high', machine.vibration_mm_s > 8);
}
// Update every 5 seconds
setInterval(fetchMachineData, 5000);
fetchMachineData(); // immediate update on load
Real-Time Data via WebSocket
// WebSocket connection for live data
const ws = new WebSocket('ws://factory-server:8080/live');
ws.onopen = () => {
document.getElementById('connection-status').textContent = 'Connected';
document.getElementById('connection-status').classList.add('connected');
};
ws.onmessage = (event) => {
const data = JSON.parse(event.data);
switch (data.type) {
case 'sensor_update':
updateCard(data.payload);
break;
case 'alarm':
addAlarmRow(data.payload);
playAlarmSound();
showNotification(data.payload.message);
break;
case 'machine_status':
updateMachineStatus(data.payload.id, data.payload.status);
break;
}
};
ws.onclose = () => {
document.getElementById('connection-status').textContent = 'Disconnected';
// Reconnect after 3 seconds
setTimeout(() => {
location.reload();
}, 3000);
};
function addAlarmRow(alarm) {
const table = document.getElementById('alarm-table');
const row = table.insertRow(0);
row.innerHTML = `
<td>${new Date(alarm.timestamp).toLocaleTimeString()}</td>
<td>${alarm.machine_name}</td>
<td class="severity-${alarm.severity}">${alarm.severity}</td>
<td>${alarm.message}</td>
`;
}
Canvas: Live Charts
The HTML <canvas> element lets you draw custom charts without external libraries:
// Simple temperature history chart
const canvas = document.getElementById('temp-chart');
const ctx = canvas.getContext('2d');
const readings = []; // array of readings
const MAX_POINTS = 60; // last 60 readings
function addReading(temp) {
readings.push(temp);
if (readings.length > MAX_POINTS) readings.shift();
drawChart();
}
function drawChart() {
const w = canvas.width;
const h = canvas.height;
ctx.clearRect(0, 0, w, h);
// Maximum threshold line
const maxLine = h - (85 / 100) * h;
ctx.strokeStyle = '#ef4444';
ctx.setLineDash([5, 5]);
ctx.beginPath();
ctx.moveTo(0, maxLine);
ctx.lineTo(w, maxLine);
ctx.stroke();
ctx.setLineDash([]);
// Draw readings
ctx.strokeStyle = '#3b82f6';
ctx.lineWidth = 2;
ctx.beginPath();
readings.forEach((temp, i) => {
const x = (i / MAX_POINTS) * w;
const y = h - (temp / 100) * h;
if (i === 0) ctx.moveTo(x, y);
else ctx.lineTo(x, y);
});
ctx.stroke();
}
Popular Frameworks for Industrial Dashboards
For larger projects, use established frameworks instead of building from scratch:
| Tool | Purpose | Strengths |
|---|---|---|
| Chart.js | Charts and graphs | Easy, interactive, responsive |
| D3.js | Advanced visualizations | Extremely flexible, steep learning curve |
| Grafana | Ready-made dashboards | Connects to any database |
| HTMX | Interactivity without complex JS | Lightweight, works with any backend |
| Tailwind CSS | Rapid styling | Utility classes, responsive out of the box |
Summary
| Technology | Role in a Monitoring Dashboard |
|---|---|
| HTML | Page structure -- cards, tables, elements |
| CSS | Appearance -- colors, layout, animations |
| JavaScript | Logic -- fetch data, update, trigger alarms |
| WebSocket | Live connection -- real-time data with no delay |
| Canvas | Charts -- reading history, trend lines |
| Responsive | Compatibility -- works on control room screens and phones |
Web technologies have transformed industrial monitoring from closed, expensive applications into flexible dashboards that any engineer can build. The browser has become the new control panel for the smart factory.