Chart Form Data Hydration#
When a chart opens in the Explore view, its form_data is assembled from up to four sources — permalink, cache, slice DB record, and dashboard context — in a layered pipeline that spans a backend command, a frontend page component, and a Redux action. Understanding this pipeline is essential for debugging unexpected filter state, color scheme issues, or stale chart configurations.
Pipeline Overview#
URL params (permalink key / form_data_key / slice_id / datasource_id)
│
▼
[Backend] GetExploreCommand.run() ← resolves initial_form_data
│ 1. permalink → GetExplorePermalinkCommand
│ 2. form_data_key → GetFormDataCommand (Redis/cache)
│ 3. fallback → slice_id or datasource_id
│
▼
[Backend] get_form_data() ← merges slice DB record
│ • slice.form_data (DB) is base
│ • initial_form_data overrides it
│ • request body/query-string params override further
│
▼
[Backend] convert_legacy_filters, merge_extra_filters, merge_request_params
│
▼
GET /api/v1/explore/ ──────────── response: { form_data, slice, dataset, metadata }
│
▼
[Frontend] ExplorePage (src/pages/Chart/index.tsx)
│ • reads LocalStorageKeys.DashboardExploreContext[pageId]
│ • builds dashboardContextFormData via getFormDataWithExtraFilters()
│ • merges with API result via getFormDataWithDashboardContext()
│
▼
[Frontend] hydrateExplore() ← populates Redux state
• defaults viz_type, time_range
• verifies color scheme registry; falls back to default
• runs getControlsState() + applyMapStateToPropsToControl()
• dispatches HYDRATE_EXPLORE
Stage 1 — Backend: GetExploreCommand#
GetExploreCommand.run() resolves initial_form_data from one of three inputs, in priority order:
- Permalink — if
permalink_keyis set,GetExplorePermalinkCommandfetches the stored state (form data + optional URL params). - Cache key — if
form_data_keyis set,GetFormDataCommandretrieves form data from the cache (Redis by default). If the cache entry is missing, a warning message is set and the fallback below is used . - Slice / datasource IDs — bare
slice_idordatasource_idfrom URL params become the seed forinitial_form_data.
This initial_form_data is then passed to get_form_data().
Stage 2 — Backend: get_form_data()#
get_form_data() performs the core server-side merge:
- Starts from
initial_form_dataas the base dict . - Overlays request body (
form_dataPOST field) and then query-stringform_dataparams — later values win . - If a
slice_idis present anduse_slice_data=True, loads theSlicerecord from the DB and appliesslice_form_dataas the base, then overlaysform_dataon top — so the saved slice is the baseline and transient params override it . - Calls
update_time_range()to normalize legacy time range formats .
Back in GetExploreCommand, three additional server-side merges happen after get_form_data() returns :
convert_legacy_filters_into_adhoc— migrates old filter format.merge_extra_filters— foldsextra_filtersintoadhoc_filters.merge_request_params— injects remaining URL query parameters.
The response payload sent to the frontend includes form_data, slice, dataset, and metadata .
Stage 3 — Frontend: Dashboard Context Merge (ExplorePage)#
ExplorePage orchestrates the frontend portion of hydration.
Dashboard context lookup: When Explore is opened from a dashboard tab, SyncDashboardState has already written dashboard state into localStorage under LocalStorageKeys.DashboardExploreContext. ExplorePage reads it back via getDashboardPageContext(pageId) using the dashboardPageId URL param as the key .
The retrieved context contains: colorScheme, labelsColor, labelsColorMap, sharedLabelsColors, chartConfiguration, nativeFilters, filterBoxFilters, dataMask, and dashboardId .
This context is fed through getFormDataWithExtraFilters() to build a fully populated dashboardContextFormData , which is then merged with the API result using getFormDataWithDashboardContext() — but only on the initial page load, not on subsequent re-renders or save actions.
Stage 4 — Frontend: getFormDataWithDashboardContext()#
getFormDataWithDashboardContext() applies the actual merge logic:
- Filter box filters (
extra_filters) are converted to adhoc filters, with time-column pseudo-filters (__time_range,__time_col, etc.) mapped to their corresponding form data keys . - Native filters (
extra_form_data) are applied viaEXTRA_FORM_DATA_OVERRIDE_REGULAR_MAPPINGSandEXTRA_FORM_DATA_OVERRIDE_EXTRA_KEYS, with additional handling fortime_grain_sqlaandgranularity_sqla. - Adhoc filters from all three sources (explore, filter box, native filters) are merged and deduplicated via
removeAdhocFilterDuplicates(), then time-range filters are applied viaapplyTimeRangeFilters(). - Color scheme priority:
dashboardColorScheme || ownColorScheme— the dashboard scheme wins; the chart's own scheme is preserved asown_color_scheme. - The final result is a spread merge:
{ ...exploreFormData, ...dashboardContextFormData, ...filterBoxData, ...nativeFiltersData, ...adhocFilters }.
Stage 5 — Frontend: hydrateExplore()#
hydrateExplore() ingests the merged form data and finalizes the Redux state:
- Defaults:
viz_typefalls back toDEFAULT_VIZ_TYPE→VizType.Table;time_rangefalls back toDEFAULT_TIME_FILTER→NO_TIME_RANGE. include_timehandling: Ifinclude_timeis enabled with agranularity_sqlacolumn, it is prepended togroupbyand cleared .- Color scheme verification: If the saved
color_schemeno longer exists in the scheme registry, it falls back toregistryDefaultScheme || 'supersetColors'(categorical) or'superset_seq_1'(sequential) . - Control state:
getControlsState()materializes the control panel state from form data;applyMapStateToPropsToControl()is then run over every control to resolve dependent control values . - Dispatches
HYDRATE_EXPLOREwith the assembled charts, datasources, and explore state .
Key Files#
| File | Role |
|---|---|
superset/commands/explore/get.py | Backend entry point; resolves permalink/cache/slice |
superset/views/utils.py — get_form_data() | Merges slice DB record with request params |
src/pages/Chart/index.tsx | Frontend entry; reads localStorage, calls merge, dispatches hydration |
src/explore/controlUtils/getFormDataWithDashboardContext.ts | Merges dashboard filters, native filters, and color scheme |
src/explore/actions/hydrateExplore.ts | Finalizes Redux state, defaults, color scheme verification |