Windowed live-data fetching + coordinated ECharts flush timers - #88
Merged
Conversation
Each mounted chart ran its own setInterval doing a full series rebuild + setOption every tick regardless of whether new data had arrived, so CPU cost scaled with timer frequency x plot count. Replace the per-chart timers with one shared driver, add a dirty flag so the expensive series rebuild only runs when data actually changed, and skip off-screen charts via a shared IntersectionObserver. The wall-clock xAxis slide still runs every tick so live charts keep visibly advancing in time.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Live plots previously fetched a parameter's entire value history on every load, then relied on the client to trim it down to the visible time window wasteful for parameters with long histories. This PR makes live-mode fetches window-aware end to end, and fixes a related client-side performance issue in the chart flush loop that was scaling badly with plot count.
Backend: window-aware live data fetching
Builders.fetch_param_data/2now takes amode. For:live, it fetches only the configured default time window (fetch_param_data_in_range/3) instead of full history;:historicalkeeps the old unbounded fetch.Builders.any_data?/1to distinguish "no data in the live window" from "no data ever recorded" without re-fetching full history, andBuilders.plot_available?/3to use that distinction when deciding whether a plot can render (a parameter with only old data outside the live window is still "available", just showing an empty chart).read_from_device_if_empty/2), preserving existing bootstrap behavior.config :secant_service, :plot_db(falls back to the previous hardcoded defaults), andBuilders.default_live_range_ms/0centralizes resolving the default window against the current time so the fetch path and each dtype's initial x-axis window can never disagree.Calibratable,Drivable,Readable,PlotDB) and dtype option builders (Scalar,Enum,Struct,ArrayHeatmap) updated to threadmodethrough and use the shared helpers instead of duplicating range-computation logic.Frontend: coordinate ECharts flush timers
Each mounted chart ran its own
setIntervaldoing a full series rebuild +setOptionevery tick, regardless of whether new data had arrived, so CPU cost scaled with timer frequency × plot count. This PR:ChartFlushDriverticking all mounted charts once a second._dataDirtyflag so the expensive part of a flush (trimming, series rebuild, heatmap visualMap recompute) only runs when data has actually changed since the last flush.IntersectionObserver(ChartVisibilityObserver) so fully off-screen charts skipsetOptionentirely; buffered data isn't lost, it's just not rendered until the chart is visible again._pointTs) and range-expansion backfill (_earliestBufferedTs) to handle both plain[ts, ...]points and enum's{value: [ts, y]}point shape, and to correctly trigger a backfill fetch even when a series has zero buffered points.