Skip to content

feat(explore): drill-down hierarchy for ECharts charts#41907

Open
tomerkl65 wants to merge 13 commits into
apache:masterfrom
tomerkl65:feat/echarts-drilldown-hierarchy
Open

feat(explore): drill-down hierarchy for ECharts charts#41907
tomerkl65 wants to merge 13 commits into
apache:masterfrom
tomerkl65:feat/echarts-drilldown-hierarchy

Conversation

@tomerkl65

Copy link
Copy Markdown

SUMMARY

Adds a hierarchical drill-down interaction for ECharts charts. The chart author
defines an ordered list of columns in a new Drill-down hierarchy control.
On a dashboard, left-clicking a data point drills to the next level scoped to
the clicked value, shows a breadcrumb for navigating back up, and emits a
cross-filter for the full drill path so other charts stay in sync.

Design decisions:

  • Dedicated drilldown_hierarchy control — the x-axis control stays a
    single (scalar) column, so existing charts and all downstream query
    consumers are unaffected. No global multi change, no feature flag needed.
  • Full-path cross-filter — emitted centrally by the DrillDownHost (which
    owns the drill stack), so downstream charts are scoped to the entire path,
    not just the deepest clicked column.
  • Leaf selection narrows the drilled chart to the clicked value at the
    deepest level, consistently across charts.

Supported charts: Bar, Line, Area, Scatter, Smooth Line, Step (x-axis based)
and Pie, Funnel, Gauge, Radar, Box Plot (groupby based).

TESTING INSTRUCTIONS

  1. Create a Bar chart, set a single X-axis column, open Drill-down hierarchy
    and add the deeper levels; save and add to a dashboard.
  2. Click a bar → chart drills to the next level scoped to the clicked value; a
    breadcrumb appears.
  3. Confirm other dashboard charts are cross-filtered by the full path.
  4. Use the breadcrumb to navigate back up; verify the chart restores.
  5. Repeat with a groupby chart (e.g. Pie).

ADDITIONAL INFORMATION

  • Has associated issue:
  • Required feature flags:
  • Changes UI
  • Includes DB Migration
  • Introduces new feature or API
  • Removes existing feature or API
image

@dosubot dosubot Bot added change:frontend Requires changing the frontend dashboard:drill-down Related to drill-down functionality of the Dashboard viz:charts:echarts Related to Echarts labels Jul 9, 2026
@tomerkl65

Copy link
Copy Markdown
Author

This supersedes #40449, which I had to close and recreate — the branch was
force-pushed so GitHub wouldn't let me reopen it. The code here is the same
feature, cleaned up and rebased on current master.

@michael-s-molina @villebro @EnxDev — following up on the earlier review, this
branch addresses the feedback:

  • No global multi change. Reverted xAxisMixin to multi: false; the
    hierarchy is now configured via a dedicated drilldown_hierarchy control, so
    x_axis stays a scalar column and no downstream consumer (normalizeTimeColumn,
    operators, backend QueryObject) is affected. No feature flag needed.
  • Treemap/Sunburst removed from the supported set. Supported: Bar, Line,
    Area, Scatter, Smooth Line, Step, Pie, Funnel, Gauge, Radar, Box Plot.
  • Backend engine-listener fix dropped — it already landed on master
    separately.
  • Dead code removed — the unused DrillDownEvent type and options param
    are gone; cross-filter emission is consolidated in the host.
  • Breadcrumb uses native <button> (a11y) and theme spacing tokens.

@tomerkl65
tomerkl65 force-pushed the feat/echarts-drilldown-hierarchy branch from beb03aa to 6f70126 Compare July 9, 2026 13:39

@bito-code-review bito-code-review Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review Agent Run #6392bc

Actionable Suggestions - 3
  • superset-frontend/src/components/Chart/DrillDown/useDrillDownState.ts - 2
  • superset-frontend/src/components/Chart/chartReducers.test.ts - 1
Additional Suggestions - 8
  • superset-frontend/plugins/plugin-chart-echarts/src/Gauge/controlPanel.tsx - 1
    • Schema property missing from type · Line 60-60
      The Gauge chart's `EchartsGaugeFormData` type does not declare `drilldown_hierarchy` even though this control is now exposed. Other charts in this plugin (Pie, BoxPlot, Funnel, Radar, BoxPlot) all declare it explicitly in their types. Add the property to maintain schema consistency across the plugin.
  • superset-frontend/src/components/Chart/DrillDown/useDrillDownState.ts - 1
    • No timeout on async query wait · Line 363-363
      There is no timeout on the waitForAsyncData promise returned by handleChartDataResponse at line 363. If the async job never completes (e.g., WebSocket disconnects without ERROR event, or polling falls behind), the promise hangs indefinitely with no retry trigger. This blocks the drill-down UI with a permanently stuck loading spinner.
  • superset-frontend/plugins/plugin-chart-echarts/src/BoxPlot/transformProps.ts - 1
    • Missing test coverage for onDrillDown · Line 60-60
      The `onDrillDown` hook is correctly destructured from `hooks` (line 60) and passed to the return object (line 338), following the same pattern as `onContextMenu`. However, the test file (`test/BoxPlot/transformProps.test.ts`) does not assert either hook in the return, so the new passthrough is unverified. Per [6262] (BITO.md adaptive rule), tests should validate behavior they describe. Add an assertion like `expect.objectContaining({ onDrillDown: expect.any(Function) })` to the existing transformProps test or a dedicated hook-passthrough test.
  • superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/EchartsTimeseries.tsx - 2
    • Inconsistent formattedVal in drill-down handler · Line 265-265
      The `formattedVal` on line 265 uses `String(values[i])`, but the identical cross-filter path in the same file already uses `formatSeriesName` (line 394) which handles time-column formatting, number formatting, and null values. Inconsistent `formattedVal` will cause the drill-down breadcrumb label to display raw unformatted values (e.g. raw timestamps or unformatted decimals) instead of user-friendly labels.
    • Inconsistent formattedVal in bar-chart and fallback branches · Line 264-264
      The second drill-down branch (bar chart with category X-axis, line 271–283) and the fallback branch (line 284–291) also use `String(...)` for `formattedVal`. All three branches should use `formatSeriesName` for consistency with the cross-filter path (line 394) and with the parallel `eventHandlers.ts` drill-down handler (lines 186–189).
  • superset-frontend/plugins/plugin-chart-echarts/src/Radar/controlPanel.tsx - 1
    • Missing control panel tests · Line 114-114
      This diff adds the `drilldownHierarchySection` control to the Radar chart but lacks corresponding test coverage. Other eCharts plugins in the same repository (Timeseries/Line, Timeseries/Bar, Timeseries/Area, etc.) have `controlPanel.test.ts` files that verify their control panel configurations. Per BITO.md adaptive rule 11730, new features should include comprehensive unit tests covering success paths and edge cases.
  • superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/Area/controlPanel.tsx - 1
    • Missing test coverage for drilldown · Line 65-65
      The test file at test/Timeseries/Area/controlPanel.test.ts does not verify the newly added `drilldownHierarchySection`. Add assertions to confirm the section is present in controlPanelSections and the drilldown_hierarchy control is correctly configured with expected defaults.
  • superset-frontend/src/components/Chart/ChartRenderer.tsx - 1
    • Unused triggerQuery in ChartActions · Line 96-96
      `triggerQuery` is declared in the `ChartActions` interface but never destructured or used within `ChartRenderer`. DrillDownHost passes it via `overlayProps.actions` and calls it directly — the declaration in `ChartActions` is dead code for this file.
Filtered by Review Rules

Bito filtered these suggestions based on rules created automatically for your feedback. Manage rules.

  • superset-frontend/src/components/Chart/DrillDown/useDrillDownState.test.ts - 1
  • superset-frontend/src/components/Chart/ChartRenderer.tsx - 1
  • superset-frontend/src/components/Chart/DrillDown/DrillDownBreadcrumb.tsx - 1
