dashboard: pace a querying chart by its window, and an example to evaluate it
A chart is drawn in buckets, and nothing it can show changes until the bucket it is drawing closes — so the resolution sets the refresh rather than a flat five-second floor. A week at quarter-hour buckets now asks four times an hour instead of sixty, for the same picture. Leaving the field empty follows the window; a slower rate is still honoured. `make seed-example` builds the thing to evaluate it with: a flow that logs a temperature to InfluxDB, a flow that answers a chart's request by turning the window into Flux and the rows back into a series, and a dashboard holding the chart. The reading flow declares the request as an input with a starting value, which is how a flow says a value reaches it from a panel rather than from a node upstream. Axis labels keep enough decimals to stay distinct — `si` rounds to three figures, so every tick of a chart living inside one degree read "19". Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -20,12 +20,16 @@ export { MAX_SERIES }
|
||||
const DEFAULT_POINTS = 300
|
||||
|
||||
/**
|
||||
* How often a chart may ask, at the fastest.
|
||||
* How often a chart asks again, for the window it is showing.
|
||||
*
|
||||
* A refresh interval is a query someone else has to run, so the panel is not
|
||||
* allowed to set it to nothing.
|
||||
* A window is drawn in buckets, and nothing the chart can show changes until
|
||||
* the bucket it is drawing closes — so the resolution sets the pace. A week at
|
||||
* quarter-hour buckets asks four times an hour instead of twice a minute, for
|
||||
* the same picture. A slower refresh than that is honoured; a faster one only
|
||||
* buys the same answer again, so it is clamped.
|
||||
*/
|
||||
export const MIN_REFRESH_S = 5
|
||||
export const refreshFor = (range: Range, configured: unknown) =>
|
||||
Math.max(range.bucketS, Number(configured) || 0)
|
||||
|
||||
/** How long an unanswered request blocks an identical one. */
|
||||
const INFLIGHT_MS = 15_000
|
||||
@@ -197,8 +201,6 @@ function QueryChart({ widget, dashboard }: WidgetProps) {
|
||||
const cfg = config(widget)
|
||||
const request = String(cfg.request ?? "")
|
||||
const message = String(cfg.message ?? "")
|
||||
const refreshS = Math.max(MIN_REFRESH_S, Number(cfg.refresh_s) || 60)
|
||||
|
||||
const [range, setRange] = useState<Range>(
|
||||
() =>
|
||||
RANGES.find((r) => r.hours * 3600 === Number(cfg.range_s)) ??
|
||||
@@ -206,6 +208,9 @@ function QueryChart({ widget, dashboard }: WidgetProps) {
|
||||
)
|
||||
const rangeS = range.hours * 3600
|
||||
const intervalS = range.bucketS
|
||||
// Follows the window: a wider one is drawn coarser, so it is worth asking
|
||||
// about less often.
|
||||
const refreshS = refreshFor(range, cfg.refresh_s)
|
||||
|
||||
const publish = usePublishMessage()
|
||||
const live = useLiveValue(message || undefined)
|
||||
|
||||
Reference in New Issue
Block a user