feat: adding XAxis to BigNumberTrend (#21577)

This commit is contained in:
Yongjie Zhao 2022-09-26 20:14:17 +08:00 committed by GitHub
parent 5d51555c46
commit f4646f8edb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 89 additions and 60 deletions

View File

@ -37,3 +37,4 @@ export { legacySortBy } from './shared-controls/legacySortBy';
export * from './shared-controls/emitFilterControl';
export * from './shared-controls/components';
export * from './types';
export { xAxisMixin, temporalColumnMixin } from './shared-controls/constants';

View File

@ -20,10 +20,16 @@ import {
FeatureFlag,
isFeatureEnabled,
QueryFormData,
QueryResponse,
t,
validateNonEmpty,
} from '@superset-ui/core';
import { ControlPanelState, ControlState } from '../types';
import {
BaseControlConfig,
ControlPanelState,
ControlState,
Dataset,
} from '../types';
const getAxisLabel = (
formData: QueryFormData,
@ -32,7 +38,7 @@ const getAxisLabel = (
? { label: t('Y-axis'), description: t('Dimension to use on y-axis.') }
: { label: t('X-axis'), description: t('Dimension to use on x-axis.') };
export const xAxisControlConfig = {
export const xAxisMixin = {
label: (state: ControlPanelState) => getAxisLabel(state?.form_data).label,
multi: false,
description: (state: ControlPanelState) =>
@ -51,3 +57,28 @@ export const xAxisControlConfig = {
},
default: undefined,
};
export const temporalColumnMixin: Pick<BaseControlConfig, 'mapStateToProps'> = {
mapStateToProps: ({ datasource }) => {
if (datasource?.columns[0]?.hasOwnProperty('column_name')) {
const temporalColumns =
(datasource as Dataset)?.columns?.filter(c => c.is_dttm) ?? [];
return {
options: temporalColumns,
default:
(datasource as Dataset)?.main_dttm_col ||
temporalColumns[0]?.column_name ||
null,
isTemporal: true,
};
}
const sortedQueryColumns = (datasource as QueryResponse)?.columns?.sort(
query => (query?.is_dttm ? -1 : 1),
);
return {
options: sortedQueryColumns,
default: sortedQueryColumns[0]?.name || null,
isTemporal: true,
};
},
};

View File

@ -22,7 +22,6 @@ import {
FeatureFlag,
isFeatureEnabled,
QueryColumn,
QueryResponse,
t,
validateNonEmpty,
} from '@superset-ui/core';
@ -39,8 +38,9 @@ import {
ColumnOption,
ColumnMeta,
FilterOption,
temporalColumnMixin,
} from '..';
import { xAxisControlConfig } from './constants';
import { xAxisMixin } from './constants';
type Control = {
savedMetrics?: Metric[] | null;
@ -231,6 +231,7 @@ export const dndSecondaryMetricControl: typeof dndAdhocMetricControl = {
export const dndGranularitySqlaControl: typeof dndSeriesControl = {
...dndSeriesControl,
...temporalColumnMixin,
label: TIME_FILTER_LABELS.granularity_sqla,
description: t(
'The time column for the visualization. Note that you ' +
@ -247,33 +248,11 @@ export const dndGranularitySqlaControl: typeof dndSeriesControl = {
optionRenderer: (c: ColumnMeta) => <ColumnOption showType column={c} />,
valueRenderer: (c: ColumnMeta) => <ColumnOption column={c} />,
valueKey: 'column_name',
mapStateToProps: ({ datasource }) => {
if (datasource?.columns[0]?.hasOwnProperty('column_name')) {
const temporalColumns =
(datasource as Dataset)?.columns?.filter(c => c.is_dttm) ?? [];
return {
options: temporalColumns,
default:
(datasource as Dataset)?.main_dttm_col ||
temporalColumns[0]?.column_name ||
null,
isTemporal: true,
};
}
const sortedQueryColumns = (datasource as QueryResponse)?.columns?.sort(
query => (query?.is_dttm ? -1 : 1),
);
return {
options: sortedQueryColumns,
default: sortedQueryColumns[0]?.name || null,
isTemporal: true,
};
},
};
export const dndXAxisControl: typeof dndGroupByControl = {
...dndGroupByControl,
...xAxisControlConfig,
...xAxisMixin,
};
export function withDndFallback(

View File

@ -18,7 +18,9 @@
*/
import {
buildQueryContext,
DTTM_ALIAS,
ensureIsArray,
getXAxis,
isXAxisSet,
QueryFormData,
} from '@superset-ui/core';
import {
@ -29,25 +31,19 @@ import {
} from '@superset-ui/chart-controls';
export default function buildQuery(formData: QueryFormData) {
return buildQueryContext(formData, baseQueryObject => {
const { x_axis } = formData;
const is_timeseries = x_axis === DTTM_ALIAS || !x_axis;
return [
{
...baseQueryObject,
is_timeseries: true,
post_processing: [
pivotOperator(formData, {
...baseQueryObject,
index: x_axis,
is_timeseries,
}),
rollingWindowOperator(formData, baseQueryObject),
resampleOperator(formData, baseQueryObject),
flattenOperator(formData, baseQueryObject),
],
},
];
});
return buildQueryContext(formData, baseQueryObject => [
{
...baseQueryObject,
columns: [
...(isXAxisSet(formData) ? ensureIsArray(getXAxis(formData)) : []),
],
...(isXAxisSet(formData) ? {} : { is_timeseries: true }),
post_processing: [
pivotOperator(formData, baseQueryObject),
rollingWindowOperator(formData, baseQueryObject),
resampleOperator(formData, baseQueryObject),
flattenOperator(formData, baseQueryObject),
],
},
]);
}

View File

@ -16,7 +16,12 @@
* specific language governing permissions and limitations
* under the License.
*/
import { smartDateFormatter, t } from '@superset-ui/core';
import {
FeatureFlag,
isFeatureEnabled,
smartDateFormatter,
t,
} from '@superset-ui/core';
import {
ControlPanelConfig,
D3_FORMAT_DOCS,
@ -24,17 +29,27 @@ import {
formatSelectOptions,
getStandardizedControls,
sections,
temporalColumnMixin,
} from '@superset-ui/chart-controls';
import React from 'react';
import { headerFontSize, subheaderFontSize } from '../sharedControls';
const config: ControlPanelConfig = {
controlPanelSections: [
sections.legacyTimeseriesTime,
sections.genericTime,
{
label: t('Query'),
expanded: true,
controlSetRows: [['metric'], ['adhoc_filters']],
controlSetRows: [
[isFeatureEnabled(FeatureFlag.GENERIC_CHART_AXES) ? 'x_axis' : null],
[
isFeatureEnabled(FeatureFlag.GENERIC_CHART_AXES)
? 'time_grain_sqla'
: null,
],
['metric'],
['adhoc_filters'],
],
},
{
label: t('Options'),
@ -270,6 +285,10 @@ const config: ControlPanelConfig = {
y_axis_format: {
label: t('Number format'),
},
x_axis: {
label: t('TEMPORAL X-AXIS'),
...temporalColumnMixin,
},
},
formDataOverrides: formData => ({
...formData,

View File

@ -17,17 +17,16 @@
* under the License.
*/
import {
DTTM_ALIAS,
extractTimegrain,
getNumberFormatter,
NumberFormats,
QueryFormData,
GenericDataType,
getMetricLabel,
t,
smartDateVerboseFormatter,
NumberFormatter,
TimeFormatter,
getXAxis,
} from '@superset-ui/core';
import { EChartsCoreOption, graphic } from 'echarts';
import {
@ -88,7 +87,7 @@ export default function transformProps(
yAxisFormat,
timeRangeFixed,
} = formData;
const granularity = extractTimegrain(rawFormData as QueryFormData);
const granularity = extractTimegrain(rawFormData);
const {
data = [],
colnames = [],
@ -103,10 +102,11 @@ export default function transformProps(
const { r, g, b } = colorPicker;
const mainColor = `rgb(${r}, ${g}, ${b})`;
const timeColumn = getXAxis(rawFormData) as string;
let trendLineData;
let percentChange = 0;
let bigNumber = data.length === 0 ? null : data[0][metricName];
let timestamp = data.length === 0 ? null : data[0][DTTM_ALIAS];
let timestamp = data.length === 0 ? null : data[0][timeColumn];
let bigNumberFallback;
const metricColtypeIndex = colnames.findIndex(name => name === metricName);
@ -115,7 +115,7 @@ export default function transformProps(
if (data.length > 0) {
const sortedData = (data as BigNumberDatum[])
.map(d => [d[DTTM_ALIAS], parseMetricValue(d[metricName])])
.map(d => [d[timeColumn], parseMetricValue(d[metricName])])
// sort in time descending order
.sort((a, b) => (a[0] !== null && b[0] !== null ? b[0] - a[0] : 0));

View File

@ -43,7 +43,7 @@ export type BigNumberWithTrendlineFormData = BigNumberTotalFormData & {
compareLag?: string | number;
};
export type BigNumberTotalChartProps = ChartProps & {
export type BigNumberTotalChartProps = ChartProps<QueryFormData> & {
formData: BigNumberTotalFormData;
queriesData: (ChartDataResponseResult & {
data?: BigNumberDatum[];

View File

@ -36,7 +36,8 @@ const formData = {
a: 1,
},
compareLag: 1,
timeGrainSqla: 'P3M' as TimeGranularity,
timeGrainSqla: TimeGranularity.QUARTER,
granularitySqla: 'ds',
compareSuffix: 'over last quarter',
viz_type: 'big_number',
yAxisFormat: '.3s',
@ -44,6 +45,7 @@ const formData = {
};
const rawFormData = {
datasource: '1__table',
metric: 'value',
color_picker: {
r: 0,
@ -52,7 +54,8 @@ const rawFormData = {
a: 1,
},
compare_lag: 1,
time_grain_sqla: 'P3M' as TimeGranularity,
time_grain_sqla: TimeGranularity.QUARTER,
granularity_sqla: 'ds',
compare_suffix: 'over last quarter',
viz_type: 'big_number',
y_axis_format: '.3s',