feat: explicit distribute columns on BoxPlot and apply time grain (#21593)

This commit is contained in:
Yongjie Zhao
2022-09-28 15:32:35 +08:00
committed by GitHub
parent 23cd5c90cf
commit 93f08e778b
13 changed files with 466 additions and 63 deletions

View File

@@ -16,26 +16,44 @@
* specific language governing permissions and limitations
* under the License.
*/
import { buildQueryContext } from '@superset-ui/core';
import {
AdhocColumn,
buildQueryContext,
ensureIsArray,
isPhysicalColumn,
} from '@superset-ui/core';
import { boxplotOperator } from '@superset-ui/chart-controls';
import { BoxPlotQueryFormData } from './types';
export default function buildQuery(formData: BoxPlotQueryFormData) {
const { columns = [], granularity_sqla, groupby = [] } = formData;
return buildQueryContext(formData, baseQueryObject => {
const distributionColumns: string[] = [];
// For now default to using the temporal column as distribution column.
// In the future this control should be made mandatory.
if (!columns.length && granularity_sqla) {
distributionColumns.push(granularity_sqla);
}
return [
{
...baseQueryObject,
columns: [...distributionColumns, ...columns, ...groupby],
series_columns: groupby,
post_processing: [boxplotOperator(formData, baseQueryObject)],
},
];
});
return buildQueryContext(formData, baseQueryObject => [
{
...baseQueryObject,
columns: [
...(ensureIsArray(formData.columns).length === 0 &&
formData.granularity_sqla
? [formData.granularity_sqla] // for backwards compatible: if columns control is empty and granularity_sqla was set, the time columns is default distributed column.
: ensureIsArray(formData.columns)
).map(col => {
if (
isPhysicalColumn(col) &&
formData.time_grain_sqla &&
formData?.datetime_columns_lookup?.[col]
) {
return {
timeGrain: formData.time_grain_sqla,
columnType: 'BASE_AXIS',
sqlExpression: col,
label: col,
expressionType: 'SQL',
} as AdhocColumn;
}
return col;
}),
...ensureIsArray(formData.groupby),
],
series_columns: formData.groupby,
post_processing: [boxplotOperator(formData, baseQueryObject)],
},
]);
}

View File

@@ -16,7 +16,13 @@
* specific language governing permissions and limitations
* under the License.
*/
import { ensureIsArray, t } from '@superset-ui/core';
import {
ensureIsArray,
isAdhocColumn,
isPhysicalColumn,
t,
validateNonEmpty,
} from '@superset-ui/core';
import {
D3_FORMAT_DOCS,
D3_FORMAT_OPTIONS,
@@ -26,20 +32,53 @@ import {
emitFilterControl,
ControlPanelConfig,
getStandardizedControls,
ControlState,
ControlPanelState,
getTemporalColumns,
sharedControls,
} from '@superset-ui/chart-controls';
const config: ControlPanelConfig = {
controlPanelSections: [
sections.legacyTimeseriesTime,
sections.legacyRegularTime,
{
label: t('Query'),
expanded: true,
controlSetRows: [
['columns'],
[
{
name: 'time_grain_sqla',
config: {
...sharedControls.time_grain_sqla,
visibility: ({ controls }) => {
const dttmLookup = Object.fromEntries(
ensureIsArray(controls?.columns?.options).map(option => [
option.column_name,
option.is_dttm,
]),
);
return ensureIsArray(controls?.columns.value)
.map(selection => {
if (isAdhocColumn(selection)) {
return true;
}
if (isPhysicalColumn(selection)) {
return !!dttmLookup[selection];
}
return false;
})
.some(Boolean);
},
},
},
'datetime_columns_lookup',
],
['groupby'],
['metrics'],
['adhoc_filters'],
emitFilterControl,
['groupby'],
['columns'], // TODO: this should be migrated to `series_columns`
['series_limit'],
['series_limit_metric'],
[
@@ -132,9 +171,17 @@ const config: ControlPanelConfig = {
columns: {
label: t('Distribute across'),
multi: true,
description: t(
'Columns to calculate distribution across. Defaults to temporal column if left empty.',
),
description: t('Columns to calculate distribution across.'),
initialValue: (control: ControlState, state: ControlPanelState) => {
if (
(state && !control?.value) ||
(Array.isArray(control?.value) && control.value.length === 0)
) {
return [getTemporalColumns(state.datasource).defaultTemporalColumn];
}
return control.value;
},
validators: [validateNonEmpty],
},
},
formDataOverrides: formData => {