Skip to main content

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