Changes in version 0.99.3 - Selection reporting. Lasso selections are always reported (Shiny input$_selected plus a sp-selection DOM event for custom hosts); cross-plot selection mirroring is scoped to the syncPlots group. - In-plot toolbar (toolbarPosition = "left" / "top" / "none"): pan, lasso, zoom-to-selection, reset, screenshot. - zoomOnSelection auto-frames the lasso selection. - Encode size / opacity by data via sizeBy / opacityBy (a numeric column or vector). - Frosted-glass legend with legendOpacity / legendBlur, round colour dots and per-category counts. - Smoother panning - the d3 axis redraw is coalesced to one frame per view event. Changes in version 0.99.2 - Bundled example dataset. data(reglScatterExample) loads a small (3,400-cell) synthetic single-cell-style UMAP data.frame with a categorical cell-type column and a continuous marker gradient, so users can plot something immediately without downloading data or installing a Suggests package. Used by the examples, vignette and tests. - Seurat support. reglScatterplot() now dispatches on Seurat objects: coordinates come from Embeddings() (reduction matched case-insensitively, default "UMAP" with umap/tsne/pca fallback), and colorBy / groupBy resolve against meta.data columns or features via FetchData(). Works with both Seurat v4 (slot) and v5 (layer) objects. SeuratObject added to Suggests. - Plain matrix input. reglScatterplot(m) accepts a numeric coordinate matrix (e.g. a UMAP embedding or prcomp()$x), using the first two columns by default; x / y may select other columns by index or name. - Monocle3. A cell_data_set is a SingleCellExperiment subclass, so it flows through the existing SCE dispatch unchanged - now covered by a test and documented. - AnnData support. reglScatterplot() now dispatches on in-memory AnnData objects (from anndataR or the anndata CRAN package): coordinates from an obsm embedding (default "UMAP" -> "X_umap", matched case-insensitively), colorBy / groupBy resolved against obs columns or var_names features, with assay selecting the layer (X / a layer / "raw"). AnnData read via zellkonverter::readH5AD() continues to use the SingleCellExperiment path. anndataR added to Suggests. - filterBy now shows interactive distribution sliders outside Shiny. Each numeric filterBy column gets a mini histogram of its distribution with a dual-handle range brush; dragging the handles selects a range, dims the out-of-range bars and filters the points live. Previously the slider UI only existed when a Shiny app supplied it (the data was loaded but nothing showed). - Per-plot filter/legend state. Legend category toggling and filterBy ranges are now scoped to each plot instead of a page-global registry, so independent plots on one page (e.g. several widgets in a Jupyter notebook, which all share window) no longer filter each other. Shiny still broadcasts filters across a dashboard via its message handlers. - Legend dragging no longer stretches the box. A bottom-/right-anchored legend kept its far-edge anchor when dragged, pinning all four edges so it ballooned to full height. Dragging now re-anchors to top/left cleanly. Legend height also trimmed to fit its contents. - title is now drawn on screen. Previously the title argument only appeared in PNG/SVG/PDF exports; it now renders as a centred caption at the top of the plot (coloured with axisColor). - Client-side plot sync without Shiny. Passing the same syncPlots group to several plots now links their pan/zoom in plain HTML / R Markdown / the Viewer, not just in Shiny. Plots are now keyed by their logical plotId (previously the internal DOM id won, so a syncPlots group never matched and sync silently did nothing outside Shiny). Verified with a headless-browser test (js/test-sync.mjs). - Legend theming. The legend header background now follows legendBg (it was a fixed light strip that looked wrong on dark themes), and the header title text follows legendText instead of a CSS variable that RStudio's dark Qt theme could override to a near-invisible colour (the "white legend title" bug). The legend also has a hard height cap so it can't span the whole plot when the container height is indefinite (e.g. a knitted R Markdown). - Download button honours an explicit enableDownload = TRUE. The export button was hidden inside any iframe (RStudio Viewer, knitted-HTML preview, Jupyter); an explicit opt-in now always shows it. - Crisp rendering in the RStudio Viewer (pixelRatio). The widget now renders the WebGL backing store at max(devicePixelRatio, 2) by default instead of relying on window.devicePixelRatio, which the RStudio Viewer (an embedded browser) reports as 1 even on HiDPI screens - the cause of the previously soft / low-quality look in the Viewer. A new pixelRatio argument overrides this (e.g. pixelRatio = 1 to save GPU memory, 3 for export-quality sharpness); very large data (n > 500000) keeps the true ratio to bound the pixel count. - No CDN at runtime - the widget now works offline. All browser dependencies (regl-scatterplot, d3, pickr, html2canvas, jspdf) are bundled into inst/htmlwidgets/reglScatterplot.js with esbuild, instead of being fetched from esm.sh / cdnjs via dynamic import() and