DuckDBTransport(quixviz.DuckDBTransport) — local SQL transport backed by DuckDB over parquet files. Implements the sameTransportprotocol asQuixClient, so charts swap in with no other changes. Pins the session toUTCand strips tz-aware datetimes so the output matches the HTTP/CSV transport regardless of host timezone.- Marimo state-driven zoom loop —
zoom_from_selection(value, set_win)helper inquixviz.notebooktranslates a plotly box-select payload into a new window viamo.state. Pairs withmarimo_chart(chart), which primes the figure for horizontal box-select zoom. - Offline LOD demo (
examples/demo_marimo_local.py) — marimo notebook over locally-generated synthetic telemetry. Slider runs in hours-from-start so handle labels stay readable; datetime range and bucket size shown in the readout. - Synthetic data generator (
examples/generate_demo_data.py) — writesdemo_telemetry.parquetwith layered 24 h / 1 h / 1 min / 1 s sinusoids plus noise across multiple drivers, so each zoom level reveals new structure. Default: 4.32 M rows at 50 Hz over 24 hours. [local]optional extra pulling induckdb>=0.10andpyarrow>=14..env.exampledocumentingQUIX_LAKE_URL/QUIX_LAKE_TOKEN.
- Axis misalignment by local timezone offset — the pinned x-axis
range was emitted as tz-aware UTC ISO (
…+00:00) while DuckDB'stime_bucketoutput landed as tz-aware UTC in pandas. The browser converted both to the host's local timezone independently, drifting the data away from the axis window by the local offset (most visible on BST machines as a ~1 h gap)._ms_to_axis_rangenow emits naive UTC ISO, andDuckDBTransport.executestrips tz from datetime columns so data and axis live in the same frame. PlotlyRenderer.updatenow acceptsx_range— pins the visible axis to the queried window. Without this, sparse data collapsed the axis to wherever rows happened to exist, hiding the fact that coarse zooms still returned the requested span.
- Secrets removed from example sources.
smoke_ac_telemetry.py,demo_marimo.py, anddemo.ipynbnow requireQUIX_LAKE_URLandQUIX_LAKE_TOKENenvironment variables instead of silently falling back to a hardcoded SDK token..ipynb_checkpoints/directory (which held stale copies) removed;.gitignorenow excludes it. - Marimo demo UX — slider runs in hours-from-start instead of raw
ms (handles render as
12.50not1.8e12); readout shows a full datetime range with bucket and point count. In-chart rangeslider / rangeselector disabled in the local demo so the top slider is the single zoom path (the in-chart ones are browser-only and can't refetch).
- The Plotly in-chart rangeslider is browser-side zoom only: no Python
callback, no refetch. In Jupyter,
attach_jupyterbridges in-chart zoom back viaFigureWidgetrelayout events. In marimo, usezoom_from_selectionfor the equivalent feedback loop.