diff --git a/superset/assets/javascripts/components/ExportSlice.js b/superset/assets/javascripts/components/ExportSlice.js new file mode 100644 index 0000000000000..6df0f577452bd --- /dev/null +++ b/superset/assets/javascripts/components/ExportSlice.js @@ -0,0 +1,31 @@ +/* eslint camelcase: 0 */ + +export function hasSvg(slice) { + return !['table', 'filter_box'].includes(slice.form_data.viz_type); +} + +export function exportSlice(slice, format) { + if (format === 'png') { + const tmp = document.getElementById('con_' + slice.slice_id); + const svg = tmp.getElementsByTagName('svg')[0]; + const svg_xml = (new XMLSerializer()).serializeToString(svg); + const data_uri = 'data:image/svg+xml;base64,' + window.btoa(svg_xml); + + const image = new Image(); + image.src = data_uri; + image.onload = function () { + const canvas = document.createElement('canvas'); + canvas.width = image.width; + canvas.height = image.height; + + const context = canvas.getContext('2d'); + context.clearRect(0, 0, image.width, image.height); + context.drawImage(image, 0, 0); + + const a = document.createElement('a'); + a.download = slice.slice_name; + a.href = canvas.toDataURL('image/png'); + a.click(); + }; + } +} diff --git a/superset/assets/javascripts/dashboard/components/SliceCell.jsx b/superset/assets/javascripts/dashboard/components/SliceCell.jsx index 0a179034825bf..49d52220e94af 100644 --- a/superset/assets/javascripts/dashboard/components/SliceCell.jsx +++ b/superset/assets/javascripts/dashboard/components/SliceCell.jsx @@ -4,6 +4,8 @@ import PropTypes from 'prop-types'; import { getExploreUrl } from '../../explore/exploreUtils'; +import { exportSlice, hasSvg } from '../../components/ExportSlice'; + const propTypes = { slice: PropTypes.object.isRequired, removeSlice: PropTypes.func.isRequired, @@ -50,6 +52,15 @@ function SliceCell({ expandedSlices, removeSlice, slice }) { > + { exportSlice(slice, 'png'); }} + title="Export PNG" + data-toggle="tooltip" + style={{ display: hasSvg(slice) ? 'inline' : 'none' }} + > + + diff --git a/superset/assets/spec/javascripts/dashboard/SliceCell_spec.jsx b/superset/assets/spec/javascripts/dashboard/SliceCell_spec.jsx index 8dbf661d20788..c9b1f266e1452 100644 --- a/superset/assets/spec/javascripts/dashboard/SliceCell_spec.jsx +++ b/superset/assets/spec/javascripts/dashboard/SliceCell_spec.jsx @@ -17,8 +17,8 @@ describe('SliceCell', () => { React.isValidElement(), ).to.equal(true); }); - it('renders six links', () => { + it('renders seven links', () => { const wrapper = mount(); - expect(wrapper.find('a')).to.have.length(6); + expect(wrapper.find('a')).to.have.length(7); }); });