Review Details
  • Files reviewed - 34 · Commit Range: beb03aa..beb03aa
    • superset-frontend/packages/superset-ui-chart-controls/src/sections/drilldownHierarchy.tsx
    • superset-frontend/packages/superset-ui-chart-controls/src/sections/index.ts
    • superset-frontend/plugins/plugin-chart-echarts/src/BoxPlot/controlPanel.ts
    • superset-frontend/plugins/plugin-chart-echarts/src/BoxPlot/transformProps.ts
    • superset-frontend/plugins/plugin-chart-echarts/src/Funnel/controlPanel.tsx
    • superset-frontend/plugins/plugin-chart-echarts/src/Funnel/transformProps.ts
    • superset-frontend/plugins/plugin-chart-echarts/src/Gauge/controlPanel.tsx
    • superset-frontend/plugins/plugin-chart-echarts/src/Gauge/transformProps.ts
    • superset-frontend/plugins/plugin-chart-echarts/src/Pie/controlPanel.tsx
    • superset-frontend/plugins/plugin-chart-echarts/src/Pie/transformProps.ts
    • superset-frontend/plugins/plugin-chart-echarts/src/Radar/controlPanel.tsx
    • superset-frontend/plugins/plugin-chart-echarts/src/Radar/transformProps.ts
    • superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/Area/controlPanel.tsx
    • superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/EchartsTimeseries.tsx
    • superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/Regular/Bar/controlPanel.tsx
    • superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/Regular/Line/controlPanel.tsx
    • superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/Regular/Scatter/controlPanel.tsx
    • superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/Regular/SmoothLine/controlPanel.tsx
    • superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/Step/controlPanel.tsx
    • superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/transformProps.ts
    • superset-frontend/plugins/plugin-chart-echarts/src/types.ts
    • superset-frontend/plugins/plugin-chart-echarts/src/utils/eventHandlers.test.ts
    • superset-frontend/plugins/plugin-chart-echarts/src/utils/eventHandlers.ts
    • superset-frontend/src/components/Chart/Chart.tsx
    • superset-frontend/src/components/Chart/ChartRenderer.tsx
    • superset-frontend/src/components/Chart/DrillDown/DrillDownBreadcrumb.test.tsx
    • superset-frontend/src/components/Chart/DrillDown/DrillDownBreadcrumb.tsx
    • superset-frontend/src/components/Chart/DrillDown/DrillDownHost.test.tsx
    • superset-frontend/src/components/Chart/DrillDown/DrillDownHost.tsx
    • superset-frontend/src/components/Chart/DrillDown/types.ts
    • superset-frontend/src/components/Chart/DrillDown/useDrillDownState.test.ts
    • superset-frontend/src/components/Chart/DrillDown/useDrillDownState.ts
    • superset-frontend/src/components/Chart/chartReducer.ts
    • superset-frontend/src/components/Chart/chartReducers.test.ts
  • Files skipped - 0
  • Tools
    • Whispers (Secret Scanner) - ✔︎ Successful
    • Detect-secrets (Secret Scanner) - ✔︎ Successful
    • Eslint (Linter) - ✔︎ Successful

Bito Usage Guide

Commands

Type the following command in the pull request comment and save the comment.

  • /review - Manually triggers a full AI review.

  • /pause - Pauses automatic reviews on this pull request.

  • /resume - Resumes automatic reviews.

  • /resolve - Marks all Bito-posted review comments as resolved.

  • /abort - Cancels all in-progress reviews.

Refer to the documentation for additional commands.

Configuration

This repository uses Superset You can customize the agent settings here or contact your Bito workspace admin at evan@preset.io.

Documentation & Help

AI Code Review powered by Bito Logo

Comment thread superset-frontend/src/components/Chart/chartReducers.test.ts
@EnxDev

EnxDev commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

EnxDev's Review Agent — #41907 · HEAD 6f70126

request changes — the drill path is wrong for x-axis charts that also have a Dimension: it drills on the series dimension, not the x-axis column the breadcrumb claims.

Context: reviewed against the diff only (no linked issue/SIP). The three earlier bot findings on EchartsTimeseries.tsx (metrics offset, getCategoryAxisValue, props.name != null) are genuinely fixed in this revision — I verified each against the code, not the claim — but none of them has a regression test.

🔴 Functional

  • plugins/plugin-chart-echarts/src/Timeseries/EchartsTimeseries.tsx:258 · HighhasDimensions is groupby.length > 0, and Bar/Line/Area/Scatter/Step have both x_axis and groupby (Dimensions). With x_axis: country, groupby: [gender], drilldown_hierarchy: [region, city]hierarchy = [country, region, city], but the click builds filters from groupby (gender), so it drills on the series dimension. useDrillDownState.ts:266 then takes the hasGroupby branch and swaps groupby → [region] while x_axis stays country. Result: the chart never advances along the hierarchy, the breadcrumb reads country › M, and the emitted cross-filter scopes other charts by gender. Anchor the drill to hierarchy[currentDepth] — when x_axis is set, read the category via getCategoryAxisValue and swap x_axis, not groupby. regression test: Bar chart with x_axis: 'country' + groupby: ['gender'], hierarchy ['country','region']; click a bar → expect the filter col to be country and effectiveFormData.x_axis === 'region'.

  • src/components/Chart/DrillDown/DrillDownHost.tsx:139 · MediumchartStatus: isLoading ? 'loading' : 'rendered', but on the render right after drillDown() the fetch effect hasn't run: isLoading === false and drillData === null. ChartRenderer gets queriesResponse: null + chartStatus: 'rendered'resultsReady false → queriesData undefined → SuperChart paints the "No results were returned for this query" empty state for a frame, then blanks while loading. Every drill click flashes "No results". Fix: chartStatus: isLoading || effectiveQueriesResponse == null ? 'loading' : 'rendered'. regression test: call onDrillDown, assert the renderer receives chartStatus: 'loading' before the fetch resolves.

  • plugins/plugin-chart-echarts/src/Timeseries/EchartsTimeseries.tsx:276 · Medium — the category branch checks only xAxis.type === AxisType.Category and drops master's props.componentType === 'series' guard (kept on line 260 of the cross-filter path). ECharts fires click for axis labels too, so clicking an x-axis tick now drills. Restore the guard. regression test: click event with componentType: 'xAxis'onDrillDown not called.

  • src/components/Chart/DrillDown/useDrillDownState.ts:422 · Low — when the author lists exactly the chart's own dimension (drilldown_hierarchy: ['country'] with x_axis: 'country'), hierarchy.length === 1 and drillStack.length >= hierarchy.length - 1 is true on the first click, so it takes the leaf branch and never pushes. isDrilling stays false → overlayProps is {} → the chart never filters. But onDrillDown is still provided, so normal cross-filter click behavior is replaced and the emitted cross-filter can't be toggled off. The control's own docstring invites this ("prepended automatically if it is not already listed"). Gate hasHierarchy on hierarchy.length >= 2. regression test: single-entry hierarchy equal to x_axishasHierarchy === false.

