No, the graph_xyz files are not created or managed by Watchtower.
A general interest script:
I'm using WatchTower for a graph of air pressure data from 5 sources. Normally, the graph lines are between about 990 hPa and 1030 hPa. Occasionally, one of the sources goes off-line, and the AP values for that device are 0. That causes the graph to expand its scale to be 0 to 1200, compressing the non-zero values to a nearly straight line (the values of the sensors typically differ by only 2-3 hPa when online).
I had a script that colored each data line. Below is an augmented version of that script that ChatGPT generated to ignore values below a “Minimum plausible pressure value“.
// Minimum plausible pressure value.
// Any value below this will be treated as bad/offline data and not graphed.
const MIN_VALID_PRESSURE_HPA = 100;
// false = show gaps where readings were bad/offline
// true = connect the line across missing readings
const CONNECT_ACROSS_BAD_VALUES = false;
$config.data.datasets[0].borderColor = '#00FF00';
$config.data.datasets[0].backgroundColor = 'transparent';
$config.data.datasets[1].borderColor = '#FF0000';
$config.data.datasets[1].backgroundColor = 'transparent';
$config.data.datasets[2].borderColor = '#FF00FF';
$config.data.datasets[2].backgroundColor = 'transparent';
$config.data.datasets[3].borderColor = '#0000FF';
$config.data.datasets[3].backgroundColor = 'transparent';
$config.data.datasets[4].borderColor = '#000000';
$config.data.datasets[4].backgroundColor = 'transparent';
//$config.data.datasets[5].borderColor = '#000000';
//$config.data.datasets[5].backgroundColor = 'transparent';
$config.options.scales.y.title.text = 'Pressure (hPa)';
// Example to suggest limits; actual bad/offline values are removed below
$config.options.scales.y.suggestedMin = 990;
$config.options.scales.y.suggestedMax = 1030;
$config.data.datasets[0].label = 'Garage Pressure';
$config.data.datasets[0].unit = ' hPa';
$config.data.datasets[1].label = 'Office Pressure';
$config.data.datasets[1].unit = ' hPa';
$config.data.datasets[2].label = 'Air Things Pressure';
$config.data.datasets[2].unit = ' hPa';
$config.data.datasets[3].label = 'AWS Pressure';
$config.data.datasets[3].unit = ' hPa';
$config.data.datasets[4].label = 'Average Pressure';
$config.data.datasets[4].unit = ' hPa';
//$config.data.datasets[5].label = 'Average';
//$config.data.datasets[5].unit = ' hPa';
// Null out implausibly low pressure values so they do not affect graph scaling.
$config.data.datasets.forEach(function(ds) {
if (!ds || !Array.isArray(ds.data)) return;
ds.data = ds.data.map(function(p) {
// Case 1: simple numeric data array
// Example: [1013.2, 1013.4, 25.5, 1013.1]
if (typeof p === 'number') {
return p < MIN_VALID_PRESSURE_HPA ? null : p;
}
// Case 2: numeric values stored as strings
if (typeof p === 'string') {
var n = Number(p);
return n < MIN_VALID_PRESSURE_HPA ? null : p;
}
// Case 3: Chart.js object points
// Example: [{x: time, y: 1013.2}, {x: time, y: 25.5}]
if (p && typeof p === 'object' && 'y' in p) {
var yNum = Number(p.y);
if (yNum < MIN_VALID_PRESSURE_HPA) {
return Object.assign({}, p, { y: null });
}
}
return p;
});
ds.spanGaps = CONNECT_ACROSS_BAD_VALUES;
});
Have been wanting to use straight line segments between points, instead of the interpolated lines.
Google Search AI gave me this configuration:
$config.options.elements = {
line: {
cubicInterpolationMode: 'monotone'
}
};
Works great....