diff --git a/superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-preset-chart-xy/src/components/ChartFrame.jsx b/superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-preset-chart-xy/src/components/ChartFrame.jsx
deleted file mode 100644
index fac6eb65a26e4..0000000000000
--- a/superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-preset-chart-xy/src/components/ChartFrame.jsx
+++ /dev/null
@@ -1,50 +0,0 @@
-import React from 'react';
-import PropTypes from 'prop-types';
-import { isDefined } from '@superset-ui/core';
-
-const propTypes = {
- contentHeight: PropTypes.number,
- contentWidth: PropTypes.number,
- height: PropTypes.number.isRequired,
- renderContent: PropTypes.func,
- width: PropTypes.number.isRequired,
-};
-const defaultProps = {
- contentHeight: null,
- contentWidth: null,
- renderContent() {},
-};
-
-class ChartFrame extends React.PureComponent {
- render() {
- const { contentWidth, contentHeight, width, height, renderContent } = this.props;
-
- const overflowX = isDefined(contentWidth) && contentWidth > width;
- const overflowY = isDefined(contentHeight) && contentHeight > height;
-
- if (overflowX || overflowY) {
- return (
-
- {renderContent({
- height: contentHeight,
- width: contentWidth,
- })}
-
- );
- }
-
- return renderContent({ height, width });
- }
-}
-
-ChartFrame.propTypes = propTypes;
-ChartFrame.defaultProps = defaultProps;
-
-export default ChartFrame;
diff --git a/superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-preset-chart-xy/src/components/ChartFrame.tsx b/superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-preset-chart-xy/src/components/ChartFrame.tsx
new file mode 100644
index 0000000000000..29974570bf09b
--- /dev/null
+++ b/superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-preset-chart-xy/src/components/ChartFrame.tsx
@@ -0,0 +1,47 @@
+import React from 'react';
+import { isDefined } from '@superset-ui/core';
+
+function checkNumber(input: any): input is number {
+ return isDefined(input) && typeof input === 'number';
+}
+
+type Props = {
+ contentWidth?: number;
+ contentHeight?: number;
+ height: number;
+ renderContent: ({ height, width }: { height: number; width: number }) => React.ReactElement;
+ width: number;
+};
+
+export default class ChartFrame extends React.PureComponent {
+ static defaultProps = {
+ renderContent() {},
+ };
+
+ render() {
+ const { contentWidth, contentHeight, width, height, renderContent } = this.props;
+
+ const overflowX = checkNumber(contentWidth) && contentWidth > width;
+ const overflowY = checkNumber(contentHeight) && contentHeight > height;
+
+ if (overflowX || overflowY) {
+ return (
+
+ {renderContent({
+ height: Math.max(contentHeight || 0, height),
+ width: Math.max(contentWidth || 0, width),
+ })}
+
+ );
+ }
+
+ return renderContent({ height, width });
+ }
+}
diff --git a/superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-preset-chart-xy/src/components/WithLegend.jsx b/superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-preset-chart-xy/src/components/WithLegend.tsx
similarity index 68%
rename from superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-preset-chart-xy/src/components/WithLegend.jsx
rename to superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-preset-chart-xy/src/components/WithLegend.tsx
index bdbf075214cfe..bac3829925d7f 100644
--- a/superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-preset-chart-xy/src/components/WithLegend.jsx
+++ b/superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-preset-chart-xy/src/components/WithLegend.tsx
@@ -17,30 +17,23 @@
* under the License.
*/
/* eslint-disable sort-keys */
-import React from 'react';
-import PropTypes from 'prop-types';
+import React, { CSSProperties, ReactNode } from 'react';
import { ParentSize } from '@vx/responsive';
+// eslint-disable-next-line import/no-unresolved
+import * as CSS from 'csstype';
-const propTypes = {
- className: PropTypes.string,
- width: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
- height: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
- legendJustifyContent: PropTypes.oneOf(['center', 'flex-start', 'flex-end']),
- position: PropTypes.oneOf(['top', 'left', 'bottom', 'right']),
- renderChart: PropTypes.func.isRequired,
- renderLegend: PropTypes.func.isRequired,
- hideLegend: PropTypes.bool,
-};
-const defaultProps = {
- className: '',
- width: 'auto',
- height: 'auto',
- legendJustifyContent: undefined,
- position: 'top',
- hideLegend: false,
+type Props = {
+ className: string;
+ width: number | string;
+ height: number | string;
+ legendJustifyContent: 'center' | 'flex-start' | 'flex-end';
+ position: 'top' | 'left' | 'bottom' | 'right';
+ renderChart: (dim: { width: number; height: number }) => ReactNode;
+ renderLegend: (params: { direction: string }) => ReactNode;
+ hideLegend: boolean;
};
-const LEGEND_STYLE_BASE = {
+const LEGEND_STYLE_BASE: CSSProperties = {
display: 'flex',
flexGrow: 0,
flexShrink: 0,
@@ -49,15 +42,24 @@ const LEGEND_STYLE_BASE = {
fontSize: '0.9em',
};
-const CHART_STYLE_BASE = {
+const CHART_STYLE_BASE: CSSProperties = {
flexGrow: 1,
flexShrink: 1,
flexBasis: 'auto',
position: 'relative',
};
-class WithLegend extends React.Component {
- getContainerDirection() {
+class WithLegend extends React.PureComponent {
+ static defaultProps = {
+ className: '',
+ width: 'auto',
+ height: 'auto',
+ legendJustifyContent: undefined,
+ position: 'top',
+ hideLegend: false,
+ };
+
+ getContainerDirection(): CSS.FlexDirectionProperty {
const { position } = this.props;
switch (position) {
case 'left':
@@ -101,13 +103,9 @@ class WithLegend extends React.Component {
hideLegend,
} = this.props;
- if (hideLegend) {
- return {renderChart({ width, height })}
;
- }
-
const isHorizontal = position === 'left' || position === 'right';
- const style = {
+ const style: CSSProperties = {
display: 'flex',
flexDirection: this.getContainerDirection(),
};
@@ -118,7 +116,7 @@ class WithLegend extends React.Component {
style.height = height;
}
- const chartStyle = { ...CHART_STYLE_BASE };
+ const chartStyle: CSSProperties = { ...CHART_STYLE_BASE };
if (isHorizontal) {
chartStyle.width = 0;
} else {
@@ -126,7 +124,7 @@ class WithLegend extends React.Component {
}
const legendDirection = isHorizontal ? 'column' : 'row';
- const legendStyle = {
+ const legendStyle: CSSProperties = {
...LEGEND_STYLE_BASE,
flexDirection: legendDirection,
justifyContent: this.getLegendJustifyContent(),
@@ -134,15 +132,17 @@ class WithLegend extends React.Component {
return (
-
- {renderLegend({
- // Pass flexDirection for @vx/legend to arrange legend items
- direction: legendDirection,
- })}
-
+ {!hideLegend && (
+
+ {renderLegend({
+ // Pass flexDirection for @vx/legend to arrange legend items
+ direction: legendDirection,
+ })}
+
+ )}
- {parent =>
+ {(parent: { width: number; height: number }) =>
parent.width > 0 && parent.height > 0
? // Only render when necessary
renderChart(parent)
@@ -155,7 +155,4 @@ class WithLegend extends React.Component {
}
}
-WithLegend.propTypes = propTypes;
-WithLegend.defaultProps = defaultProps;
-
export default WithLegend;
diff --git a/superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-preset-chart-xy/src/components/tooltip/TooltipFrame.tsx b/superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-preset-chart-xy/src/components/tooltip/TooltipFrame.tsx
new file mode 100644
index 0000000000000..a37df9ab384f9
--- /dev/null
+++ b/superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-preset-chart-xy/src/components/tooltip/TooltipFrame.tsx
@@ -0,0 +1,26 @@
+import React from 'react';
+
+type Props = {
+ className?: string;
+ children: React.ReactNode;
+};
+
+const CONTAINER_STYLE = { padding: 8 };
+
+class TooltipFrame extends React.PureComponent {
+ static defaultProps = {
+ className: '',
+ };
+
+ render() {
+ const { className, children } = this.props;
+
+ return (
+
+ {children}
+
+ );
+ }
+}
+
+export default TooltipFrame;
diff --git a/superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-preset-chart-xy/src/components/tooltip/TooltipTable.tsx b/superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-preset-chart-xy/src/components/tooltip/TooltipTable.tsx
new file mode 100644
index 0000000000000..aeee7f88ad656
--- /dev/null
+++ b/superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-preset-chart-xy/src/components/tooltip/TooltipTable.tsx
@@ -0,0 +1,39 @@
+import React, { CSSProperties } from 'react';
+
+type Props = {
+ className?: string;
+ data: {
+ key: string;
+ keyStyle?: CSSProperties;
+ value: string | number;
+ valueStyle?: CSSProperties;
+ }[];
+};
+
+const VALUE_CELL_STYLE: CSSProperties = { paddingLeft: 8, textAlign: 'right' };
+
+export default class TooltipTable extends React.PureComponent {
+ static defaultProps = {
+ className: '',
+ data: [],
+ };
+
+ render() {
+ const { className, data } = this.props;
+
+ return (
+
+
+ {data.map(({ key, keyStyle, value, valueStyle }) => (
+
+ {key} |
+
+ {value}
+ |
+
+ ))}
+
+
+ );
+ }
+}