🟡 Should-fix

  • src/components/Chart/Chart.tsx:359ChartContainer feeds Chart.tsx from both the dashboard and Explore (ExploreChartPanel), so drill-down and its click-behavior override are live in Explore, where the PR says this is a dashboard feature. The control panel and the rendered chart then disagree, and configKey is only slice_id__viz_type, so editing controls doesn't reset the drill. Gate on source === ChartSource.Dashboard.
  • src/components/Chart/DrillDown/useDrillDownState.ts:311JSON.stringify(effectiveFormData) runs on every render for every chart in the app, hierarchy or not (at depth 0 effectiveFormData === formData). Guard with hasHierarchy && currentDepth > 0.
  • src/components/Chart/DrillDown/useDrillDownState.ts:73 — the module-level drillStateStore is keyed by slice_id, never evicted, and shared across dashboards and Explore for the same slice. Key by chartId, or scope it to the dashboard id.
  • src/components/Chart/DrillDown/useDrillDownState.ts:218ensureIsArray(...) as string[] is an unchecked cast; the control spreads sharedControls.groupby (dndGroupByControl, freeForm: true), so entries can be AdhocColumn objects. Those never match drillLevels.includes(xAxisStr), get assigned raw into x_axis/groupby, and when one lands at hierarchy[0] the breadcrumb renders an object as a React child. Set freeForm: false on the control or normalize with getColumnLabel.
  • packages/superset-ui-chart-controls/src/sections/drilldownHierarchy.tsx:61renderTrigger: false contradicts its own comment ("no re-render/re-query is needed"). With false, every hierarchy edit marks the chart stale and re-runs the base query. Use renderTrigger: true.
  • src/components/Chart/DrillDown/DrillDownHost.tsx:149handleResetTo dispatches updateDataMask regardless of emitCrossFilters, while onDrillDown gates on it. With cross-filters off, drilling emits nothing but returning to root writes an empty filterState and forces triggerQuery(true, chartId) — a full re-query — even though nothing was ever emitted.
  • src/components/Chart/chartReducer.ts:230 — an unrelated defensive fix bundled into a feature PR, and it silently drops every keyed action for a missing chart. The comment ties it to drill-down cross-filtering, which suggests the drill flow dispatches against removed charts. Split it out and fix the root cause rather than the symptom.
  • Test coverageEchartsTimeseries.tsx gained 67 lines of drill logic with zero tests; eventHandlers.test.ts only exercises the groupby path in utils/eventHandlers.ts. The x-axis branch, horizontal orientation, zero-valued labels, and the multi-metric offset are all untested — exactly the three bugs already reported once on this file. The x_axis + groupby case above would have been caught by any test of that combination.
  • No feature flag, no docs. Superset already ships DRILL_BY (default on) and drill-to-detail. A second, parallel drill mechanism with no flag, no docs/ update, and no stated relationship to DrillBy needs a maintainer decision before merge.
  • src/components/Chart/DrillDown/DrillDownBreadcrumb.tsx:94 — raw <div>/<span>/<button> where @superset-ui/core/components exports Breadcrumb. DrillDownHost.test.tsx also imports render from @testing-library/react instead of spec/helpers/testing-library, and uses as any four times.

🔵 Nits

  • src/components/Chart/DrillDown/useDrillDownState.ts:388console.error logs the full effectiveFormData on every failed drill.
  • src/components/Chart/ChartRenderer.tsx:149,181 — inline import('@superset-ui/core').BinaryQueryObjectFilterClause; use a top-level type import.
  • src/components/Chart/DrillDown/DrillDownHost.tsx:191 — the breadcrumb-height effect depends only on drillStack.length, so it misses selectedLeaf/error changes and wrapping, leaving adjustedHeight stale.
  • src/components/Chart/DrillDown/DrillDownBreadcrumb.tsx:100key={index}.
  • src/components/Chart/DrillDown/DrillDownBreadcrumb.test.tsx — the last test's comment ("only have been called for the root click test") describes state from another, isolated test.

🙌 Praise

  • src/components/Chart/DrillDown/useDrillDownState.ts:302 — the effectiveFormDataRef + serialized-key guard against identity-only formData churn is a subtle bug to have found, and the comment names the exact failure mode (in-flight request cancelled, chart spinning to the 60s timeout).
  • src/components/Chart/DrillDown/useDrillDownState.ts:73 — persisting drill state synchronously on mutate rather than in an effect, with a remount test to lock it in.

Reviewed by EnxDev's Review Agent — @EnxDev · HEAD 6f70126.

@tomerkl65
tomerkl65 force-pushed the feat/echarts-drilldown-hierarchy branch 3 times, most recently from 967b575 to d77f08d Compare July 9, 2026 15:48
@codecov

codecov Bot commented Jul 9, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 88.16199% with 38 lines in your changes missing coverage. Please review.
✅ Project coverage is 65.08%. Comparing base (18f1dd3) to head (7eb64fb).
⚠️ Report is 34 commits behind head on master.

Files with missing lines Patch % Lines
...rc/components/Chart/DrillDown/useDrillDownState.ts 92.65% 13 Missing ⚠️
...chart-echarts/src/Timeseries/EchartsTimeseries.tsx 43.75% 9 Missing ⚠️
...d/src/components/Chart/DrillDown/DrillDownHost.tsx 84.21% 9 Missing ⚠️
...components/Chart/DrillDown/DrillDownBreadcrumb.tsx 80.00% 4 Missing ⚠️
...chart-controls/src/sections/drilldownHierarchy.tsx 50.00% 1 Missing ⚠️
...lugin-chart-echarts/src/Timeseries/drillFilters.ts 95.83% 1 Missing ⚠️
...ns/plugin-chart-echarts/src/utils/eventHandlers.ts 94.11% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master   #41907      +/-   ##
==========================================
+ Coverage   65.03%   65.08%   +0.04%     
==========================================
  Files        2744     2749       +5     
  Lines      153627   153930     +303     
  Branches    35226    35323      +97     
==========================================
+ Hits        99915   100180     +265     
- Misses      51805    51843      +38     
  Partials     1907     1907              
Flag Coverage Δ
hive 39.04% <ø> (ø)
javascript 70.45% <88.16%> (+0.06%) ⬆️
mysql 57.90% <ø> (ø)
postgres 57.96% <ø> (ø)
presto 41.03% <ø> (ø)
python 59.34% <ø> (ø)
sqlite 57.57% <ø> (ø)
unit 100.00% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@tomerkl65
tomerkl65 force-pushed the feat/echarts-drilldown-hierarchy branch from d77f08d to a10f64b Compare July 9, 2026 16:41

@bito-code-review bito-code-review Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review Agent Run #93499c

Actionable Suggestions - 3
  • superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/Regular/Scatter/controlPanel.tsx - 1
  • superset-frontend/packages/superset-ui-chart-controls/src/sections/drilldownHierarchy.tsx - 1
  • superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/transformProps.ts - 1
Additional Suggestions - 4
  • superset-frontend/plugins/plugin-chart-echarts/src/utils/eventHandlers.test.ts - 2
    • Weak label assertion in drill-down test · Line 72-96
      The test currently asserts the label argument using `expect.any(String)`, which only checks type. Please replace this with an explicit value assertion (e.g., `'USA'`) and extend the test to validate the filters array’s `formattedVal` field, not just `col` and `op`.
    • Missing test for empty-groupby guard · Line 47-70
      The combination `onDrillDown != null` with `groupby.length === 0` is not covered by existing tests. Currently all drill-down tests use `groupby: ['country']`, so the guard on line 176 is exercised only in the truthy branch. Adding a test for the empty-groupby fallback ensures the nullish-coalescing fallback on line 205 is exercised and does not regress.
  • superset-frontend/src/components/Chart/DrillDown/useDrillDownState.test.ts - 2
    • Inconsistent retry attempt count · Line 591-591
      The comment incorrectly states '2 retries' but `MAX_ATTEMPTS = 3` means 3 total attempts (attempt 1, attempt 2, attempt 3). Update comment to accurately reflect 3 total attempts.
    • Unverifiable assertion in test · Line 632-636
      The test comment at line 632-634 claims 'should not leave isLoading stuck' but the test provides no assertion verifying this. After unmount, `result.current` is invalid and `isLoading` cannot be queried. The test only verifies that the cleanup function doesn't throw, not that `isLoading` actually resets to false.
Filtered by Review Rules

Bito filtered these suggestions based on rules created automatically for your feedback. Manage rules.

  • superset-frontend/plugins/plugin-chart-echarts/src/utils/eventHandlers.test.ts - 1
