diff --git a/superset/assets/spec/javascripts/sqllab/TableElement_spec.jsx b/superset/assets/spec/javascripts/sqllab/TableElement_spec.jsx index ff3087158599f..e19a312a856ef 100644 --- a/superset/assets/spec/javascripts/sqllab/TableElement_spec.jsx +++ b/superset/assets/spec/javascripts/sqllab/TableElement_spec.jsx @@ -54,8 +54,6 @@ describe('TableElement', () => { expect(wrapper.state().expanded).to.equal(true); wrapper.find('.table-remove').simulate('click'); expect(wrapper.state().expanded).to.equal(false); - setTimeout(() => { - expect(mockedActions.removeTable.called).to.equal(true); - }, 10); + expect(mockedActions.removeDataPreview.called).to.equal(true); }); }); diff --git a/superset/assets/src/components/VirtualizedRendererWrap.jsx b/superset/assets/src/components/VirtualizedRendererWrap.jsx index 32821124bd19b..2f4e063fc6919 100644 --- a/superset/assets/src/components/VirtualizedRendererWrap.jsx +++ b/superset/assets/src/components/VirtualizedRendererWrap.jsx @@ -35,7 +35,7 @@ export default function VirtualizedRendererWrap(renderer) {
diff --git a/superset/assets/src/dashboard/components/gridComponents/ChartHolder.jsx b/superset/assets/src/dashboard/components/gridComponents/ChartHolder.jsx index 9ad9522965dcd..366d3fede833b 100644 --- a/superset/assets/src/dashboard/components/gridComponents/ChartHolder.jsx +++ b/superset/assets/src/dashboard/components/gridComponents/ChartHolder.jsx @@ -12,6 +12,7 @@ import { GRID_MIN_COLUMN_COUNT, GRID_MIN_ROW_UNITS, GRID_BASE_UNIT, + GRID_GUTTER_SIZE, } from '../../util/constants'; const CHART_MARGIN = 32; @@ -131,8 +132,14 @@ class ChartHolder extends React.Component { > diff --git a/superset/assets/src/visualizations/big_number.css b/superset/assets/src/visualizations/BigNumber/BigNumber.css similarity index 100% rename from superset/assets/src/visualizations/big_number.css rename to superset/assets/src/visualizations/BigNumber/BigNumber.css diff --git a/superset/assets/src/visualizations/BigNumber.jsx b/superset/assets/src/visualizations/BigNumber/BigNumber.jsx similarity index 95% rename from superset/assets/src/visualizations/BigNumber.jsx rename to superset/assets/src/visualizations/BigNumber/BigNumber.jsx index e2658f38c016e..3c5cffbc5e670 100644 --- a/superset/assets/src/visualizations/BigNumber.jsx +++ b/superset/assets/src/visualizations/BigNumber/BigNumber.jsx @@ -4,12 +4,12 @@ import ReactDOM from 'react-dom'; import * as color from 'd3-color'; import { XYChart, AreaSeries, CrossHair, LinearGradient } from '@data-ui/xy-chart'; -import { brandColor } from '../modules/colors'; -import { d3FormatPreset } from '../modules/utils'; -import { formatDateVerbose } from '../modules/dates'; -import { computeMaxFontSize } from '../modules/visUtils'; +import { brandColor } from '../../modules/colors'; +import { d3FormatPreset } from '../../modules/utils'; +import { formatDateVerbose } from '../../modules/dates'; +import { computeMaxFontSize } from '../../modules/visUtils'; -import './big_number.css'; +import './BigNumber.css'; const CHART_MARGIN = { top: 4, @@ -98,7 +98,7 @@ class BigNumberVis extends React.Component { document.body.appendChild(container); const fontSize = computeMaxFontSize({ text, - maxWidth: width, + maxWidth: Math.floor(width), maxHeight, className: 'header_line', container, @@ -126,7 +126,7 @@ class BigNumberVis extends React.Component { document.body.appendChild(container); fontSize = computeMaxFontSize({ text: subheader, - maxWidth: width, + maxWidth: Math.floor(width), maxHeight, className: 'subheader_line', container, @@ -165,7 +165,7 @@ class BigNumberVis extends React.Component { type: 'linear', includeZero: startYAxisAtZero, }} - width={width} + width={Math.floor(width)} height={maxHeight} margin={CHART_MARGIN} renderTooltip={renderTooltip} diff --git a/superset/assets/src/visualizations/index.js b/superset/assets/src/visualizations/index.js index 0189d2756edb8..72e345f8bea26 100644 --- a/superset/assets/src/visualizations/index.js +++ b/superset/assets/src/visualizations/index.js @@ -65,9 +65,9 @@ const vizMap = { [VIZ_TYPES.area]: loadNvd3, [VIZ_TYPES.bar]: loadNvd3, [VIZ_TYPES.big_number]: () => - loadVis(import(/* webpackChunkName: 'big_number' */ './BigNumber.jsx')), + loadVis(import(/* webpackChunkName: 'big_number' */ './BigNumber/BigNumber.jsx')), [VIZ_TYPES.big_number_total]: () => - loadVis(import(/* webpackChunkName: "big_number" */ './BigNumber.jsx')), + loadVis(import(/* webpackChunkName: "big_number" */ './BigNumber/BigNumber.jsx')), [VIZ_TYPES.box_plot]: loadNvd3, [VIZ_TYPES.bubble]: loadNvd3, [VIZ_TYPES.bullet]: loadNvd3, diff --git a/superset/assets/src/visualizations/pivot_table.js b/superset/assets/src/visualizations/pivot_table.js index fded4616b350a..cd93867cbfdb4 100644 --- a/superset/assets/src/visualizations/pivot_table.js +++ b/superset/assets/src/visualizations/pivot_table.js @@ -1,51 +1,78 @@ import dt from 'datatables.net-bs'; import 'datatables.net-bs/css/dataTables.bootstrap.css'; import $ from 'jquery'; - +import PropTypes from 'prop-types'; import { d3format, fixDataTableBodyHeight } from '../modules/utils'; import './pivot_table.css'; dt(window, $); -module.exports = function (slice, payload) { - const container = slice.container; - const fd = slice.formData; - const height = container.height(); - let cols = payload.data.columns; - if (Array.isArray(cols[0])) { - cols = cols.map(col => col[0]); - } +const propTypes = { + data: PropTypes.shape({ + // TODO: replace this with raw data in SIP-6 + html: PropTypes.string, + columns: PropTypes.arrayOf(PropTypes.oneOfType([ + PropTypes.string, + PropTypes.arrayOf(PropTypes.string), + ])), + }), + height: PropTypes.number, + columnFormats: PropTypes.objectOf(PropTypes.string), + groupBy: PropTypes.arrayOf(PropTypes.string), + numberFormat: PropTypes.string, + verboseMap: PropTypes.objectOf(PropTypes.string), +}; + +function PivotTable(element, props) { + PropTypes.checkPropTypes(propTypes, props, 'prop', 'PivotTable'); + + const { + data, + height, + columnFormats, + groupBy, + numberFormat, + verboseMap, + } = props; + + const { html, columns } = data; + const container = element; + const $container = $(element); // payload data is a string of html with a single table element - container.html(payload.data.html); + container.innerHTML = html; + + const cols = Array.isArray(columns[0]) + ? columns.map(col => col[0]) + : columns; // jQuery hack to set verbose names in headers const replaceCell = function () { const s = $(this)[0].textContent; - $(this)[0].textContent = slice.datasource.verbose_map[s] || s; + $(this)[0].textContent = verboseMap[s] || s; }; - slice.container.find('thead tr:first th').each(replaceCell); - slice.container.find('thead tr th:first-child').each(replaceCell); + $container.find('thead tr:first th').each(replaceCell); + $container.find('thead tr th:first-child').each(replaceCell); // jQuery hack to format number - slice.container.find('tbody tr').each(function () { + $container.find('tbody tr').each(function () { $(this).find('td').each(function (i) { const metric = cols[i]; - const format = slice.datasource.column_formats[metric] || fd.number_format || '.3s'; + const format = columnFormats[metric] || numberFormat || '.3s'; const tdText = $(this)[0].textContent; - if (!isNaN(tdText) && tdText !== '') { + if (!Number.isNaN(tdText) && tdText !== '') { $(this)[0].textContent = d3format(format, tdText); } }); }); - if (fd.groupby.length === 1) { + if (groupBy.length === 1) { // When there is only 1 group by column, // we use the DataTable plugin to make the header fixed. // The plugin takes care of the scrolling so we don't need // overflow: 'auto' on the table. - container.css('overflow', 'hidden'); - const table = container.find('table').DataTable({ + container.style.overflow = 'hidden'; + const table = $container.find('table').DataTable({ paging: false, searching: false, bInfo: false, @@ -54,12 +81,37 @@ module.exports = function (slice, payload) { scrollX: true, }); table.column('-1').order('desc').draw(); - fixDataTableBodyHeight(container.find('.dataTables_wrapper'), height); + fixDataTableBodyHeight($container.find('.dataTables_wrapper'), height); } else { // When there is more than 1 group by column we just render the table, without using // the DataTable plugin, so we need to handle the scrolling ourselves. // In this case the header is not fixed. - container.css('overflow', 'auto'); - container.css('height', `${height + 10}px`); + container.style.overflow = 'auto'; + container.style.height = `${height + 10}px`; } -}; +} + +function adaptor(slice, payload) { + const { selector, formData, datasource } = slice; + const { + groupby: groupBy, + number_format: numberFormat, + } = formData; + const { + column_formats: columnFormats, + verbose_map: verboseMap, + } = datasource; + const element = document.querySelector(selector); + + return PivotTable(element, { + data: payload.data, + height: slice.height(), + columnFormats, + groupBy, + numberFormat, + verboseMap, + }); +} + +export default adaptor; + diff --git a/superset/assets/src/visualizations/time_table.jsx b/superset/assets/src/visualizations/time_table.jsx index c34e5d01c7379..d2bf633e46f75 100644 --- a/superset/assets/src/visualizations/time_table.jsx +++ b/superset/assets/src/visualizations/time_table.jsx @@ -123,6 +123,7 @@ function viz(slice, payload) { } else if (column.comparisonType === 'perc_change') { v = (recent / v) - 1; } + v = v || 0; } else if (column.colType === 'contrib') { // contribution to column total v = recent / Object.keys(reversedData[0]) diff --git a/superset/assets/yarn.lock b/superset/assets/yarn.lock index 0b112848213af..5edcfa92fbaeb 100644 --- a/superset/assets/yarn.lock +++ b/superset/assets/yarn.lock @@ -12382,7 +12382,7 @@ webpack-log@^2.0.0: ansi-colors "^3.0.0" uuid "^3.3.2" -webpack-sources@^1.0.0, webpack-sources@^1.1.0, webpack-sources@^1.2.0: +webpack-sources@^1.0.0, webpack-sources@^1.0.1, webpack-sources@^1.1.0: version "1.2.0" resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.2.0.tgz#18181e0d013fce096faf6f8e6d41eeffffdceac2" dependencies: