This is an automated email from the ASF dual-hosted git repository.

kgabryje pushed a commit to branch what-if
in repository https://gitbox.apache.org/repos/asf/superset.git

commit 3df0521b2d5874d2e20e4b1706a945a7106d533c
Author: Kamil Gabryjelski <[email protected]>
AuthorDate: Tue Dec 16 21:29:37 2025 +0100

    BETTER CHART LOADING
---
 superset-frontend/src/components/Chart/Chart.tsx   | 60 ++++++++++++++++++++--
 .../src/components/Chart/ChartRenderer.jsx         | 10 +++-
 .../components/gridComponents/Chart/Chart.jsx      |  9 +++-
 3 files changed, 73 insertions(+), 6 deletions(-)

diff --git a/superset-frontend/src/components/Chart/Chart.tsx 
b/superset-frontend/src/components/Chart/Chart.tsx
index 12522b5314..0be79b6ef1 100644
--- a/superset-frontend/src/components/Chart/Chart.tsx
+++ b/superset-frontend/src/components/Chart/Chart.tsx
@@ -170,6 +170,20 @@ const MessageSpan = styled.span`
   color: ${({ theme }) => theme.colorText};
 `;
 
+const LoadingOverlay = styled.div`
+  position: absolute;
+  top: 0;
+  left: 0;
+  right: 0;
+  bottom: 0;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  justify-content: center;
+  background-color: ${({ theme }) => theme.colorBgMask};
+  z-index: 10;
+`;
+
 class Chart extends PureComponent<ChartProps, {}> {
   static defaultProps = defaultProps;
 
@@ -314,6 +328,23 @@ class Chart extends PureComponent<ChartProps, {}> {
     );
   }
 
+  renderLoadingOverlay(databaseName: string | undefined) {
+    const message = databaseName
+      ? t('Waiting on %s', databaseName)
+      : t('Waiting on database...');
+
+    return (
+      <LoadingOverlay>
+        <Loading
+          position="inline-centered"
+          size={this.props.dashboardId ? 's' : 'm'}
+          muted={!!this.props.dashboardId}
+        />
+        <MessageSpan>{message}</MessageSpan>
+      </LoadingOverlay>
+    );
+  }
+
   render() {
     const {
       height,
@@ -373,6 +404,30 @@ class Chart extends PureComponent<ChartProps, {}> {
       );
     }
 
+    const hasExistingData =
+      ensureIsArray(queriesResponse).length > 0 &&
+      queriesResponse?.some(response => response?.data);
+    const isFirstLoad = isLoading && !hasExistingData;
+
+    if (isFirstLoad) {
+      return (
+        <ErrorBoundary
+          onError={this.handleRenderContainerFailure}
+          showMessage={false}
+        >
+          <Styles
+            data-ui-anchor="chart"
+            className="chart-container"
+            data-test="chart-container"
+            height={height}
+            width={width}
+          >
+            {this.renderSpinner(databaseName)}
+          </Styles>
+        </ErrorBoundary>
+      );
+    }
+
     return (
       <ErrorBoundary
         onError={this.handleRenderContainerFailure}
@@ -385,9 +440,8 @@ class Chart extends PureComponent<ChartProps, {}> {
           height={height}
           width={width}
         >
-          {isLoading
-            ? this.renderSpinner(databaseName)
-            : this.renderChartContainer()}
+          {this.renderChartContainer()}
+          {isLoading && this.renderLoadingOverlay(databaseName)}
         </Styles>
       </ErrorBoundary>
     );
diff --git a/superset-frontend/src/components/Chart/ChartRenderer.jsx 
b/superset-frontend/src/components/Chart/ChartRenderer.jsx
index 61cf48fdb5..ce02be6f8a 100644
--- a/superset-frontend/src/components/Chart/ChartRenderer.jsx
+++ b/superset-frontend/src/components/Chart/ChartRenderer.jsx
@@ -279,8 +279,14 @@ class ChartRenderer extends Component {
   render() {
     const { chartAlert, chartStatus, chartId, emitCrossFilters } = this.props;
 
-    // Skip chart rendering
-    if (chartStatus === 'loading' || !!chartAlert || chartStatus === null) {
+    // Skip chart rendering for errors
+    if (chartAlert) {
+      return null;
+    }
+
+    const hasData =
+      this.mutableQueriesResponse && this.mutableQueriesResponse.length > 0;
+    if (!hasData && (chartStatus === 'loading' || chartStatus === null)) {
       return null;
     }
 
diff --git 
a/superset-frontend/src/dashboard/components/gridComponents/Chart/Chart.jsx 
b/superset-frontend/src/dashboard/components/gridComponents/Chart/Chart.jsx
index 931ea28d40..9cb458718e 100644
--- a/superset-frontend/src/dashboard/components/gridComponents/Chart/Chart.jsx
+++ b/superset-frontend/src/dashboard/components/gridComponents/Chart/Chart.jsx
@@ -21,6 +21,7 @@ import { useCallback, useEffect, useRef, useMemo, useState, 
memo } from 'react';
 import PropTypes from 'prop-types';
 import { t, logging } from '@superset-ui/core';
 import { styled } from '@apache-superset/core/ui';
+import { Loading } from '@superset-ui/core/components';
 import { debounce } from 'lodash';
 import { useHistory } from 'react-router-dom';
 import { bindActionCreators } from 'redux';
@@ -103,6 +104,10 @@ const ChartOverlay = styled.div`
   top: 0;
   left: 0;
   z-index: 5;
+  background-color: ${({ theme }) => theme.colorBgMask};
+  display: flex;
+  align-items: center;
+  justify-content: center;
 `;
 
 const SliceContainer = styled.div`
@@ -684,7 +689,9 @@ const Chart = props => {
               width,
               height: getChartHeight(),
             }}
-          />
+          >
+            <Loading size="s" muted />
+          </ChartOverlay>
         )}
 
         <ChartContainer

Reply via email to