Review Details
  • Files reviewed - 34 · Commit Range: d77f08d..d77f08d
    • superset-frontend/packages/superset-ui-chart-controls/src/sections/drilldownHierarchy.tsx
    • superset-frontend/packages/superset-ui-chart-controls/src/sections/index.ts
    • superset-frontend/plugins/plugin-chart-echarts/src/BoxPlot/controlPanel.ts
    • superset-frontend/plugins/plugin-chart-echarts/src/BoxPlot/transformProps.ts
    • superset-frontend/plugins/plugin-chart-echarts/src/Funnel/controlPanel.tsx
    • superset-frontend/plugins/plugin-chart-echarts/src/Funnel/transformProps.ts
    • superset-frontend/plugins/plugin-chart-echarts/src/Gauge/controlPanel.tsx
    • superset-frontend/plugins/plugin-chart-echarts/src/Gauge/transformProps.ts
    • superset-frontend/plugins/plugin-chart-echarts/src/Pie/controlPanel.tsx
    • superset-frontend/plugins/plugin-chart-echarts/src/Pie/transformProps.ts
    • superset-frontend/plugins/plugin-chart-echarts/src/Radar/controlPanel.tsx
    • superset-frontend/plugins/plugin-chart-echarts/src/Radar/transformProps.ts
    • superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/Area/controlPanel.tsx
    • superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/EchartsTimeseries.tsx
    • superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/Regular/Bar/controlPanel.tsx
    • superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/Regular/Line/controlPanel.tsx
    • superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/Regular/Scatter/controlPanel.tsx
    • superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/Regular/SmoothLine/controlPanel.tsx
    • superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/Step/controlPanel.tsx
    • superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/transformProps.ts
    • superset-frontend/plugins/plugin-chart-echarts/src/types.ts
    • superset-frontend/plugins/plugin-chart-echarts/src/utils/eventHandlers.test.ts
    • superset-frontend/plugins/plugin-chart-echarts/src/utils/eventHandlers.ts
    • superset-frontend/src/components/Chart/Chart.tsx
    • superset-frontend/src/components/Chart/ChartRenderer.tsx
    • superset-frontend/src/components/Chart/DrillDown/DrillDownBreadcrumb.test.tsx
    • superset-frontend/src/components/Chart/DrillDown/DrillDownBreadcrumb.tsx
    • superset-frontend/src/components/Chart/DrillDown/DrillDownHost.test.tsx
    • superset-frontend/src/components/Chart/DrillDown/DrillDownHost.tsx
    • superset-frontend/src/components/Chart/DrillDown/types.ts
    • superset-frontend/src/components/Chart/DrillDown/useDrillDownState.test.ts
    • superset-frontend/src/components/Chart/DrillDown/useDrillDownState.ts
    • superset-frontend/src/components/Chart/chartReducer.ts
    • superset-frontend/src/components/Chart/chartReducers.test.ts
  • Files skipped - 0
  • Tools
    • Whispers (Secret Scanner) - ✔︎ Successful
    • Detect-secrets (Secret Scanner) - ✔︎ Successful
    • Eslint (Linter) - ✔︎ Successful

Bito Usage Guide

Commands

Type the following command in the pull request comment and save the comment.

  • /review - Manually triggers a full AI review.

  • /pause - Pauses automatic reviews on this pull request.

  • /resume - Resumes automatic reviews.

  • /resolve - Marks all Bito-posted review comments as resolved.

  • /abort - Cancels all in-progress reviews.

Refer to the documentation for additional commands.

Configuration

This repository uses Superset You can customize the agent settings here or contact your Bito workspace admin at evan@preset.io.

Documentation & Help

AI Code Review powered by Bito Logo

@tomerkl65
tomerkl65 force-pushed the feat/echarts-drilldown-hierarchy branch 2 times, most recently from 0ef7d19 to 0ed9d9f Compare July 9, 2026 17:37
@netlify

netlify Bot commented Jul 10, 2026

Copy link
Copy Markdown

Deploy Preview for superset-docs-preview ready!

Name Link
🔨 Latest commit 2c92a8c
🔍 Latest deploy log https://app.netlify.com/projects/superset-docs-preview/deploys/6a509c1dda674a0009c2eb5e
😎 Deploy Preview https://deploy-preview-41907--superset-docs-preview.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

@bito-code-review bito-code-review Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review Agent Run #647224

Actionable Suggestions - 1
  • superset-frontend/src/components/Chart/DrillDown/DrillDownHost.test.tsx - 1
