Repository navigation
Merge #38–#52 for 0.6.0 - #53
Merged
Merged
Conversation
The airline showcase build found three height disagreements on 6.1.0. The grid
model was already shared; the questions asked of it were not.
- size.table-window passed a table showing half its row_limit
(table_visible_ratio 0.5) while smoke warns when any returned row hides, so a
25-row table at 13 units passed advise and failed smoke. The ratio is 1 for
every audience and the target is every row, the number smoke gives once the
data fills row_limit.
- size.pivot-window read row_limit as the pivot's rows ("~0 of 1000 rows",
raise to 331). row_limit caps records (rows x columns); a pivot draws a row
per distinct row key. Offline the rule now checks only what the spec fixes
(frame, header rows, totals row, first row) and reports without a fix; under
--profile size.grid-fit counts the row dimensions and owns the chart, and
table-window leaves probed tables to it too.
- Smoke's pivot estimate was already right after the calibration (9 units for
5 rows and a totals row); the old "5.7 header units" bundled the totals row
and scrollbar allowance. Messages now name each part.
spec.grid_fit is the one estimate every consumer calls. pivot_axes, pivot_frame,
pivot_rows and pivot_rows_from_counts follow 6.1.0's PivotTableChart.tsx and
react-pivottable: transpose, metrics laid out as rows, row_subtotals and
pivots without row dimensions are counted, where smoke counted `rows` for all
of them. A table's show_totals row now takes a body row (checks and the
page-length fill), and smoke queries a table or pivot with the compiler's
row_limit default rather than 1,000.
Design brain 8. tests/test_grid_rows.py checks that table-window and smoke,
and grid-fit and smoke, warn together and name the same height.
Found live on 6.1.0: a required single-select Carrier filter (default "All carriers") scoped to 88 charts, over tables holding one row set per carrier. Smoke queried every chart unfiltered, so a 9-row status table counted 20 rows (its row_limit) and smoke told 30+ charts to grow while the dashboard fit; the same counts can call a chart empty, or not, wrongly. Smoke now adds, to each chart in a filter's scope whose dataset has the filter's column, what the dashboard applies on load: a select's default (NOT IN under inverse selection), a range's bounds, a time range (bound like the chart, overriding its own) and a time grain on a time axis. default_to_first is read with one small query shaped like the Select filter's (column, ordered by itself or sort_metric per sort_descending, its pre-filter and its parents' defaults), taking the first row as the plugin does. A time column default, or a first value smoke can't read, is named as not applied. Verified against the 6.1.0 source (getFormDataWithExtraFilters.ts, buildQueryObject.ts, Select/buildQuery.ts, SelectFilterPlugin.tsx, helpers.py's column-name filter check, same check in 4.1.4 and 5.0.0). Each result says which defaults it ran with; the apply report lists them under a new filter_defaults key, present only when there are some, so other reports are unchanged. Compile output is untouched.
A sketch legend symbol can now stand for a header block
({"header": ..., "size": ..., "background": ...}) or a markdown block
({"markdown": ..., "height": ...}) as well as a chart name, so a tab drawn
as a sketch can carry section titles and captions.
- A header is one sketch line. Drawn across the whole sketch it compiles
to a HEADER between rows, as a header row does; anywhere else it sits
in a COLUMN, stacked with the charts it shares a slot with or alone in a
column of its own. Superset nests a header in a grid, tab or column,
never in a row (dashboard/util/isValidChild.ts :75 and :97 at 4.1.4,
5.0.0 and 6.1.0).
- A markdown block is drawn like a chart: the drawing sets its width and
height, and its own height in fifths wins over the drawn one. A width
on a legend block is refused.
- Decompile reads headers and markdown in a section of stacked charts
back into its sketch instead of flattening the columns. It now draws
stacks with offset boundaries where the even drawing would let the
parser cut the band, which also keeps two columns of two charts as one
row. A drawing the parser refuses falls back to rows, named.
- plan normalizes sketch blocks as rows does; the design model reads a
slot of blocks as markdown and skips header bands, as in rows.
- Chart-only sketches compile to the same bytes (pinned by hash).
- Layout guide section with a compiled example and image, a test that
every guide example compiles, schema, FEATURES, CONTRACTS, SKILL,
VERIFICATION and CHANGELOG.
Verified live on 4.1.4, 5.0.0 and 6.1.0: a sketch with a header band, a
header and a note in columns, side-by-side headers and a footnote, flat
and in sub-tabs, imports, renders, decompiles with no losses and plans
clean.
…big-number dates Four display options on existing chart types, each verified in plugin source at 4.1.4, 5.0.0 and 6.1.0 (and 6.0.0 for since-releases): - Mixed chart: a query's `kind` can be "area", a line series with "Area chart" ticked (seriesType line + area/areaB), with `opacity` (opacity/opacityB) for the fill. The edge line stays at full strength, so opacity 1 gives a filled area with no visible outline; a line draws over an area in either query order (seen live on all three releases). - Trendline KPI: `rolling_type` (sum, mean, std, cumsum), `rolling_periods` and `rolling_min_periods` write the panel's rolling window (rolling_type, rolling_periods, min_periods). The number and compare_lag read the rolled series, so a 12-step sum with compare_lag 12 compares a trailing year with the year before. min_periods defaults to the window, so every point is a whole window. - Heatmap: `x_order` (left to right) and `y_order` (top to bottom), each a_to_z, z_to_a, value_asc or value_desc, write sort_x_axis/sort_y_axis. The y axis is a bottom-up category axis, so y_order is reversed when compiled; omitted fields compile to the alpha_asc both axes always had. A value order ranks by each label's total only from 6.1.0 (sortAxisValues); check warns for it on older releases. - Big number: `date_format` writes time_format and ticks force_timestamp_formatting, so MAX(<date column>) shows as "Sat 3 Oct 2026" and a number of epoch milliseconds as a date. All four compile only when set (goldens unchanged), decompile back with written defaults read as unset, and plan reports UI changes. Version gate: a heatmap value order warns before 6.1.0; nothing else needs a release. Design brain version 9: data.rolling-window-span warns when a rolling KPI's time range (or a defaulted dashboard time filter it loads with) can't hold its window and comparison, and smoke warns from the real bucket count; default.compare-suffix writes "vs prior 12 months" between trailing windows; default.date-tile fills date_format on a big number of a date column's MIN or MAX when the column type is known; ordinal-order leaves value-ordered heatmap axes alone; no number format is offered to a date tile, by the brain or a standard. Decompile also stops naming a mixed chart's untouched query B defaults and a trendline's untouched Force date format as losses, and reads the old echarts_timeseries_* series types, which Superset draws as a line, as kind line. The display-controls fixtures (offline and live) carry every new field, so params_drift and the live CI job cover them. Verified live on 4.1.4, 5.0.0 and 6.1.0: apply, re-apply id stability, plan clean, no decompile losses, and screenshots of each look.
… check that the steps add up A waterfall (Superset's Waterfall plugin): x_column holds the steps, metric the one measure they add, Superset adds the closing total. The three bar colours take green, amber, red or #RRGGBB and replace Superset's stock ones on every release; values on the bars, the legend, number format, axis titles, tick rotation and a time grain complete it. Compiled, decompiled (with Superset's stored defaults read as unset), compared by plan and queried by the data check on 4.1.4, 5.0.0 and 6.1.0. On 6.1.0, steps lists a bridge's values in its own order, opening first, and closing names the row that closes it. The compiler orders the bars by an x axis it writes (a CASE giving each step a key, the closing its own name), with the step column as the breakdown and show_total off; older releases draw a running total after every step, so check, apply and plan refuse steps there, and the 6.1.0 labels warn. The data check names a bridge's missing rows, values steps doesn't list, and a closing row that doesn't equal the steps added up. Seen rendering on 6.1.0: in order, the colours applied, the closing grey under its own name; plan clean. The opening rises from zero in the increase colour: the plugin's value axis keeps zero only while the first bar is a step (scale: true, no bounds control), and drawn as a total the opening floats the axis and disappears. Design brain 9: chart.waterfall-additive, -order, -colors, -axis-titles and -steps, the value-label and count-format fills for waterfalls, and a chart-choice guideline. The params contract's waterfall entry is extracted from the plugin source by tools/extract_panel_contract.py; tools/ci_live_waterfall.py builds a bridge in CI. Also: plan reads a trend_color written as a named shade's hex as equal to the name decompile reads back, so the chart no longer shows as changed after every apply.
… zero on the axis opening names the row that opens a bridge (with steps and closing, Superset 6.1.0): both ends are drawn as totals in the total colour under their own names, the steps between them in order. The plugin's value axis lets go of zero (scale: true, no bounds control), which cut an opening total away; a 6.x theme's ECharts override (echartsOptionsOverridesByChartType.waterfall.yAxis.scale false) keeps it. So the spec needs dashboard.theme, and check and apply read that theme's JSON on the instance and refuse opening without the override (waterfall_opening_axis). The x axis keys each step after the opening's name, so the opening must sort before the closing byte by byte and letter by letter (FY2025 before FY2026); the breakdown marks both ends Total. Decompile reads the opening back, and the data check names a missing opening row. Seen rendering on 6.1.0: a price-volume revenue bridge on the example sales data, FY2003 and FY2004 grey, the steps in order, plan clean. The CI live check builds an opened bridge and a plain one on 6.1.0.
…k that the boxes hold every observation A box plot (Superset's Box Plot plugin): distribute_across names the columns whose rows are the observations (a time column at time_grain: a day each), groupby the columns that get a box each, metrics the measure, and whiskers Tukey's, the lowest and highest values, or any two percentiles ([5, 95] works on every release: the select is free-form and the operator reads any 'lo/hi percentiles'). The compiler writes whiskerOptions even at Tukey, since without it the plugin adds no boxplot step, and temporal_columns_lookup for the time columns, which the grain needs. Compiled, decompiled, compared by plan and queried by the data check on 4.1.4, 5.0.0 and 6.1.0; the box plot in the featured-charts export reads back whole. row_limit is a 6.0.0 control: a 4.1.4 dashboard's query still stops at it, Explore's leaves it out (both seen live), so it warns before 6.0.0. The data check says when the observations reach the row limit, 10,000 unset on 6.x, so the boxes miss some. Design brain 9 also gets chart.box-plot-observations and chart.box-plot-groups, and chart.ordinal-order reads a box plot's groups and, with a profile, stands down for a column the dataset reports numeric or temporal. The chart-choice guide says when a distribution beats an average and a box plot beats a line of P50 and P90, and how to give the boxes one colour (dashboard.label_colors). Seen rendering on 4.1.4 and 6.1.0; on 6.1.0 a theme hides the plugin's stray "boxplot / outlier" legend. Also: decompile reads stored zoomable false and an empty series_limit as Superset's defaults, which Explore-saved time-axis, mixed and pivot charts carry.
…ed empty IN values Gaps a design review found while building a showcase dashboard, each checked in plugin source at 4.1.4, 5.0.0 and 6.1.0: - Trendline KPI: `y_axis_truncate` unticks "Start y-axis at 0" (start_y_axis_at_zero, BigNumberWithTrendline/controlPanel.tsx:96 at 4.1.4 and 5.0.0, :107 at 6.1.0), which the trendline reads as yAxis.scale: !startYAxisAtZero (transformProps.ts:219, :326 at 6.1.0). A trailing-12-month total that moved a few percent was a flat line over a solid block; fitted, it shows the movement. Omitted, it compiles to true as before, so the goldens are unchanged; decompile reads false back as the field and plan reports a change made in the UI. All three releases declare it: no version gate. - Design brain 10: no page-size picker, pager or search box on a table whose rows all show in its panel. Any page_length above 0 draws the picker, on one page too (hasPagination, DataTable.tsx:123, :173 at 6.1.0). default.search-box now fills only a raw table that pages, where the box sits in the picker's bar, and --fix removes a box it filled over rows that all show; size.table-chrome, a new info rule, names an author's page_length or search_box there. - Apply's data check names the values a chart's IN filter lists that return no rows, on a column the chart groups or draws by (a line chart listing four zones where two have data). A time column and a series-limited groupby are left alone, and a query that reached its row limit says so. No spec field where the plugin has no control, documented instead (spec descriptions, CONTRACTS.md, the chart-choice guide): - A mixed chart draws every line solid at one width: transformSeries takes a line style only from its caller, and MixedTimeseries passes none for either query at any of the three releases. 6.1.0's ECharts Options replace the series list whole and a theme override styles every series, so neither reaches one series. A reference series goes in its own query with a pale label_colors colour. - The area chart declares a fill opacity (already `opacity`) but no line width; on 6.1.0 a theme's echartsOptionsOverridesByChartType can thin every area chart's edges (read from source, not tried live). - Line, bar, area and scatter charts have one number format for the value axis, the value labels and the tooltip; a `~` format such as ",.1~f" keeps the axis in whole numbers. A mixed chart writes query B's value labels in number_format_secondary whichever axis B sits on. Verified live on 4.1.4, 5.0.0 and 6.1.0 with throwaway dashboards: apply, re-apply with stable ids, plan clean, decompile without losses, screenshots of each look and the data check naming an empty deal size. The display-controls live check passes on 6.1.0 with the fixture's new field.
…s spelled A 33-chart spec applied to 6.1.0 planned 28 charts changed straight after. Two causes: decompile rounded a chart height in fifths (4.6, as absorb writes) to a whole unit, and read the spec's SQL(MAX(col)) AS Label back as MAX(col) AS Label. Decompile now reads chart heights in exact fifths, as it already did for text blocks (compiler.spec_units, shared with absorb), and plan compares heights on the 8 px grid compile writes. The tool's own SQL aggregate reads back as written: every metric it writes carries the metric_sdc_ optionName, which Superset's popover keeps, so custom SQL typed in the UI still reads as the friendlier MAX(col) AS Label. The two spellings stay apart in plan because Superset stores them differently (a quoted column versus raw SQL). Siblings found by sweeping every field: plan now reads alike the spellings apply stores alike. Superset's own defaults written out join SUPERSET_DEFAULTS (time_range "No filter", number_format SMART_NUMBER and the mixed secondary, x_label_format smart_date, x_label_rotation 0, a table's date_format smart_date), each cited to the control at the three tags; a metric compares as decompile reads compile's payload for it (COUNT(*) AS N vs SQL(COUNT(*)) AS N, spacing around AS); a named shade's hex reads as the name; an empty table metrics or groupby list, a pre-filter over "No filter" and blank text read as unset. An aggregate spelled with spaces (SUM( qty )) now reads back as written, so a table's settings keyed by that label are no longer dropped. Tests: a respelled kitchen sink compiles, decompiles with no loss and plans clean; the soak mutator (and so the property round-trip test) writes fifth-unit heights and SQL(AGG(col)) metrics; the written-default cases compile byte-identically. ci_live_check now also asserts plan is clean after apply, and the live display-controls fixture writes fifth-unit heights and SQL aggregates, so CI checks both on 4.1.4, 5.0.0 and 6.1.0.
The showcase heatmap's hour axis couldn't read 00/06/12/18, and on 6.1.0 its row labels lost their first letter at the card's edge. HeatmapChart takes x_label_every and y_label_every (xscale_interval / yscale_interval, a label every Nth value from the first) and left_margin (px), the plugin's own controls at 4.1.4, 5.0.0 and 6.1.0, so no release gate; the x_label_every gate no longer warns for a heatmap. On 6.1.0 Heatmap.tsx renders Echart without vizType, so a theme can't reach it. Decompile reads them back (Superset's -1 and 'auto' as omitted, anything else named), plan reports a UI change, and bottom_margin stays a named loss: nothing was seen to need it. Design brain 12: default.heatmap-label-room fills left_margin 16 on every heatmap. Seen live on 6.1.0, 8 px cleared a 95 px label and 16 px a 150 px one; 4.1.4 and 5.0.0 drew them whole.
A showcase About tab cut its definitions off mid-section at 10 units and nothing
said so: Superset scrolls a markdown block's overflow inside the block, and macOS
draws no scrollbar there. advise now estimates each block's text height from its
markdown (headings by level, paragraphs and hard breaks, lists tight, loose and
nested, GFM tables, quotes, code, rules, <br>) and its width, and compares it with
the block.
- chartwright/design/markdown_fit.py: the estimate. Type sizes, margins, Inter's
character widths and the grid widths (1536 px at a 1600 px viewport, 1276 or
1308 px beside the filter bar) measured on 4.1.4, 5.0.0 and 6.1.0; text wrapped
word by word, margins collapsed as CSS does. A low bound (never above any
release) decides; a high bound (never below, allowing for Windows scrollbars)
sizes the fix.
- size.markdown-fit (warn/info, fixable): warns when the low bound cuts letters
off on every release and says by how much ("it needs ~29.6 units at 12/12, has
10"); an info when only the last line or the padding reaches the edge. Covers
layout rows, tabs, sub-tabs, header and footer rows. No fix for a standard's
row, a block with an image, or past 100 units. Short strips under 2 units are
the same estimate: 32 px of padding plus the line's margins.
- layout.markdown-height fixes a one-line block to the height its line takes
(1.6 to 2.4 units) instead of 2, which cut a level-1 heading's padding off.
- Design brain 11.
- tools/record_markdown_fit.py records the calibration into
tests/fixtures/markdown_fit/measurements.json (17 texts, five widths, three
releases, plus renders with Windows-style scrollbars at three heights);
tests/test_markdown_fit.py checks both bounds against every measurement;
tools/ci_live_markdown_fit.py runs in the live CI job on every release.
Decompile reads hidden labels back in column_config's order, not the spec's, so a table hiding two or more columns (as a showcase siting table does, for two rule-only flags) showed as changed after every apply.
A stacked horizontal bar ("first four hours" + "beyond four hours") must rank by its total, and two side-by-side bars may need one order. BarChart.sort_by takes "total" (Superset's "Total value", SortSeriesType.Sum: x_axis_sort from 6.0.0, x_axis_sort_series at 4.1.4 and 5.0.0, both written) or a metric, drawn or not: x_axis_sort for sortOperator plus timeseries_limit_metric, so the query is ordered by it too and an undrawn one is queried as an extra metric but never drawn. With several metrics at 4.1.4 and 5.0.0, x_axis_sort_series null stops the plugin's name re-sort. Verified live on all three releases with plan clean; no gate needed.
Sibling found and documented: without sort_by, several series read in name order (two stacked metrics on 4.1.4 and 5.0.0, a grouped bar everywhere); the guideline now says to use sort_by "total". The default compile output is unchanged.
Spec refuses sort_by with category_sort or contribution, "total" on one series, and a metric with a groupby (sortOperator skips a groupby). Check resolves the sort metric, smoke queries it, decompile reads both forms back and names min/max/avg rankings and smallest-first ones. data.top-n-sort warns when a row_limit cuts a bar ranked by "total"; chart.ordinal-order leaves a sort_by bar alone.
A formula annotation is y = f(x), so a threshold on a horizontal bar (1.0x, 4 hours, 2019 = 100) needed checking. Superset draws it on the value axis there on every supported release: transformFormulaAnnotation maps each point to [y, x] on a horizontal chart (Timeseries/transformers.ts 4.1.4 :381-383, 5.0.0 :387-389, 6.1.0 :482-484), so the line stands upright at its value. Seen live on 4.1.4, 5.0.0 and 6.1.0. The compiler already wrote the same layer for either orientation; this says so in the spec's field descriptions and the docs, adds a compile and round-trip test, and has the live CI fixture build one (a 1M target over a horizontal bar ranked by a hidden metric).
…ease The design asked for a ghost line lighter than the ink line, in weight or dash. MixedTimeseries offers each query a series type, stacking, an area fill and its opacity, values, markers and an axis (controlPanel.tsx createCustomizeSection at 4.1.4, 5.0.0 and 6.1.0), and transformProps passes neither query a line style. The one-query Timeseries chart dashes time-comparison series only, and 6.1.0's ECharts Options replace the series array whole. No workaround is built: CONTRACTS, the MixedSeries schema text and the brief's guideline name the limit and the nearest forms, a pale label colour (dashboard.label_colors) or an annotation for a fixed level.
ECharts steps a category axis from index 0, which on a heatmap's y axis is the bottom label. With y_order a_to_z the first label is on top, so a step of 6 on 24 hours labels 23, 17, 11, 05; found on a showcase heatmap.
Dashboards that set their markdown's text sizes in CSS were estimated with Superset's own sizes, so the rule missed both ways: a long block a few lines over went unreported, a small footer that fits got a warning, and captions set smaller than Superset's text were under-estimated. - markdown_fit.py now reads the spec's dashboard.css and applies it in cascade order (!important, specificity, source order) over Superset's own styles, written as CSS per release: rules on .dashboard-markdown and its elements, with descendant, child, + and ~ combinators, :first-child and :last-child, for font-size, line-height, font-weight, letter- and word-spacing, margins, padding, borders and border-spacing (px, em, rem, %; unitless line heights). Measured on every release: every .dashboard-markdown rule beats Superset's, except an h6's font size and h4-h6 weight, which the markdown component sets in its own class; heading and body line heights are factors. - The layout is now an element tree with CSS margin collapsing (li margins, p:last-child), line boxes from their inline text (a smaller <em> in a line), inline font sizes and padding (em, code) in the widths, measured Inter widths for Latin-1 and common symbols, and wide/narrow guesses for the rest per bound. - CSS it can't read that could size markdown (another font family, attribute selectors and pseudo-elements, @media, var(), a percentage margin, the block's padding, class-less rules) is named in the finding instead of the old blanket "assumes Superset's default" caveat; a theme is still named. - The rule assumes a 1440 px window (wider windows wrap less, so the fix holds there too), estimates only the releases the spec can go to (a theme leaves out 4.1.4 and 5.0.0, so a horizontal filter bar sits on top), and lets a block run under half a px over, since scrollHeight is whole px. - The fixture now holds both windows, a styled sales-review dashboard's 14 blocks under its own CSS, 570 elements' computed styles (no CSS, every property on every element, the styled dashboard's CSS) and verify passes for corpus and styled blocks at 1440. Tests check the cascade against every computed style and both bounds against every height; the live CI check covers the styled blocks too.
conditional_formatting on big_number_total: rules with the operators, thresholds and colours of table and pivot rules colour the number itself, e.g. a balance-closure KPI in red outside +/-2% and green inside. The number is text, so a named colour takes its darker text shade; a hex is used as written. Superset 4.1.4, 5.0.0 and 6.1.0 all declare the control (BigNumberTotal/controlPanel.ts) and paint the number solid from every rule whose column is set, so no release is gated. The compiler writes the metric's label as the column, as the panel does. A rule may name the chart's own metric (read as omitted) and no other; apply_to and paint are refused, and so are rules on big_number_trend, which has no colour rules in any release. Decompile reads the rules back (text shades as names, other hexes as themselves; a 6.1 theme token or an operator the spec lacks is a named loss), and rules left on a chart switched to the trendline are no loss, since it never draws them. Apply's data check warns when a coloured number is exactly 0, which Superset never colours. Design brain 14: chart.format-bands checks a big number's rules for overlap (a lone band is fine on a KPI) and no longer reads an '=' rule as everything above its target; chart.color-contrast (warn) flags colours too pale to read on the white card (3:1 for a big number or trendline, 4.5:1 for table and pivot text); narrative.kpi-thresholds (info) asks a coloured KPI to state its thresholds in its subtitle or description. The display-controls fixtures gain a coloured KPI, so params drift and the live CI job cover the field on every release.
A table's bars can now go on the columns whose size is the point. cell_bars takes a list of labels as well as true or false; color_by_sign colours bars green above zero and red below (Superset 6.0+; 4.1.4 and 5.0.0 colour only negative bars), for the whole table or the labels listed; absolute_bars sizes bars by absolute value from the cell's left edge (Superset's Align +/-). A list turns Superset's table-wide switch (show_cell_bars, color_pn, align_pn) off and each listed column's own (showCellBars, colorPositiveNegative, alignPositiveNegative in column_config) on, declared at 4.1.4, 5.0.0 and 6.1.0. color_by_sign true and absolute_bars false are Superset's defaults and compile as omitted, so specs without the fields build the same bytes. Colour and alignment draw on a bar, so each label they list must have one. decompile reads any mix of table-wide and per-column values back as Superset draws it, and plan reports a switch changed in the UI. check, apply and plan warn when a table asks for bars beside colour rules before 6.1.0, which draws no cell bar on a table with any colour rule. The default.cell-bars fill stands down when a sign switch asks for bars, and the brief points at the per-column form. Sibling fixes: plan compared a table's hidden labels in order, so a list written in another order than decompile reads back showed the table as changed after a clean apply; decompile reported the values an untouched table stores (HTML rendered, columns fixed, client-side paging, no percentage metrics, colour by sign on) as settings it could not carry. Verified live on 4.1.4, 5.0.0 and 6.1.0: applied, plan clean, decompiled without losses, screenshots match the source reading; the extended display-controls fixture passes the live check on all three.
…ently A table's apply_to and the table and pivot text paint take effect only on 6.1.0: the 4.1.4, 5.0.0 and 6.0.0 plugins read none of the rule keys 6.1.0 added, so apply_to painted the tested column, and text paint filled the cell with the dark text shade under dark text (3.0:1 on a table, 1.0:1 on a pivot). GATED_FIELDS now warns for both, naming what the older release draws, in check, apply, plan, compile --superset-version and the MCP tools. Warnings, not errors: the dashboard imports and saves, and an error would keep a multi-release spec off the older instances. Sibling sweep, each verified at the tags and live on 4.1.4, 5.0.0 and 6.1.0: - solid bands (useGradient) are read from 6.1.0 only; older releases fade every rule but '=' toward its threshold: conditional_formatting warns; - 6.1.0 turns a painted cell's text white on a dark fill; older releases keep their dark cell text: color warns for a cell-painted hex under 3:1; - hidden table columns show before 6.0.0: hidden warns. Colour rules take >=, <=, != and between_inclusive, comparators every release has; decompile reads them back from rules made in the UI, and names a rule 6.1's popover saved with its gradient on. plan no longer reports drift when a rule's colour is a named shade's own hex. Design brain 16: chart.format-bands reads each operator's range, so '=' is one value and inclusive bounds count.
…g-number text advise never checked type size, so dashboards shipped Superset's 12 px table cells and big-number subtitles drawn at 8 px. Three rules (design brain 13) judge text against floors for reading on a 1440 px laptop, from IBM Carbon's and Material's type scales and the critical print size of reading research (docs/DESIGN-BRAIN.md sec.17, "Type sizes"): - readability.table-text: table and pivot cells 14 px, headers 12 px, rows 24 px. - readability.chart-text: axis labels and legends 12 px, chart titles 14 px. - readability.kpi-text: a big number's value 24 px, its subtitle or comparison 12 px. Superset sizes them by the card's height, so --fix raises the card (and the cards beside it) to 5 units with a subtitle or 6 for a trendline's comparison. Superset's own default under a floor is an info naming the selector or token to set; text the dashboard's CSS or theme sets under it is a warn. A minimal CSS reader applies a declaration only where it beats Superset's own rule on that release, and names what it can't place; check and advise --profile read the named theme's tokens (json_data from the theme list) and ECharts overrides. No fill writes CSS (sec.14.18). The floors are parameters design.yaml and a standard can tune or lock. tools/record_readability_measurements.py measured what 4.1.4, 5.0.0 and 6.1.0 draw under six stylesheets and for big numbers at heights 2 to 10; the offline suite holds the model to that fixture, and the live CI job re-measures with --check.
Superset lays a bar chart's axis titles out for a vertical chart and then swaps the axes (Timeseries/transformProps.ts 4.1.4 and 5.0.0 :530-531, 6.1.0 :993-994). The value title, placed Top, landed past the bottom axis's right end and was cut off; the category title sat 30 px from the axis line, inside the category labels. Horizontal bars now place the value title Left (centred under the bottom axis, 30 px clear) and give the category title a 64 px gap.
chart.axis-titles (info) notes an axis chart with no y_axis_title or no x_axis_title. layout.thin-subtabs (info) notes a sub-tab holding two charts or fewer besides its KPIs. The value-label default now covers grouped bars, counting rows times metrics against the same limits. The brief tells authors to title every axis and to keep thin sub-tabs on their parent page; the shipped example now titles its axes.
…xis order, big-number dates
…t show, named empty IN values
…or metric is spelled
…or metric is spelled
…lds on horizontal bars
…lds on horizontal bars
A big number's rule colours the number, which is text, so a named colour paints its text shade and decompile reads that shade's hex back as the name. Plan's colour canonicalisation picked the shade by the rule's paint, which a big number's rule doesn't have, so it used the cell shades: a rule written as #B3261E showed as changed after every clean apply, and one written as #EFA1AA read as unchanged when switched to red, which paints #B3261E.
…draw differently
…hart and big-number text
…es, and fixes horizontal bar titles
This was referenced Oct 6, 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.
Merges the fifteen open pull requests #38–#52 into main in one step, in PR-number order. Each merge has its own commit ("Merge #NN: …"), and GitHub marks every PR merged when this lands. The version bump and the consolidated CHANGELOG follow in the release PR.
How it was built
The integration branch is the baseline.
showcase/integrationalready merged fix: advise and smoke ask one height question of tables and pivots #38–feat: readability floors in the design brain, for table, chart and big-number text #51 in this order. It resolved every conflict there:It passes 2416 tests and the live showcase dashboard runs on it.
Replayed onto main. Integration's history was replayed onto a fresh branch from main, and every step matches integration's tested tree exactly (
git diffempty at each of 18 steps).feat: design brain 8 asks every axis chart to title its axes, and fixes horizontal bar titles #52 merged on top. Its conflicts were resolved by hand: Design Brain 17, its rules
since="17", and four brief lines tightened so all three briefs stay within 150 lines (148, 150, 149).Checks
params_drift --allis clean on 4.1.4, 5.0.0 and 6.1.0.chart.color-contrastandnarrative.kpi-thresholdsare intact);hiddensort, replaced by feat: per-column cell bars, sign colours and absolute bars on tables #49's column-order sort;_markdown_heighthelper;docs/FEATURES.mdlisted chart types twice ("15" and "17"). Fixed in the last commit.Not in this PR
examples/sundown/.