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} -
+ -
+