Additional Suggestions - 5
  • superset-frontend/src/components/Chart/DrillDown/useDrillDownState.ts - 1
    • CWE-20: Leaf Filters Persist After Navigation · Line 323-323
      Leaf filters are applied to `effectiveFormData.adhoc_filters` even when `selectedLeaf` is undefined (e.g., after `resetTo()` or when navigating back). The `selectedLeafFilters` state is only cleared in `resetTo`, but the filter accumulation in `effectiveFormData` reads it regardless of whether `selectedLeaf` is set. This could cause stale leaf filters to persist in `effectiveFormData` across navigation levels until the chart is reconfigured. ([CWE-20](https://cwe.mitre.org/data/definitions/20.html))
  • superset-frontend/src/components/Chart/ChartRenderer.tsx - 1
    • Unused interface prop · Line 97-97
      The `triggerQuery?: (value: boolean, key: number | string) => void` prop added at line 97 is defined in `ChartActions` but never destructured or passed to `SuperChart`'s hooks bag (lines 398-426) in this diff. This creates a contract inconsistency where the interface promises functionality that isn't connected.
  • superset-frontend/src/components/Chart/DrillDown/DrillDownBreadcrumb.tsx - 1
    • Missing i18n for breadcrumb separator · Line 101-101
      The breadcrumb separator character `›` is user-facing text rendered directly in the UI. Per [6516], all such labels must be wrapped with the translation function (`t()`) to support internationalization. Import `t` from `@apache-superset/core` and change lines 101 and 118 to use `t('›')` instead of the literal character.
  • superset-frontend/plugins/plugin-chart-echarts/src/Funnel/transformProps.ts - 1
    • Missing drill-down test coverage · Line 155-155
      The Funnel plugin lacks test coverage for the onDrillDown integration. Given BITO.md rule 6262 (assert behavior logic in tests, not just rendering), adding tests that verify onDrillDown is correctly passed through and handled would prevent regressions.
  • superset-frontend/src/components/Chart/DrillDown/DrillDownHost.test.tsx - 1
    • Duplicate inline mock component · Line 188-195
      Duplicate function definitions: `CaptureRenderer` is defined inline at lines 188-195 and again at lines 235-242 with identical implementation. Extract to module-level constant to reduce duplication and improve maintainability.
Filtered by Review Rules

Bito filtered these suggestions based on rules created automatically for your feedback. Manage rules.

  • superset-frontend/src/components/Chart/DrillDown/useDrillDownState.test.ts - 1
Review Details
  • Files reviewed - 34 · Commit Range: 2a07da6..2a07da6
    • superset-frontend/packages/superset-ui-chart-controls/src/sections/drilldownHierarchy.tsx
    • superset-frontend/packages/superset-ui-chart-controls/src/sections/index.ts
    • superset-frontend/plugins/plugin-chart-echarts/src/BoxPlot/transformProps.ts
    • superset-frontend/plugins/plugin-chart-echarts/src/Funnel/controlPanel.tsx
    • superset-frontend/plugins/plugin-chart-echarts/src/Funnel/transformProps.ts
    • superset-frontend/plugins/plugin-chart-echarts/src/Gauge/controlPanel.tsx
    • superset-frontend/plugins/plugin-chart-echarts/src/Gauge/transformProps.ts
    • superset-frontend/plugins/plugin-chart-echarts/src/Pie/controlPanel.tsx
    • superset-frontend/plugins/plugin-chart-echarts/src/Pie/transformProps.ts
    • superset-frontend/plugins/plugin-chart-echarts/src/Radar/controlPanel.tsx
    • superset-frontend/plugins/plugin-chart-echarts/src/Radar/transformProps.ts
    • superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/Area/controlPanel.tsx
    • superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/EchartsTimeseries.tsx
    • superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/Regular/Bar/controlPanel.tsx
    • superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/Regular/Line/controlPanel.tsx
    • superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/Regular/Scatter/controlPanel.tsx
    • superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/Regular/SmoothLine/controlPanel.tsx
    • superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/Step/controlPanel.tsx
    • superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/transformProps.ts
    • superset-frontend/plugins/plugin-chart-echarts/src/types.ts
    • superset-frontend/plugins/plugin-chart-echarts/src/utils/eventHandlers.test.ts
    • superset-frontend/plugins/plugin-chart-echarts/src/utils/eventHandlers.ts
    • superset-frontend/plugins/plugin-chart-echarts/test/Gauge/transformProps.test.ts
    • superset-frontend/src/components/Chart/Chart.tsx
    • superset-frontend/src/components/Chart/ChartRenderer.tsx
    • superset-frontend/src/components/Chart/DrillDown/DrillDownBreadcrumb.test.tsx
    • superset-frontend/src/components/Chart/DrillDown/DrillDownBreadcrumb.tsx
    • superset-frontend/src/components/Chart/DrillDown/DrillDownHost.test.tsx
    • superset-frontend/src/components/Chart/DrillDown/DrillDownHost.tsx
    • superset-frontend/src/components/Chart/DrillDown/types.ts
    • superset-frontend/src/components/Chart/DrillDown/useDrillDownState.test.ts
    • superset-frontend/src/components/Chart/DrillDown/useDrillDownState.ts
    • superset-frontend/src/components/Chart/chartReducer.ts
    • superset-frontend/src/components/Chart/chartReducers.test.ts
  • Files skipped - 0
  • Tools
    • Whispers (Secret Scanner) - ✔︎ Successful
    • Detect-secrets (Secret Scanner) - ✔︎ Successful
    • Eslint (Linter) - ✔︎ Successful

Bito Usage Guide

Commands

Type the following command in the pull request comment and save the comment.

  • /review - Manually triggers a full AI review.

  • /pause - Pauses automatic reviews on this pull request.

  • /resume - Resumes automatic reviews.

  • /resolve - Marks all Bito-posted review comments as resolved.

  • /abort - Cancels all in-progress reviews.

Refer to the documentation for additional commands.

Configuration

This repository uses Superset You can customize the agent settings here or contact your Bito workspace admin at evan@preset.io.

Documentation & Help

AI Code Review powered by Bito Logo

Comment thread superset-frontend/src/components/Chart/DrillDown/DrillDownHost.test.tsx Outdated
Add a hierarchical drill-down interaction for ECharts charts. The chart author
defines an ordered list of columns in a new **Drill-down hierarchy** control
(`drilldown_hierarchy`). On a dashboard, left-clicking a data point drills to
the next level scoped to the clicked value, shows a breadcrumb for navigating
back up, and emits a cross-filter for the full drill path so other charts stay
in sync. At the deepest level a click narrows the chart to the selected value.

Supported charts: Bar, Line, Area, Scatter, Smooth Line, Step (x-axis based)
and Pie, Funnel, Gauge, Radar, Box Plot (groupby based).
- Use spec/helpers/testing-library in DrillDownHost test and dedupe CaptureRenderer
- Guard leaf filters so they never persist after navigating back (resetTo)
- Wrap breadcrumb separator in t() for i18n
- Add Funnel onDrillDown pass-through test coverage
@tomerkl65
tomerkl65 force-pushed the feat/echarts-drilldown-hierarchy branch from 2a07da6 to e342acd Compare July 10, 2026 12:55
@netlify

netlify Bot commented Jul 10, 2026

Copy link
Copy Markdown

Deploy Preview for superset-docs-preview ready!

Name Link
🔨 Latest commit 7eb64fb
🔍 Latest deploy log https://app.netlify.com/projects/superset-docs-preview/deploys/6a553dc3c2df790008c235f6
😎 Deploy Preview https://deploy-preview-41907--superset-docs-preview.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

- Skip leading metric/series tokens in labelMap when mapping groupby columns in the drill-down click handler (matches getCrossFilterDataMask), fixing misaligned filters on multi-metric charts
- Add drilldownHierarchySection to the Box Plot control panel so its onDrillDown plumbing is reachable
- Add regression test for the multi-metric labelMap offset
…ps tests

- Cast inline-literal ChartProps through unknown (matches Timeseries/Waterfall test convention) to resolve TS2352 in Funnel and Gauge drill-down tests
- Apply prettier formatting to Gauge test queriesData

@bito-code-review bito-code-review Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review Agent Run #3f0632

Actionable Suggestions - 2
  • superset-frontend/plugins/plugin-chart-echarts/src/Radar/transformProps.ts - 1
  • superset-frontend/plugins/plugin-chart-echarts/src/Pie/transformProps.ts - 1
Additional Suggestions - 3
  • superset-frontend/plugins/plugin-chart-echarts/src/Pie/controlPanel.tsx - 1
    • CWE-20: Missing type for drilldown_hierarchy · Line 70-70
      The `drilldownHierarchySection` exposes a `drilldown_hierarchy` control (string array, default `[]`), but `EchartsPieFormData` in `types.ts` has no corresponding property. TypeScript will not recognize the runtime value. Add the field to the type definition to match other plugin types (e.g., `GaugeChartTransformedProps`).
  • superset-frontend/src/components/Chart/DrillDown/DrillDownHost.tsx - 1
    • Duplicate filter-building logic · Line 183-189
      The filter-object construction inside `handleResetTo` (lines 183-189) duplicates the logic in `onDrillDown` (lines 105-121) — both build `IN`-op filter objects from `drillStack` entries. Duplication risks divergence if the filter schema is ever extended.
  • superset-frontend/plugins/plugin-chart-echarts/src/Radar/controlPanel.tsx - 1
    • Missing unit test for drilldown · Line 114-114
      The new `sections.drilldownHierarchySection` is added to the Radar chart's control panel (line 114) but lacks corresponding test coverage. Other charts in this plugin (Scatter, SmoothLine, Bar, Area, Line, Step) have controlPanel.test.ts files, but Radar only has transformProps.test.ts and utils.test.ts. Per adaptive rule [6262], tests should verify actual business logic — the drilldown behavior requires a unit test.
Filtered by Review Rules

Bito filtered these suggestions based on rules created automatically for your feedback. Manage rules.

  • superset-frontend/src/components/Chart/DrillDown/useDrillDownState.test.ts - 1
Review Details
  • Files reviewed - 36 · Commit Range: 54aa3b2..26ccc78
    • superset-frontend/packages/superset-ui-chart-controls/src/sections/drilldownHierarchy.tsx
    • superset-frontend/packages/superset-ui-chart-controls/src/sections/index.ts
    • superset-frontend/plugins/plugin-chart-echarts/src/BoxPlot/controlPanel.ts
    • superset-frontend/plugins/plugin-chart-echarts/src/BoxPlot/transformProps.ts
    • superset-frontend/plugins/plugin-chart-echarts/src/Funnel/controlPanel.tsx
    • superset-frontend/plugins/plugin-chart-echarts/src/Funnel/transformProps.ts
    • superset-frontend/plugins/plugin-chart-echarts/src/Gauge/controlPanel.tsx
    • superset-frontend/plugins/plugin-chart-echarts/src/Gauge/transformProps.ts
    • superset-frontend/plugins/plugin-chart-echarts/src/Pie/controlPanel.tsx
    • superset-frontend/plugins/plugin-chart-echarts/src/Pie/transformProps.ts
    • superset-frontend/plugins/plugin-chart-echarts/src/Radar/controlPanel.tsx
    • superset-frontend/plugins/plugin-chart-echarts/src/Radar/transformProps.ts
    • superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/Area/controlPanel.tsx
    • superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/EchartsTimeseries.tsx
    • superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/Regular/Bar/controlPanel.tsx
    • superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/Regular/Line/controlPanel.tsx
    • superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/Regular/Scatter/controlPanel.tsx
    • superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/Regular/SmoothLine/controlPanel.tsx
    • superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/Step/controlPanel.tsx
    • superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/transformProps.ts
    • superset-frontend/plugins/plugin-chart-echarts/src/types.ts
    • superset-frontend/plugins/plugin-chart-echarts/src/utils/eventHandlers.test.ts
    • superset-frontend/plugins/plugin-chart-echarts/src/utils/eventHandlers.ts
    • superset-frontend/plugins/plugin-chart-echarts/test/Funnel/transformProps.test.ts
    • superset-frontend/plugins/plugin-chart-echarts/test/Gauge/transformProps.test.ts
    • superset-frontend/src/components/Chart/Chart.tsx
    • superset-frontend/src/components/Chart/ChartRenderer.tsx
    • superset-frontend/src/components/Chart/DrillDown/DrillDownBreadcrumb.test.tsx
    • superset-frontend/src/components/Chart/DrillDown/DrillDownBreadcrumb.tsx
    • superset-frontend/src/components/Chart/DrillDown/DrillDownHost.test.tsx
    • superset-frontend/src/components/Chart/DrillDown/DrillDownHost.tsx
    • superset-frontend/src/components/Chart/DrillDown/types.ts
    • superset-frontend/src/components/Chart/DrillDown/useDrillDownState.test.ts
    • superset-frontend/src/components/Chart/DrillDown/useDrillDownState.ts
    • superset-frontend/src/components/Chart/chartReducer.ts
    • superset-frontend/src/components/Chart/chartReducers.test.ts
  • Files skipped - 0
  • Tools
    • Whispers (Secret Scanner) - ✔︎ Successful
    • Detect-secrets (Secret Scanner) - ✔︎ Successful
    • Eslint (Linter) - ✔︎ Successful

Bito Usage Guide

Commands

Type the following command in the pull request comment and save the comment.

  • /review - Manually triggers a full AI review.

  • /pause - Pauses automatic reviews on this pull request.

  • /resume - Resumes automatic reviews.

  • /resolve - Marks all Bito-posted review comments as resolved.

  • /abort - Cancels all in-progress reviews.

Refer to the documentation for additional commands.

Configuration

This repository uses Superset You can customize the agent settings here or contact your Bito workspace admin at evan@preset.io.

Documentation & Help

AI Code Review powered by Bito Logo

…ter builder

- Add onDrillDown pass-through tests for Pie and Radar transformProps
- Add Radar controlPanel test asserting the drilldown_hierarchy control
- Extract shared toCrossFilterClauses helper in DrillDownHost to remove duplicated filter-building logic between onDrillDown and handleResetTo
@bito-code-review

bito-code-review Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Code Review Agent Run #41bcb4

Actionable Suggestions - 0
Review Details
  • Files reviewed - 4 · Commit Range: 26ccc78..db42179
    • superset-frontend/plugins/plugin-chart-echarts/test/Pie/transformProps.test.ts
    • superset-frontend/plugins/plugin-chart-echarts/test/Radar/controlPanel.test.ts
    • superset-frontend/plugins/plugin-chart-echarts/test/Radar/transformProps.test.ts
    • superset-frontend/src/components/Chart/DrillDown/DrillDownHost.tsx
  • Files skipped - 0
  • Tools
    • Whispers (Secret Scanner) - ✔︎ Successful
    • Detect-secrets (Secret Scanner) - ✔︎ Successful
    • Eslint (Linter) - ✔︎ Successful

Bito Usage Guide

Commands

Type the following command in the pull request comment and save the comment.

  • /review - Manually triggers a full AI review.

  • /pause - Pauses automatic reviews on this pull request.

  • /resume - Resumes automatic reviews.

  • /resolve - Marks all Bito-posted review comments as resolved.

  • /abort - Cancels all in-progress reviews.

Refer to the documentation for additional commands.

Configuration

This repository uses Superset You can customize the agent settings here or contact your Bito workspace admin at evan@preset.io.

Documentation & Help

AI Code Review powered by Bito Logo

@EnxDev

EnxDev commented Jul 12, 2026

Copy link
Copy Markdown
Contributor

EnxDev's Review Agent — #41907 · HEAD db42179

comment — supersedes my prior request changes (6f70126). The drill-path blocker and all four 🔴 findings are fixed; what's left is test coverage and a maintainer call on flagging/docs. No hard blocker remains.

Verified against the code, not the "fixed" claims:

  • x_axis + groupby charts now drill the x-axis, not the series dimension. useDrillDownState.ts xAxisIsSet branch swaps x_axis and preserves groupby; EchartsTimeseries.tsx builds the filter from xAxis.label. Regression test present (effectiveFormData advances x_axis (not groupby) when the chart has both).
  • chartStatus: isLoading || effectiveQueriesResponse == null ? 'loading' : 'rendered' — no more "No results" flash on drill.
  • Axis-label guard restored (props.componentType === 'series').
  • hasHierarchy = hierarchy.length >= 2 — a single-level hierarchy no longer hijacks the click. Test present.
  • Explore gate (source === ChartSource.Dashboard), store keyed by chartId + eviction, freeForm: false, renderTrigger: true, handleResetTo gated on emitCrossFilters, and console.error no longer dumping form_data — all addressed. (triggerQuery and updateDataMask are confirmed bound on the dashboard chart's actions via ChartContainer, so the reset-to-root re-query is real, not a silent no-op.)

🟡 Should-fix

  • plugins/plugin-chart-echarts/src/Timeseries/EchartsTimeseries.tsx — the ~60-line inline drill handler is still ~26% covered (codecov: 17 missing lines on this file). The x-axis category branch, horizontal-bar orientation, the restored axis-label guard, and the non-category branch are all untested — the same file that carried the three earlier bugs. Two of the fixes I asked for last round shipped without a regression test. Add: category-series click → filter col === xAxis.label; componentType: 'xAxis'onDrillDown not called; first drill render → renderer receives chartStatus: 'loading'.
  • No feature flag, no docs/, no stated relationship to the existing DRILL_BY / drill-to-detail. A second, parallel drill mechanism on a size/XXL PR is a maintainer decision before merge.
  • EchartsTimeseries.tsx drill handler — the breadcrumb label uses String(categoryAxisValue) / String(props.name), while the groupby path (utils/eventHandlers.ts) and the cross-filter path both use formatSeriesName. Timeseries breadcrumb and cross-filter labels show raw values (unformatted decimals, raw timestamps). Use formatSeriesName for parity. For a non-category (time) top level the raw props.name is also used as the filter val, which can fail to match the underlying column — low-probability, but worth guarding if time-as-drill-root is meant to be supported.
  • src/components/Chart/chartReducer.ts:226 — the "ignore a keyed action when the chart is missing" guard is an unrelated defensive change bundled into this feature PR, and it silently drops every keyed action for a missing chart. Its own comment ties it to drill-down cross-filtering — i.e. the drill flow dispatches against removed charts. Split it out and fix the root cause rather than masking the symptom.

🔵 Nits

  • src/components/Chart/DrillDown/DrillDownBreadcrumb.tsx — raw <div>/<span>/<button>; @superset-ui/core/components exports Breadcrumb.
  • BoxPlot onDrillDown passthrough is the only transformProps still without a hook test (Pie/Funnel/Gauge/Radar each got one).

🙌 Praise

  • The x_axis/groupby fix is the right shape: anchor the drill to hierarchy[currentDepth], advance the x-axis, keep the series groupby, and pin exactly that combination with a test.

Reviewed by EnxDev's Review Agent — @EnxDev · HEAD db42179.

tomerkl65 and others added 5 commits July 13, 2026 10:02
- Use formatSeriesName for the timeseries drill breadcrumb/cross-filter label (parity with the groupby drill path) instead of raw String()
- Add onDrillDown pass-through test for BoxPlot transformProps
- Replace the hand-rolled div/span/button breadcrumb with the antd Breadcrumb from @superset-ui/core/components (mirrors DrillByModal)
- Keep keyboard a11y via role/tabIndex + Enter/Space on navigable segments
- Update test to assert role=button/tabindex instead of native button tag
- Extract the timeseries drill-filter building into a pure buildTimeseriesDrillFilters helper (and shared getCategoryAxisValue) so the click behavior is unit-testable
- Add tests: category-series click builds a filter keyed to the x-axis column; non-series clicks (e.g. componentType 'xAxis') do not drill; horizontal orientation reads the correct tuple index; time axis drills on the event name; labels formatted via formatSeriesName
- EchartsTimeseries now delegates to the helper (no behavior change)
…flag

- Add DRILL_DOWN feature flag (default off / dark launch) to config.py and the frontend FeatureFlag enum; sync docs/static/feature-flags.json
- Gate the DrillDownHost runtime and the drilldown_hierarchy control visibility on the flag
- Enable the flag in DrillDownHost tests and add a flag-off gating test
@github-actions github-actions Bot added the doc Namespace | Anything related to documentation label Jul 13, 2026
…ill by / Drill to detail

Add a 'Drilling into data' section clarifying the three independent, flag-gated drill interactions (DRILL_TO_DETAIL, DRILL_BY, DRILL_DOWN) and how they differ.
@bito-code-review

Copy link
Copy Markdown
Contributor

AI Code Review is in progress (usually takes 3 to 15 minutes unless it's a very large PR).

Bito Usage Guide

Commands

Type the following command in the pull request comment and save the comment.

  • /review - Manually triggers a full AI review.

  • /pause - Pauses automatic reviews on this pull request.

  • /resume - Resumes automatic reviews.

  • /resolve - Marks all Bito-posted review comments as resolved.

  • /abort - Cancels all in-progress reviews.

Refer to the documentation for additional commands.

Configuration

This repository uses Superset You can customize the agent settings here or contact your Bito workspace admin at evan@preset.io.

Documentation & Help

@EnxDev

EnxDev commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

EnxDev's Review Agent — #41907 · HEAD 60f31c0

comment — supersedes my prior comment (db42179). Every prior should-fix is addressed: the timeseries drill handler was extracted to drillFilters.ts with a real test, the DRILL_DOWN flag + config + docs landed, and formatSeriesName label parity is in. No blocker remains. Dark-launched (flag off by default).

Verified against the code, not the "fixed" claims:

  • Timeseries drills the x-axis, not the series dimension. The inline handler is gone; buildTimeseriesDrillFilters builds the filter from xAxisLabel, orientation-aware via getCategoryAxisValue(data, name, orientation), with name != null so zero-like labels still drill. Covered by test/Timeseries/drillFilters.test.ts (category / horizontal / time / no-value / formatting).
  • Groupby path applies the metrics offseteventHandlers.ts uses values[metricsCount + i], tested in eventHandlers.test.ts ("skips leading metric tokens").
  • Feature flag in sync across config.py, featureFlags.ts, feature-flags.json; exploring-data.mdx explains the relationship to DRILL_BY / DRILL_TO_DETAIL.
  • Retry exhaustion, unmount isLoading reset, remount persistence, and the reset-to-root re-query are all covered in useDrillDownState.test.ts.

The open bot findings are stale: codeant's four "logic-error" flags (metrics offset, horizontal orientation, falsy-zero, values[i]) reference pre-refactor line numbers and no longer apply; its "BoxPlot has no hierarchy control" is also fixed (sections.drilldownHierarchySection was added). The bito test-coverage flags (retry logic, unmount, chartReducer four-field assertion, fake-timer afterEach, Radar/Pie passthrough) are addressed. CI is green.

🟡 Should-fix

  • plugins/plugin-chart-echarts/src/utils/eventHandlers.ts:~178 · Low — for a multi-metric Box Plot the series name is `${group}, ${metric}` but labelMap is keyed by group only (BoxPlot/transformProps.ts:165-176), so labelMap[e.name] is undefined → the drill handler returns early and, because drill mode replaces the normal cross-filter click, the click becomes a no-op. Only bites multi-metric BoxPlot + a configured hierarchy (matches the existing cross-filter limitation), but worth gating drill-down to single-metric or keying by the full series name. regression test: multi-metric BoxPlot drill click → onDrillDown not called today.
  • src/components/Chart/chartReducer.ts:226 — the "ignore a keyed action when the chart is missing" guard is still bundled into this feature PR and silently drops every keyed action for a missing chart. Carried over from my last review: its own comment ties it to the drill cross-filter flow dispatching against removed charts — split it out and fix the root cause rather than mask the symptom.

🔵 Nits

  • plugins/plugin-chart-echarts/src/utils/eventHandlers.tsmetricsCount = values.length - groupby.length is recomputed inside the groupby.forEach; hoist it above the loop.
  • useDrillDownState.tsconsole.error('[DrillDown] query failed:', …); Superset prefers logging from @apache-superset/core/utils.
  • DrillDownBreadcrumb.tsx renders navigable segments as <span role="button"> (the PR description claims a native <button>); functionally keyboard-operable via the keydown handler, so fine as-is.

🙌 Praise

  • The prior "0 coverage" gap is closed: drillFilters.ts, the 640-line useDrillDownState spec (remount persistence + retry exhaustion), and the DrillDownHost full-path cross-filter test all guard the behavior they claim to.

Reviewed by EnxDev's Review Agent — @EnxDev · HEAD 60f31c0.

const config: ControlPanelConfig = {
controlPanelSections: [
sections.echartsTimeSeriesQueryWithXAxisSort,
sections.drilldownHierarchySection,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: Adding this section unconditionally exposes an empty “Drill-down hierarchy” panel when the DrillDown feature flag is off, because only the inner control has visibility gating. Gate the section itself (or conditionally add it) so users don’t see a blank section in disabled environments. [logic error]

Severity Level: Major ⚠️
⚠️ Explore Bar chart shows empty Drill-down hierarchy section.
⚠️ Users see feature label without any usable controls.
⚠️ Same empty section on Area, Step, Pie charts.
Steps of Reproduction ✅
1. Disable the DRILL_DOWN feature flag as shown in
`superset-frontend/src/components/Chart/DrillDown/DrillDownHost.test.tsx:163-166`, where
`global.featureFlags[FeatureFlag.DrillDown]` is set to `false`.

2. Open Explore for a Bar chart, which uses the control panel config in
`superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/Regular/Bar/controlPanel.tsx:15-22`;
note `controlPanelSections` includes `sections.drilldownHierarchySection` at line 317
unconditionally.

3. The section `drilldownHierarchySection` is defined in
`superset-frontend/packages/superset-ui-chart-controls/src/sections/drilldownHierarchy.tsx:2-34`
with label `t('Drill-down hierarchy')` and a single control `drilldown_hierarchy` whose
`config.visibility` is `() => isFeatureEnabled(FeatureFlag.DrillDown)` at line 29, so this
control is hidden when the flag is disabled.

4. In Explore, sections are rendered by `renderControlPanelSection` in
`superset-frontend/src/explore/components/ControlPanelsContainer.tsx:593-597` and 629-135;
section visibility uses only `section.visibility` (`isVisible = visibility?.call(...) !==
false` at line 14), which is undefined for `drilldownHierarchySection`, so the section
remains visible with `style: { display: isVisible ? 'block' : 'none' }` at line 135, while
its only row is dropped because `renderedControls.length === 0` at lines 104-107. The
result is a visible "Drill-down hierarchy" header with no controls whenever the DRILL_DOWN
feature flag is off.

Fix in Cursor Fix in VSCode Claude

(Use Cmd/Ctrl + Click for best experience)

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/Regular/Bar/controlPanel.tsx
**Line:** 317:317
**Comment:**
	*Logic Error: Adding this section unconditionally exposes an empty “Drill-down hierarchy” panel when the `DrillDown` feature flag is off, because only the inner control has `visibility` gating. Gate the section itself (or conditionally add it) so users don’t see a blank section in disabled environments.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
👍 | 👎

Comment on lines +256 to +266
const drillFilters = buildTimeseriesDrillFilters({
componentType: props.componentType,
data: props.data,
name: props.name,
xAxisType: xAxis.type,
xAxisLabel: xAxis.label,
orientation: formData.orientation,
dateFormat: formData.dateFormat,
numberFormat: formData.numberFormat,
coltype: coltypeMapping?.[xAxis.label],
});

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: For time-axis clicks, this forwards props.name into drill filter construction, but ECharts click name is often the formatted axis label while the raw filterable value is in the data tuple (the same file already uses data[0] for time drill-to-detail). This can generate drill filters with display strings instead of raw temporal values and return empty/incorrect drilled results. Use the raw axis value from the clicked data point for non-category axes when building drill filters. [logic error]

Severity Level: Critical 🚨
- ❌ Timeseries drill-down on time axes returns empty results.
- ❌ Dashboard cross-filters from drill path mis-scope linked charts.
- ⚠️ Breadcrumb labels no longer reflect actual filtered timestamps.
- ⚠️ Users experience inconsistent behavior between context menu drill modes.
Steps of Reproduction ✅
1. Render a Timeseries chart with a time x-axis on a dashboard so that the React component
`EchartsTimeseries` in
`superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/EchartsTimeseries.tsx:48-69`
is used with `xAxis.type === AxisType.Time` and `onDrillDown` provided by the
DrillDownHost (drill-down hierarchy configured in the chart controls).

2. Click a data point in the timeseries; the ECharts click event is handled by
`eventHandlers.click` defined in `EchartsTimeseries.tsx:241-264`, which, when
`hasDrillHierarchy` is true, calls `buildTimeseriesDrillFilters` with `data: props.data`
and `name: props.name` (see lines 256-266 where the drill filter params are constructed).

3. In
`superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/drillFilters.ts:85-135`,
`buildTimeseriesDrillFilters` handles non-category axes (time axis) via the branch
starting at line 122: it ignores `data` and builds the filter from `name` (`val: name as
string | number`, `formattedVal: format(name as string | number)` on lines 124-131), while
the same Timeseries file uses `data[0]` as the raw timestamp for drill-to-detail in the
context menu handler (`EchartsTimeseries.tsx:75-86` where `val: data[0]` and
`formattedVal: xValueFormatter(data[0])` are used when `xAxis.type === AxisType.Time`).

4. On time axes, the ECharts click event typically carries the raw timestamp in the series
data tuple (`props.data[0]`) and a formatted axis label in `props.name`; because
`buildTimeseriesDrillFilters` uses `name` instead of the raw axis value, the emitted drill
filters (filtering `col: xAxisLabel` by `val: name`) can contain display strings rather
than the underlying temporal values, causing the backend drill-down query to be scoped to
mismatched values and returning empty or incorrect results, while the drill-to-detail
context menu (which uses `data[0]`) still works as expected—demonstrating the
inconsistency.

Fix in Cursor Fix in VSCode Claude

(Use Cmd/Ctrl + Click for best experience)

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/EchartsTimeseries.tsx
**Line:** 256:266
**Comment:**
	*Logic Error: For time-axis clicks, this forwards `props.name` into drill filter construction, but ECharts click `name` is often the formatted axis label while the raw filterable value is in the data tuple (the same file already uses `data[0]` for time drill-to-detail). This can generate drill filters with display strings instead of raw temporal values and return empty/incorrect drilled results. Use the raw axis value from the clicked data point for non-category axes when building drill filters.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
👍 | 👎

@bito-code-review bito-code-review Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review Agent Run #927598

Actionable Suggestions - 2
  • superset-frontend/src/components/Chart/DrillDown/DrillDownBreadcrumb.test.tsx - 1
  • docs/docs/using-superset/exploring-data.mdx - 1
    • CWE-1104: Deprecated Feature Documented Without Notice · Line 332-350
Review Details
  • Files reviewed - 12 · Commit Range: db42179..7eb64fb
    • superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/EchartsTimeseries.tsx
    • superset-frontend/plugins/plugin-chart-echarts/test/BoxPlot/transformProps.test.ts
    • superset-frontend/src/components/Chart/DrillDown/DrillDownBreadcrumb.test.tsx
    • superset-frontend/src/components/Chart/DrillDown/DrillDownBreadcrumb.tsx
    • superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/drillFilters.ts
    • superset-frontend/plugins/plugin-chart-echarts/test/Timeseries/drillFilters.test.ts
    • superset-frontend/packages/superset-ui-chart-controls/src/sections/drilldownHierarchy.tsx
    • superset-frontend/packages/superset-ui-core/src/utils/featureFlags.ts
    • superset-frontend/src/components/Chart/DrillDown/DrillDownHost.test.tsx
    • superset-frontend/src/components/Chart/DrillDown/DrillDownHost.tsx
    • superset/config.py
    • docs/docs/using-superset/exploring-data.mdx
  • Files skipped - 1
    • docs/static/feature-flags.json - Reason: Filter setting
  • Tools
    • MyPy (Static Code Analysis) - ✔︎ Successful
    • Astral Ruff (Static Code Analysis) - ✔︎ Successful
    • Whispers (Secret Scanner) - ✔︎ Successful
    • Detect-secrets (Secret Scanner) - ✔︎ Successful
    • Eslint (Linter) - ✔︎ Successful

Bito Usage Guide

Commands

Type the following command in the pull request comment and save the comment.

  • /review - Manually triggers a full AI review.

  • /pause - Pauses automatic reviews on this pull request.

  • /resume - Resumes automatic reviews.

  • /resolve - Marks all Bito-posted review comments as resolved.

  • /abort - Cancels all in-progress reviews.

Refer to the documentation for additional commands.

Configuration

This repository uses Superset You can customize the agent settings here or contact your Bito workspace admin at evan@preset.io.

Documentation & Help

AI Code Review powered by Bito Logo

const root = screen.getByText('country');
expect(root).toHaveAttribute('role', 'button');
expect(root).toHaveAttribute('tabindex', '0');
expect(screen.getByText('USA')).toHaveAttribute('role', 'button');

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Incomplete tabindex assertion

Test claims all clickable segments are 'focusable via tabIndex' (line 93-94 comment) but only verifies tabindex on the 'country' element, not on 'USA'. Both segments are created by the same clickable() function which sets tabIndex={0} (DrillDownBreadcrumb.tsx:68). Inconsistent assertion weakens accessibility coverage.

Code Review Run #927598


Should Bito avoid suggestions like this for future reviews? (Manage Rules)

  • Yes, avoid them

Comment on lines +332 to +350
### Drilling into data

Superset offers three distinct "drill" interactions. They are independent, each gated by its own
feature flag, and can be enabled in any combination:

- **Drill to detail** (`DRILL_TO_DETAIL`): right-click a data point and choose **Drill to detail**
to open a modal listing the individual rows that make up that point. It answers "what records are
behind this value?" without changing the chart.
- **Drill by** (`DRILL_BY`): right-click a data point and choose **Drill by** to open a modal that
re-groups the chart by a different dimension, scoped to the clicked value. It answers "how does
this value break down by another column?" and leaves the original chart untouched.
- **Drill-down hierarchy** (`DRILL_DOWN`, off by default): configure an ordered **Drill-down
hierarchy** in the chart's control panel, then left-click a data point on a dashboard chart to
descend to the next level of that hierarchy *in place*. A breadcrumb above the chart lets you
step back up, and each level emits a cross-filter for the accumulated path so the rest of the
dashboard follows along. It answers "let me navigate this dimension hierarchy by clicking."

Drill to detail and Drill by are context-menu actions that open modals; the drill-down hierarchy is
an in-place, click-to-navigate interaction on the dashboard itself.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CWE-1104: Deprecated Feature Documented Without Notice

The DRILL_TO_DETAIL feature flag is deprecated (config.py line 936, lifecycle: deprecated) and was deprecated in version 5.0 (CHANGELOG/5.0.0.md line 462). The documentation should note this status to avoid misleading users about a deprecated feature. Also, the description for DRILL_DOWN implies it follows the same Behavior enum pattern as DrillToDetail/DrillBy, but Behavior.DrillDown does not exist in the Behavior enum (Base.ts lines 25-36); the drill-down feature uses a separate DrillDownHost.tsx implementation on dashboards. (See also: CWE-1104)

Code Review Run #927598


Should Bito avoid suggestions like this for future reviews? (Manage Rules)

  • Yes, avoid them

@rusackas

Copy link
Copy Markdown
Member

I added a hold label to this PR because I believe it's a significant enough change to require a SIP. I think we want to look at the need for an additional drilling method since we already have Drill By that allows a lot of flexibility. So to switch to something hierarchical that require configuration should get some level of consensus. I think we'd want to see the UI in screenshots of how the drilling works. I think we'd want to hear the use cases of why we need a new drilling method or what's insufficient about the existing one, and I think we'll need more detail on how one sets up the hierarchy for hierarchical drilling, especially in terms of semantic layer extensions that are now landing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

change:frontend Requires changing the frontend dashboard:drill-down Related to drill-down functionality of the Dashboard doc Namespace | Anything related to documentation hold:sip! packages plugins size/XXL viz:charts:echarts Related to Echarts

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants