Charting Historical Data
Learn how to visualize historical OPC UA data in Node-RED dashboards.
Basic Chart Flow
[ Timer ] → [ History Read ] → [ Format for Chart ] → [ Chart Node ]
Format for Chart (Function)
// msg.payload contains history data
const chartData = [{
series: ["Temperature"],
data: [msg.payload.map(point => ({
x: new Date(point.sourceTimestamp),
y: point.value
}))],
labels: [""]
}];
msg.payload = chartData;
return msg;
Single Variable Chart
Last 24 Hours
History Read Configuration:
msg.nodeId = "ns=2;s=Temperature";
msg.startTime = "24 hours ago";
msg.endTime = "now";
msg.numValuesPerNode = 500;
Chart Node Settings:
- X-Axis Type: Time
- Interpolate: Linear
- Auto-scale: Enabled
Multiple Variables Chart
[ Timer ] → [ Read All ] → [ Format Multi ] → [ Chart ]
Format Multi (Function):
// Assuming msg.payload has multiple variable results
msg.payload = [{
series: ["Temp", "Pressure", "Flow"],
data: [
msg.temp.map(p => ({ x: new Date(p.sourceTimestamp), y: p.value })),
msg.pressure.map(p => ({ x: new Date(p.sourceTimestamp), y: p.value })),
msg.flow.map(p => ({ x: new Date(p.sourceTimestamp), y: p.value }))
],
labels: [""]
}];
return msg;
Aggregated Data for Smooth Charts
For long time periods, use aggregated data:
History Read Configuration:
msg.nodeId = "ns=2;s=Temperature";
msg.startTime = "7 days ago";
msg.endTime = "now";
msg.processingInterval = "1 hour";
// Set Aggregate Type: Average
This reduces data points while maintaining trend visibility.
Real-Time + Historical
Combine current and historical data:
┌→ [ Format Historical ] ┐
[ Timer ] → [ History Read ] ├→ [ Merge ] → [ Chart ]
[ MQTT ] → [ Current Value ] → [ Format Live ]┘
Dashboard Examples
Gauge with Historical Context
[ Timer ] → [ Recent History ] → [ Calculate Stats ] → [ Gauge ]
Calculate Stats (Function):
const values = msg.payload.map(p => p.value);
msg.payload = {
current: values[values.length - 1],
min: Math.min(...values),
max: Math.max(...values),
avg: values.reduce((a, b) => a + b) / values.length
};
return msg;
Time Range Selector
[ UI Dropdown ] → [ History Read ] → [ Chart ]
Dropdown Options:
- Last Hour
- Last 24 Hours
- Last Week
- Last Month
Function Node:
const ranges = {
"hour": "1 hour ago",
"day": "24 hours ago",
"week": "7 days ago",
"month": "30 days ago"
};
msg.startTime = ranges[msg.payload];
msg.endTime = "now";
return msg;
Tips
- Use aggregated data for charts spanning days/weeks
- Limit data points to 500-1000 for smooth rendering
- Update charts periodically (every 15-60 seconds)
- Use appropriate processing intervals for aggregation
- Consider browser performance with large datasets