You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by vi...@apache.org on 2026/10/16 22:12:07 UTC
(superset) 17/17: fix(dashboard): apply temporal x-axis cross-filters to target charts (#45310)
This is an automated email from the ASF dual-hosted git repository.
villebro pushed a commit to branch 7.0
in repository https://gitbox.apache.org/repos/asf/superset.git
commit 76a20ae554ecd21799efe50b499e9da635437221
Author: Madhushree <ma...@gmail.com>
AuthorDate: Fri Oct 16 12:30:36 2026 -0700
fix(dashboard): apply temporal x-axis cross-filters to target charts (#45310)
Co-authored-by: madhushree agarwal <ma...@apple.com>
(cherry picked from commit 853f207c668717c13514b2033fffcf5dd3805b98)
---
.../src/Timeseries/EchartsTimeseries.tsx | 4 ++
.../test/Timeseries/EchartsTimeseries.test.tsx | 6 +++
.../util/charts/getFormDataWithExtraFilters.ts | 7 +++-
.../util/getFormDataWithExtraFilters.test.ts | 49 ++++++++++++++++++++++
4 files changed, 65 insertions(+), 1 deletion(-)
diff --git a/superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/EchartsTimeseries.tsx b/superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/EchartsTimeseries.tsx
index d8db68da7ba..09d8ed2db7e 100644
--- a/superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/EchartsTimeseries.tsx
+++ b/superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/EchartsTimeseries.tsx
@@ -471,6 +471,10 @@ export default function EchartsTimeseries({
val: timeRange,
},
],
+ // The backend rewrites every TEMPORAL_RANGE filter's value with the
+ // query's time_range, so without this override target charts would
+ // keep their own saved range and ignore the clicked bucket.
+ ...(values.length ? { time_range: timeRange } : {}),
},
filterState: {
label: values.length ? values : undefined,
diff --git a/superset-frontend/plugins/plugin-chart-echarts/test/Timeseries/EchartsTimeseries.test.tsx b/superset-frontend/plugins/plugin-chart-echarts/test/Timeseries/EchartsTimeseries.test.tsx
index 72104b286e5..bbfa155be36 100644
--- a/superset-frontend/plugins/plugin-chart-echarts/test/Timeseries/EchartsTimeseries.test.tsx
+++ b/superset-frontend/plugins/plugin-chart-echarts/test/Timeseries/EchartsTimeseries.test.tsx
@@ -523,6 +523,7 @@ test('emits TEMPORAL_RANGE cross-filter from time axis label click on day bucket
val: '2021-01-01T00:00:00 : 2021-01-02T00:00:00',
},
],
+ time_range: '2021-01-01T00:00:00 : 2021-01-02T00:00:00',
},
filterState: {
label: ['2021-01-01T00:00:00 : 2021-01-02T00:00:00'],
@@ -568,6 +569,11 @@ test('emits upper-exclusive TEMPORAL_RANGE from time point click on month bucket
val: '2021-01-01T00:00:00 : 2021-02-01T00:00:00',
},
]);
+ // Target charts' own TEMPORAL_RANGE filters are rewritten from time_range on
+ // the backend, so the clicked bucket must be sent as time_range as well.
+ expect(setDataMask.mock.calls[0][0].extraFormData.time_range).toBe(
+ '2021-01-01T00:00:00 : 2021-02-01T00:00:00',
+ );
});
test('uses resolved time grain for temporal point-click cross-filter', () => {
diff --git a/superset-frontend/src/dashboard/util/charts/getFormDataWithExtraFilters.ts b/superset-frontend/src/dashboard/util/charts/getFormDataWithExtraFilters.ts
index 71c399aa0cf..676ff087179 100644
--- a/superset-frontend/src/dashboard/util/charts/getFormDataWithExtraFilters.ts
+++ b/superset-frontend/src/dashboard/util/charts/getFormDataWithExtraFilters.ts
@@ -473,9 +473,14 @@ export default function getFormDataWithExtraFilters({
});
let extraData: JsonObject = {};
+ // Cross-filter ids are chart ids, so plain key order would put them before
+ // native filter ids and let a native filter's override keys (e.g. a Time
+ // Range filter's time_range) replace the cross-filter's. Merge native
+ // filters first so a cross-filter selection takes precedence.
const filterIdsAppliedOnChart = Object.entries(activeFilters)
.filter(([, activeFilter]) => activeFilter?.scope?.includes(chart.id))
- .map(([filterId]) => filterId);
+ .map(([filterId]) => filterId)
+ .sort((a, b) => Number(!nativeFilters?.[a]) - Number(!nativeFilters?.[b]));
if (filterIdsAppliedOnChart.length) {
const aggregatedFormData = getExtraFormData(
diff --git a/superset-frontend/src/dashboard/util/getFormDataWithExtraFilters.test.ts b/superset-frontend/src/dashboard/util/getFormDataWithExtraFilters.test.ts
index aca21a5f166..9b2b727880c 100644
--- a/superset-frontend/src/dashboard/util/getFormDataWithExtraFilters.test.ts
+++ b/superset-frontend/src/dashboard/util/getFormDataWithExtraFilters.test.ts
@@ -276,6 +276,55 @@ test('should merge both filters and customization extraFormData', () => {
expect(result.extra_form_data).toBeDefined();
});
+test('cross-filter time_range takes precedence over a native time range filter', () => {
+ const nativeTimeFilterId = 'NATIVE_FILTER-time';
+ const crossFilterId = '42';
+ const nativeRange = 'Last week';
+ const clickedRange = '2021-01-01T00:00:00 : 2021-01-02T00:00:00';
+ const result = getFormDataWithExtraFilters({
+ ...mockArgs,
+ nativeFilters: {
+ [nativeTimeFilterId]: {
+ id: nativeTimeFilterId,
+ chartsInScope: [chartId],
+ },
+ } as unknown as GetFormDataWithExtraFiltersArguments['nativeFilters'],
+ activeFilters: {
+ [nativeTimeFilterId]: {
+ targets: [],
+ scope: [chartId],
+ values: { time_range: nativeRange },
+ },
+ [crossFilterId]: {
+ targets: [],
+ scope: [chartId],
+ values: { time_range: clickedRange },
+ },
+ },
+ dataMask: {
+ [nativeTimeFilterId]: {
+ id: nativeTimeFilterId,
+ extraFormData: { time_range: nativeRange },
+ filterState: { value: nativeRange },
+ ownState: {},
+ },
+ [crossFilterId]: {
+ id: crossFilterId,
+ extraFormData: {
+ filters: [{ col: 'ds', op: 'TEMPORAL_RANGE', val: clickedRange }],
+ time_range: clickedRange,
+ },
+ filterState: { value: [clickedRange] },
+ ownState: {},
+ },
+ },
+ });
+
+ expect(result.extra_form_data).toEqual(
+ expect.objectContaining({ time_range: clickedRange }),
+ );
+});
+
const makeGroupByArgs = (
selectedValue: string | string[],
baseGroupby: string[] = [],