diff --git a/superset-frontend/package-lock.json b/superset-frontend/package-lock.json
index 1f6ee258c3c2b..5b84de38ef37c 100644
--- a/superset-frontend/package-lock.json
+++ b/superset-frontend/package-lock.json
@@ -39196,6 +39196,11 @@
"integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=",
"dev": true
},
+ "lodash.throttle": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz",
+ "integrity": "sha1-wj6RtxAkKscMN/HhzaknTMOb8vQ="
+ },
"lodash.topath": {
"version": "4.5.2",
"resolved": "https://registry.npmjs.org/lodash.topath/-/lodash.topath-4.5.2.tgz",
@@ -44133,6 +44138,11 @@
"performance-now": "^2.1.0"
}
},
+ "raf-schd": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/raf-schd/-/raf-schd-4.0.2.tgz",
+ "integrity": "sha512-VhlMZmGy6A6hrkJWHLNTGl5gtgMUm+xfGza6wbwnE914yeQ5Ybm18vgM734RZhMgfw4tacUrWseGZlpUrrakEQ=="
+ },
"railroad-diagrams": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/railroad-diagrams/-/railroad-diagrams-1.0.0.tgz",
@@ -46510,6 +46520,17 @@
}
}
},
+ "react-resize-detector": {
+ "version": "6.0.1-rc.1",
+ "resolved": "https://registry.npmjs.org/react-resize-detector/-/react-resize-detector-6.0.1-rc.1.tgz",
+ "integrity": "sha512-r+UZtJottPZaW/2CKAyb4Vgpi6KROsXBH890UChK7mB8DSFf8nEvwqpvE9akfd8wQOGi0cXekcGLHzYp9FiscA==",
+ "requires": {
+ "lodash.debounce": "^4.0.8",
+ "lodash.throttle": "^4.1.1",
+ "raf-schd": "^4.0.2",
+ "resize-observer-polyfill": "^1.5.1"
+ }
+ },
"react-router": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/react-router/-/react-router-5.1.2.tgz",
diff --git a/superset-frontend/package.json b/superset-frontend/package.json
index d30a070f1ee4e..48efeba88a4e6 100644
--- a/superset-frontend/package.json
+++ b/superset-frontend/package.json
@@ -150,6 +150,7 @@
"react-loadable": "^5.5.0",
"react-markdown": "^4.3.1",
"react-redux": "^7.2.0",
+ "react-resize-detector": "^6.0.1-rc.1",
"react-router-dom": "^5.1.2",
"react-search-input": "^0.11.3",
"react-select": "^3.1.0",
diff --git a/superset-frontend/src/explore/components/DatasourcePanel.tsx b/superset-frontend/src/explore/components/DatasourcePanel.tsx
index b185ea1a335f3..95b9d3f1974ac 100644
--- a/superset-frontend/src/explore/components/DatasourcePanel.tsx
+++ b/superset-frontend/src/explore/components/DatasourcePanel.tsx
@@ -141,6 +141,24 @@ const DatasourceContainer = styled.div`
}
`;
+const LabelContainer = styled.div`
+ overflow: hidden;
+ text-overflow: ellipsis;
+
+ & > span {
+ white-space: nowrap;
+ }
+
+ .option-label {
+ display: inline;
+ }
+
+ .metric-option > .option-label {
+ overflow: hidden;
+ text-overflow: ellipsis;
+ }
+`;
+
const DataSourcePanel = ({
datasource,
controls: { datasource: datasourceControl },
@@ -200,9 +218,9 @@ const DataSourcePanel = ({
{t(`Showing %s of %s`, metricSlice.length, metrics.length)}
{metricSlice.map(m => (
-
+
-
+
))}
{columnSlice.map(col => (
-
+
-
+
))}
diff --git a/superset-frontend/src/explore/components/ExploreChartPanel.jsx b/superset-frontend/src/explore/components/ExploreChartPanel.jsx
index 75fde2f72db5b..2fd0338c56e95 100644
--- a/superset-frontend/src/explore/components/ExploreChartPanel.jsx
+++ b/superset-frontend/src/explore/components/ExploreChartPanel.jsx
@@ -16,12 +16,11 @@
* specific language governing permissions and limitations
* under the License.
*/
-import React, { useState, useEffect, useRef, useCallback } from 'react';
+import React, { useState, useEffect, useCallback, useMemo } from 'react';
import PropTypes from 'prop-types';
import Split from 'react-split';
-import { ParentSize } from '@vx/responsive';
import { styled, useTheme } from '@superset-ui/core';
-import debounce from 'lodash/debounce';
+import { useResizeDetector } from 'react-resize-detector';
import { chartPropShape } from 'src/dashboard/util/propShapes';
import ChartContainer from 'src/chart/ChartContainer';
import ConnectedExploreChartHeader from './ExploreChartHeader';
@@ -55,6 +54,7 @@ const propTypes = {
const GUTTER_SIZE_FACTOR = 1.25;
const CHART_PANEL_PADDING = 30;
+const HEADER_PADDING = 15;
const INITIAL_SIZES = [90, 10];
const MIN_SIZES = [300, 50];
@@ -104,20 +104,32 @@ const ExploreChartPanel = props => {
const gutterMargin = theme.gridUnit * GUTTER_SIZE_FACTOR;
const gutterHeight = theme.gridUnit * GUTTER_SIZE_FACTOR;
- const panelHeadingRef = useRef(null);
+ const { height: hHeight, ref: headerRef } = useResizeDetector({
+ refreshMode: 'debounce',
+ refreshRate: 300,
+ });
+ const { width: chartWidth, ref: chartRef } = useResizeDetector({
+ refreshMode: 'debounce',
+ refreshRate: 300,
+ });
const [splitSizes, setSplitSizes] = useState(INITIAL_SIZES);
const calcSectionHeight = useCallback(
percent => {
- const headerHeight = props.standalone
- ? 0
- : panelHeadingRef?.current?.offsetHeight ?? 50;
+ let headerHeight;
+ if (props.standalone) {
+ headerHeight = 0;
+ } else if (hHeight) {
+ headerHeight = hHeight + HEADER_PADDING;
+ } else {
+ headerHeight = 50;
+ }
const containerHeight = parseInt(props.height, 10) - headerHeight;
return (
(containerHeight * percent) / 100 - (gutterHeight / 2 + gutterMargin)
);
},
- [gutterHeight, gutterMargin, props.height, props.standalone],
+ [gutterHeight, gutterMargin, props.height, props.standalone, hHeight],
);
const [tableSectionHeight, setTableSectionHeight] = useState(
@@ -132,15 +144,11 @@ const ExploreChartPanel = props => {
);
useEffect(() => {
- const recalcSizes = debounce(() => recalcPanelSizes(splitSizes), 200);
-
- window.addEventListener('resize', recalcSizes);
- return () => window.removeEventListener('resize', recalcSizes);
- }, [props.standalone, recalcPanelSizes, splitSizes]);
+ recalcPanelSizes(splitSizes);
+ }, [recalcPanelSizes, splitSizes]);
const onDragEnd = sizes => {
setSplitSizes(sizes);
- recalcPanelSizes(sizes);
};
const onCollapseChange = openPanelName => {
@@ -154,42 +162,46 @@ const ExploreChartPanel = props => {
];
}
setSplitSizes(splitSizes);
- recalcPanelSizes(splitSizes);
};
- const renderChart = () => {
+ const renderChart = useCallback(() => {
const { chart } = props;
const newHeight = calcSectionHeight(splitSizes[0]) - CHART_PANEL_PADDING;
return (
-
- {({ width }) =>
- width > 0 && (
-
- )
- }
-
+ chartWidth > 0 && (
+
+ )
);
- };
+ }, [calcSectionHeight, chartWidth, props, splitSizes]);
+
+ const panelBody = useMemo(
+ () => (
+
+ {renderChart()}
+
+ ),
+ [chartRef, renderChart],
+ );
if (props.standalone) {
// dom manipulation hack to get rid of the boostrap theme's body background
@@ -222,14 +234,12 @@ const ExploreChartPanel = props => {
[dimension]: `calc(${elementSize}% - ${gutterSize + gutterMargin}px)`,
});
- const panelBody = {renderChart()}
;
-
return (
-
+
{header}
{props.vizType === 'filter_box' ? (
diff --git a/superset-frontend/src/explore/components/ExploreViewContainer.jsx b/superset-frontend/src/explore/components/ExploreViewContainer.jsx
index 6599890f0f501..1a701df8e180a 100644
--- a/superset-frontend/src/explore/components/ExploreViewContainer.jsx
+++ b/superset-frontend/src/explore/components/ExploreViewContainer.jsx
@@ -23,6 +23,7 @@ import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import { styled, t, supersetTheme, css } from '@superset-ui/core';
import { debounce } from 'lodash';
+import { Resizable } from 're-resizable';
import { useDynamicPluginContext } from 'src/components/DynamicPlugins';
import { Global } from '@emotion/core';
@@ -81,10 +82,8 @@ const Styles = styled.div`
border-top: 1px solid ${({ theme }) => theme.colors.grayscale.light2};
.explore-column {
display: flex;
- flex: 0 0 ${({ theme }) => theme.gridUnit * 95}px;
flex-direction: column;
padding: ${({ theme }) => 2 * theme.gridUnit}px 0;
- max-width: ${({ theme }) => theme.gridUnit * 95}px;
max-height: 100%;
}
.data-source-selection {
@@ -404,7 +403,11 @@ function ExploreViewContainer(props) {
dashboardId={props.dashboardId}
/>
)}
-
-
+
{isCollapsed ? (
) : null}
-
+
-
+