fix(explore): Fix downloading as image charts which use Mapbox (#13181)

* Fix downloading as image charts which use Mapbox

* Remove unused prop

* Bump deckgl version
This commit is contained in:
Kamil Gabryjelski 2021-02-20 18:45:03 +01:00 committed by GitHub
parent 19a60435b0
commit c1aacde304
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 30 additions and 22 deletions

View File

@ -35,7 +35,7 @@
"@superset-ui/legacy-plugin-chart-treemap": "^0.17.9",
"@superset-ui/legacy-plugin-chart-world-map": "^0.17.9",
"@superset-ui/legacy-preset-chart-big-number": "^0.17.9",
"@superset-ui/legacy-preset-chart-deckgl": "^0.4.1",
"@superset-ui/legacy-preset-chart-deckgl": "^0.4.2",
"@superset-ui/legacy-preset-chart-nvd3": "^0.17.9",
"@superset-ui/plugin-chart-echarts": "^0.17.9",
"@superset-ui/plugin-chart-table": "^0.17.9",
@ -14579,9 +14579,9 @@
}
},
"node_modules/@superset-ui/legacy-preset-chart-deckgl": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/@superset-ui/legacy-preset-chart-deckgl/-/legacy-preset-chart-deckgl-0.4.1.tgz",
"integrity": "sha512-3THN+WM8HUU1NlV3VNXRVS1j2jH33CmVAdyPNB35RqtwkY+udgFGOxm0lXumcUElht/3ROGMPvcwo1SXijVuLA==",
"version": "0.4.2",
"resolved": "https://registry.npmjs.org/@superset-ui/legacy-preset-chart-deckgl/-/legacy-preset-chart-deckgl-0.4.2.tgz",
"integrity": "sha512-lr9K0KihVgaCjE72Zu/nd3YoU/q2EDX7qd73y95vzoXBgIA2cMfIkAmEnOe2Komb51ed9hzz0MnudfZHZk1cfw==",
"dependencies": {
"@math.gl/web-mercator": "^3.2.2",
"@types/d3-array": "^2.0.0",
@ -14601,6 +14601,11 @@
"underscore": "^1.8.3",
"urijs": "^1.18.10",
"xss": "^1.0.6"
},
"peerDependencies": {
"@superset-ui/chart-controls": "^0.16.3",
"@superset-ui/core": "^0.16.3",
"react": "^15 || ^16"
}
},
"node_modules/@superset-ui/legacy-preset-chart-nvd3": {
@ -68832,9 +68837,9 @@
}
},
"@superset-ui/legacy-preset-chart-deckgl": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/@superset-ui/legacy-preset-chart-deckgl/-/legacy-preset-chart-deckgl-0.4.1.tgz",
"integrity": "sha512-3THN+WM8HUU1NlV3VNXRVS1j2jH33CmVAdyPNB35RqtwkY+udgFGOxm0lXumcUElht/3ROGMPvcwo1SXijVuLA==",
"version": "0.4.2",
"resolved": "https://registry.npmjs.org/@superset-ui/legacy-preset-chart-deckgl/-/legacy-preset-chart-deckgl-0.4.2.tgz",
"integrity": "sha512-lr9K0KihVgaCjE72Zu/nd3YoU/q2EDX7qd73y95vzoXBgIA2cMfIkAmEnOe2Komb51ed9hzz0MnudfZHZk1cfw==",
"requires": {
"@math.gl/web-mercator": "^3.2.2",
"@types/d3-array": "^2.0.0",

View File

@ -87,7 +87,7 @@
"@superset-ui/legacy-plugin-chart-treemap": "^0.17.9",
"@superset-ui/legacy-plugin-chart-world-map": "^0.17.9",
"@superset-ui/legacy-preset-chart-big-number": "^0.17.9",
"@superset-ui/legacy-preset-chart-deckgl": "^0.4.1",
"@superset-ui/legacy-preset-chart-deckgl": "^0.4.2",
"@superset-ui/legacy-preset-chart-nvd3": "^0.17.9",
"@superset-ui/plugin-chart-echarts": "^0.17.9",
"@superset-ui/plugin-chart-table": "^0.17.9",

View File

@ -47,7 +47,6 @@ const propTypes = {
onOpenPropertiesModal: PropTypes.func,
onOpenInEditor: PropTypes.func,
chartStatus: PropTypes.string,
chartHeight: PropTypes.string.isRequired,
latestQueryFormData: PropTypes.object.isRequired,
slice: PropTypes.object,
};
@ -100,7 +99,7 @@ export const DisplayQueryButton = props => {
};
const handleMenuClick = ({ key, domEvent }) => {
const { chartHeight, slice, onOpenInEditor, latestQueryFormData } = props;
const { slice, onOpenInEditor, latestQueryFormData } = props;
switch (key) {
case MENU_KEYS.EDIT_PROPERTIES:
props.onOpenPropertiesModal();
@ -110,12 +109,11 @@ export const DisplayQueryButton = props => {
break;
case MENU_KEYS.DOWNLOAD_AS_IMAGE:
downloadAsImage(
'.chart-container',
'.panel-body > .chart-container',
// eslint-disable-next-line camelcase
slice?.slice_name ?? t('New chart'),
{
height: parseInt(chartHeight, 10),
},
{},
true,
)(domEvent);
break;
default:

View File

@ -41,7 +41,6 @@ type ActionButtonProps = {
type ExploreActionButtonsProps = {
actions: { redirectSQLLab: Function; openPropertiesModal: Function };
canDownload: boolean;
chartHeight: number;
chartStatus: string;
latestQueryFormData: {};
queriesResponse: {};
@ -85,7 +84,6 @@ const ExploreActionButtons = (props: ExploreActionButtonsProps) => {
const {
actions,
canDownload,
chartHeight,
chartStatus,
latestQueryFormData,
queriesResponse,
@ -189,7 +187,6 @@ const ExploreActionButtons = (props: ExploreActionButtonsProps) => {
</>
)}
<ConnectedDisplayQueryButton
chartHeight={chartHeight}
queryResponse={queriesResponse?.[0]}
latestQueryFormData={latestQueryFormData}
chartStatus={chartStatus}

View File

@ -44,7 +44,6 @@ const propTypes = {
addHistory: PropTypes.func,
can_overwrite: PropTypes.bool.isRequired,
can_download: PropTypes.bool.isRequired,
chartHeight: PropTypes.string.isRequired,
isStarred: PropTypes.bool.isRequired,
slice: PropTypes.object,
sliceName: PropTypes.string,
@ -210,7 +209,6 @@ export class ExploreChartHeader extends React.PureComponent {
slice={this.props.slice}
canDownload={this.props.can_download}
chartStatus={chartStatus}
chartHeight={this.props.chartHeight}
latestQueryFormData={latestQueryFormData}
queryResponse={queryResponse}
/>

View File

@ -241,7 +241,6 @@ const ExploreChartPanel = props => {
addHistory={props.addHistory}
can_overwrite={props.can_overwrite}
can_download={props.can_download}
chartHeight={props.height}
isStarred={props.isStarred}
slice={props.slice}
sliceName={props.sliceName}

View File

@ -43,16 +43,20 @@ const generateFileStem = (description: string, date = new Date()) =>
* @param selector css selector of the parent element which should be turned into image
* @param description name or a short description of what is being printed.
* Value will be normalized, and a date as well as a file extension will be added.
* @param backgroundColor background color to apply to screenshot document
* @param domToImageOptions dom-to-image Options object.
* @param isExactSelector if false, searches for the closest ancestor that matches selector.
* @returns event handler
*/
export default function downloadAsImage(
selector: string,
description: string,
domToImageOptions: Options = {},
isExactSelector = false,
) {
return (event: SyntheticEvent) => {
const elementToPrint = event.currentTarget.closest(selector);
const elementToPrint = isExactSelector
? document.querySelector(selector)
: event.currentTarget.closest(selector);
if (!elementToPrint) {
return addWarningToast(
@ -64,6 +68,10 @@ export default function downloadAsImage(
.toJpeg(elementToPrint, {
quality: 0.95,
bgcolor: GRAY_BACKGROUND_COLOR,
// Mapbox controls are loaded from different origin, causing CORS error
// See https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toDataURL#exceptions
filter: (node: Element) =>
node.className !== 'mapboxgl-control-container',
...domToImageOptions,
})
.then(dataUrl => {
@ -71,6 +79,9 @@ export default function downloadAsImage(
link.download = `${generateFileStem(description)}.jpg`;
link.href = dataUrl;
link.click();
})
.catch(e => {
console.error('Creating image failed', e);
});
};
}