sadpandajoe commented on code in PR #45541:
URL: https://github.com/apache/superset/pull/45541#discussion_r4376023294
##########
superset-frontend/src/components/Chart/ChartRenderer.tsx:
##########
@@ -282,25 +328,53 @@ function ChartRendererComponent({
const chartEnableNoResults =
getChartMetadataRegistry().get(vizType)?.enableNoResults ?? true;
- // A failed load leaves its errored response in the store, and the next
- // CHART_UPDATE_STARTED clears chartAlert but not queriesResponse. Checking
- // the response itself keeps that stale error from being drawn as chart data
- // while the retry is in flight.
- const hasAnyErrors = queriesResponse?.some(item => item?.error);
- // The response of a chart that fetches its own data stays empty once it has
- // loaded, so for those any response that landed counts as previous data.
- const hasPreviousResponse = chartEnableNoResults
- ? (queriesResponse?.length ?? 0) > 0
- : Array.isArray(queriesResponse);
- const hasValidPreviousData = hasPreviousResponse && !hasAnyErrors;
-
- // An auto-refresh keeps the chart on screen while its query is in flight.
- // The store holds the previous response until the new one lands, so that
- // response is what the chart renders in the meantime.
- const isRefreshing =
+ // A dashboard keeps the chart on screen while its query is in flight, be it
+ // an auto-refresh, a manual refresh or a filter change. The store holds the
+ // previous response until the new one lands, so that response is what the
+ // chart renders in the meantime.
+ const isAutoRefreshing =
Boolean(restProps.suppressLoadingSpinner) && chartStatus === 'loading';
+ const isRefreshing =
+ chartStatus === 'loading' &&
+ (isAutoRefreshing || source === ChartSource.Dashboard);
const hasRenderableResults =
- resultsReady || (isRefreshing && hasValidPreviousData);
+ resultsReady ||
+ (isRefreshing &&
+ responseFormData !== undefined &&
+ hasValidPreviousData(queriesResponse, responseFormData, vizType));
+
+ // A filter change updates formData as soon as the new query starts, so the
+ // previous response is drawn with the form data it was queried with until
+ // the new one lands. What changes without a new query always comes from the
+ // current form data: the dashboard's colours, and the controls a chart sets
+ // on itself, such as an Area chart's stack toggle or a map's viewport.
+ //
+ // A plugin transforms and redraws the chart whenever it gets a new form data
+ // object, and an ECharts chart replays its entrance animation when it does.
+ // When the chart is already drawn with the same values, as it is when a
+ // refresh starts with nothing changed, it keeps the object it has.
+ const drawnFormDataRef = useRef(currentFormData);
+ const renderedFormData = useMemo(() => {
+ let nextFormData = currentFormData;
+ if (isRefreshing && responseFormData) {
+ nextFormData = { ...responseFormData };
+ [...DASHBOARD_COLOR_KEYS, ...getDisplayControlNames(vizType)].forEach(
+ key => {
+ if (key in currentFormData) {
+ nextFormData[key] = currentFormData[key];
+ } else {
+ delete nextFormData[key];
+ }
+ },
+ );
+ }
+ return isEqual(nextFormData, drawnFormDataRef.current)
+ ? drawnFormDataRef.current
+ : nextFormData;
+ }, [isRefreshing, responseFormData, currentFormData, vizType]);
+ useEffect(() => {
+ drawnFormDataRef.current = renderedFormData;
Review Comment:
Deleting this effect leaves the new no-redraw test green, because its form
data never changes, so `drawnFormDataRef` always holds the first object.
Without the effect, once a filter change completes and the next refresh starts
with nothing changed, the rebuilt form data no longer matches that stale ref
and the plugin transforms the retained chart again, replaying the ECharts
entrance animation this test guards against. Could the test go through a
completed filter change (new `formData` and response), then a second refresh
with nothing changed, and assert `testChartTransformed` isn't called again?
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]