Add Indicator, Histogram2d, Icicle trace types + layout uirevision (#422)#423
Open
jqnatividad wants to merge 14 commits into
Open
Add Indicator, Histogram2d, Icicle trace types + layout uirevision (#422)#423jqnatividad wants to merge 14 commits into
jqnatividad wants to merge 14 commits into
Conversation
Replaces the three vendored plotly.min.js copies (plotly, plotly_static, docs/book) with v3.7.0 and bumps the pinned CDN version strings in plot.rs, the jupyter notebook template, plotly_static template, and the book header. Closes plotly#419 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Align the example CDN references with the newly bundled 3.7.0. The wasm-yew examples were pinned at 2.14.0, and multiple_plots_example used plotly-latest.min.js, which the CDN freezes at v1.58.5 (2021) — a 1.x runtime against a library that now emits 3.x JSON. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The scatter_geo, scatter_map, and scatter_mapbox modules each defined a byte-identical Selection/SelectionMarker pair. Move the single definition to crate::common and re-export it from each module (pub use) so the public paths plotly::traces::scatter_geo::Selection etc. keep resolving — no serialized-output change, all existing trace tests pass unchanged. This is the shared building block for backfilling selected/unselected styling onto the older cartesian traces. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Bring the older trace types up to plotly.js 3.7.0 parity on the common "universal" attributes that the newer traces already expose: - legendrank, legendwidth, uirevision on Scatter, Bar, BoxPlot, Violin, Histogram, HeatMap, Contour, Candlestick, Ohlc, Scatter3D, Surface, ScatterPolar (Scatter3D already had legendrank). - uirevision only on Sunburst, Treemap, Table (these do not participate in the legend, so legendrank/legendwidth do not apply). - offsetgroup/alignmentgroup on Scatter (Bar/BoxPlot/Violin/Histogram already had them). All fields are additive Option<T> with serde renames; existing tests pass unchanged. Contour uses a hand-written builder (no FieldSetter derive), so its fields, Default impl, and setters were added by hand. Added focused rename-guard tests for Scatter and Contour. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add plotly.js interaction/layering attributes to the cartesian traces that lacked them, reusing the shared common::Selection struct: - selected, unselected, selectedpoints on Scatter, Bar, BoxPlot, Histogram. - selectedpoints only on Candlestick and Ohlc (finance traces expose the selection array but not selected/unselected marker styling). - zorder on Scatter, Bar, BoxPlot, Histogram, HeatMap, Contour, Candlestick, Ohlc (SVG draw order; Violin already had it). Additive Option<T> fields with serde renames. Contour (hand-written builder) got its field, Default entry, and setter by hand. Extended the Scatter and Contour rename-guard tests. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add a PeriodAlignment enum to common and the plotly.js period-positioning attributes to the cartesian traces that support them: - xperiod/xperiod0/xperiodalignment and yperiod/yperiod0/yperiodalignment on Scatter, Bar, BoxPlot, HeatMap, Contour. - x-period only on Candlestick and Ohlc (x is the date axis for finance traces; they have no y-period). Histogram is intentionally excluded (it bins raw data via xbins and has no period attributes). Additive Option<T> fields; Contour's hand-written builder got fields, Default entries, and setters by hand. Extended the Scatter rename-guard test. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Expose plotly.js scatter fill styling beyond a solid fillcolor: - fillpattern reuses the existing common::Pattern struct. - fillgradient uses a new common::FillGradient struct (type/start/stop/ colorscale), distinct from the marker-oriented common::Gradient. Additive Option<T> fields on Scatter; extended the rename-guard test. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
These hierarchy/table traces lack a `showlegend` attribute but DO expose `legendrank`, `legendwidth`, `legend`, and `legendgrouptitle` in the plotly.js 3.7.0 schema, so they participate in the legend. The initial backfill wrongly gated legend participation on `showlegend` presence and gave them `uirevision` only. Verified against the authoritative plotly.js 3.7.0 plot-schema.json. Adds rename-guard tests for the three traces.
… uirevision (plotly#422) Add three new trace types and the layout-level uirevision attribute, with field names verified against the plotly.js v3.7.0 plot-schema.json. - Indicator: KPI number/delta/gauge displays (Gauge, Delta, Number config) - Histogram2d: 2D histogram heatmap (histfunc/histnorm/nbinsx/nbinsy/xbins/ ybins), reusing histogram's Bins/HistFunc/HistNorm and heat_map's Smoothing - Icicle: hierarchical icicle chart (sibling of Treemap/Sunburst) - layout.uirevision: preserve UI state (zoom/pan/selection) across re-renders, complementing the trace-level uirevision added in plotly#421 Includes PlotType variants, re-exports, exact-JSON round-trip tests, doctests, and CHANGELOG entries. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Replace the minimal GaugeAxis (range + a few ticks) with the complete set of 27 attributes plotly.js exposes on indicator.gauge.axis: tick mode/placement (tickmode/nticks/tick0/dtick/tickvals/ticktext), tick styling (ticks/ticklen/tickwidth/tickcolor/tickangle/tickfont), label controls (showticklabels/tickprefix/ticksuffix + their ArrayShow flags), exponent and number formatting (showexponent/exponentformat/minexponent/separatethousands/ tickformat/tickformatstops/ticklabelstep), and labelalias. Reuses existing enums (common::TickMode/ExponentFormat/TickFormatStop, layout::ArrayShow/TicksDirection) rather than layout::Axis, which carries ~70 attributes (grid lines, spikes, range sliders, subplot anchoring) that a gauge axis does not support and would silently serialize as ignored JSON. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
histogram2d `z` is a data_array ("aggregation data") aligned 1:1 with the
`x`/`y` samples and aggregated per bin via `hist_func` — not a pre-binned 2D
matrix like `heatmap.z`. Reword the struct and `new_xyz` docs accordingly
(directing pre-computed matrices to `HeatMap`), and replace the matrix
round-trip test with an aligned 1D aggregation example using `hist_func(Sum)`.
Addresses roborev review job 3598.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
gauge.axis.ticks accepts "outside", "inside", or "" (disabled). TicksDirection only covers inside/outside, so "no ticks" was inexpressible. Switch to common::Ticks (Outside/Inside/None -> "outside"/"inside"/"") and add a test that Ticks::None serializes to "". Addresses roborev review job 3599 (the tickmode finding in that review was a false positive: the v3.7.0 schema lists gauge.axis.tickmode as ["auto","linear","array"], so TickMode::Auto is valid). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
jqnatividad
added a commit
to dathere/qsv
that referenced
this pull request
Jul 11, 2026
…y.rs #423) (#4184) * feat(viz): KPI overview row, icicle charts & layout uirevision (plotly.rs #423) Adopt dathere/plotly branch `feature/trace-type-additions` (PR plotly/plotly.rs#423, a strict superset of the prior pin) and use the new API in `viz`: - viz smart now leads with a full-width KPI overview row of plotly `Indicator` tiles: a built-in completeness gauge plus the headline numeric measures (sum for extensive, mean for intensive). A measure becomes a gauge when the data dictionary supplies a validated `x-qsv.gauge_range` (drawn only when the range actually contains the observed value; a range also forces the mean so it lands in-scale) and a "vs target" delta when it supplies `x-qsv.target` (a semantically-justified goal, never a fabricated prior-period baseline). Renders in both the inline and typed-grid paths and stays invisible to --max-charts, the panel-count notices, and the render-path thresholds (it is a domain band, not a cartesian subplot). HTML-only. - Add `viz icicle` subcommand and `--hierarchy-style icicle`, a level-aligned sibling of treemap/sunburst. - Set layout-level `uirevision` centrally in apply_theme so user zoom/pan/ selection/legend state survives the Plotly.newPlot re-renders that inject the fullscreen modebar button and recolor on theme toggle. describegpt emission of gauge_range/target is deferred; until then the hints are consumed from any dictionary that carries them, with completeness + number tiles working with no dictionary. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(viz): don't orphan the 8th cartesian axis behind the KPI row (roborev #3602) The leading KPI row is domain-positioned and consumes no cartesian axis, but it still occupies panel index 0 in `smart_grid_parts`, so `pos = n + 1` labelled the cartesian panels behind it x2..x9. With exactly MAX_SUBPLOTS (8) cartesian panels on the typed-grid path the 8th chart landed on x9, which the typed `Layout` (x1..x8) has no slot for — `assign_typed_axis` silently drops it, orphaning the trace onto the default axis. Subtract a one-slot `axis_offset` when the leading panel is the KPI row so the cartesian axes number x1..x8. The KPI row and geo panels never coexist in this assembler (geo forces the inline path for HTML; image exports carry no KPI row), so a single leading offset is sufficient. Adds a regression test that drives the exact 8-cartesian-panel boundary via `--max-charts 8`. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs(viz): regenerate gallery with KPI overview row & add icicle showcase The smart dashboards now lead with a KPI overview row (completeness gauge + top-measure number tiles); regenerated the 7 affected smart_*.html figures so they reflect it. Added a dedicated `viz icicle` example to gen_gallery.py so the new chart type is showcased (gallery is now 38 figures). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs(viz): correct icicle default-orientation comment; document pre-gen KPI-row lag (roborev #3604) The icicle code comment claimed a top-down default, but plotly leaves tiling.orientation at horizontal ("h") — root on the left, children fanning right (confirmed in plotly.rs Tiling docs + live render). The gallery description was already accurate; fixed the misleading code comment instead. Also documented, per developer deferral, that the LLM-dependent pre-generated dashboards intentionally lag the KPI/Completeness row until describegpt emits the gauge_range/target dictionary hints and they can be regenerated in one pass. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This was referenced Jul 12, 2026
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.
Implements the four additions from #422, field-verified against the plotly.js v3.7.0
plot-schema.json.What's added
Indicator— KPI number / delta / gauge displays, withMode(number/delta/gauge flaglist),Number,Delta/Direction, and a fullGauge(GaugeAxis,GaugeBar,Step,Threshold).Indicator::new(value)sets onlyvalue, leavingmodeto the plotly.js default (consistent with sibling constructors).Histogram2d— 2D histogram heatmap. Reuseshistogram::{Bins, HistFunc, HistNorm}andheat_map::Smoothing; addshistfunc/histnorm/nbinsx/nbinsy/xbins/ybins/autobinx/autobiny.new(x, y)bins raw samples;new_xyz(x, y, z)takes a pre-computed matrix.Icicle— hierarchical icicle chart (sibling ofTreemap/Sunburst), with icicle-specificTiling(reusingcommon::Orientation), a marker without treemap'spad/corner_radius/depth_fade, plusLeafandRoot.layout.uirevision— preserves UI state (zoom/pan/selection/legend visibility) acrossPlotly.react/newPlotre-renders, complementing the trace-leveluirevisionadded in Backfill common trace attributes for plotly.js 3.7 parity #421.Notes
GaugeAxiscovers all 27 meaningfulindicator.gauge.axisattributes (tick placement, styling, label/exponent/number formatting,labelalias,tickformatstops), reusingcommon::{TickMode, ExponentFormat, TickFormatStop}andlayout::{ArrayShow, TicksDirection}rather thanlayout::Axis— the latter carries ~70 attributes (grid lines, spikes, range sliders, subplot anchoring) that a gauge axis doesn't support and would silently serialize as ignored JSON.PlotTypevariants (Histogram2d,Icicle,Indicator) serialize viarename_all = "lowercase"; re-exported fromtraces/mod.rsand bothlib.rslists.[Unreleased] → Added.Verification
cargo build -p plotly(default) and--features all— cleancargo test -p plotly --features all— 363 unit + 34 doc tests green (exact-JSON round-trips for each new trace, plus a layoutuirevisiontest)cargo clippy -p plotly --features all --all-targets -- -D warnings -A deprecated— cleancargo +nightly fmt --all— appliedBrowser-render smoke test not run (no chromedriver in this environment); JSON correctness rests on schema-grounded field names + round-trip tests.
🤖 Generated with Claude Code