mirror of
https://github.com/apache/superset.git
synced 2024-09-12 00:29:39 -04:00
chore(superset-ui-chart-controls): refactor pivot and rename operator (#22963)
This commit is contained in:
parent
ed7b3533bc
commit
c53c3aa23d
@ -31,13 +31,14 @@ export const pivotOperator: PostProcessingFactory<PostProcessingPivot> = (
|
|||||||
) => {
|
) => {
|
||||||
const metricLabels = ensureIsArray(queryObject.metrics).map(getMetricLabel);
|
const metricLabels = ensureIsArray(queryObject.metrics).map(getMetricLabel);
|
||||||
const xAxisLabel = getXAxisLabel(formData);
|
const xAxisLabel = getXAxisLabel(formData);
|
||||||
|
const columns = queryObject.series_columns || queryObject.columns;
|
||||||
|
|
||||||
if (xAxisLabel && metricLabels.length) {
|
if (xAxisLabel && metricLabels.length) {
|
||||||
return {
|
return {
|
||||||
operation: 'pivot',
|
operation: 'pivot',
|
||||||
options: {
|
options: {
|
||||||
index: [xAxisLabel],
|
index: [xAxisLabel],
|
||||||
columns: ensureIsArray(queryObject.columns).map(getColumnLabel),
|
columns: ensureIsArray(columns).map(getColumnLabel),
|
||||||
// Create 'dummy' mean aggregates to assign cell values in pivot table
|
// Create 'dummy' mean aggregates to assign cell values in pivot table
|
||||||
// use the 'mean' aggregates to avoid drop NaN. PR: https://github.com/apache-superset/superset-ui/pull/1231
|
// use the 'mean' aggregates to avoid drop NaN. PR: https://github.com/apache-superset/superset-ui/pull/1231
|
||||||
aggregates: Object.fromEntries(
|
aggregates: Object.fromEntries(
|
||||||
|
@ -32,14 +32,16 @@ export const renameOperator: PostProcessingFactory<PostProcessingRename> = (
|
|||||||
queryObject,
|
queryObject,
|
||||||
) => {
|
) => {
|
||||||
const metrics = ensureIsArray(queryObject.metrics);
|
const metrics = ensureIsArray(queryObject.metrics);
|
||||||
const columns = ensureIsArray(queryObject.columns);
|
const columns = ensureIsArray(
|
||||||
|
queryObject.series_columns || queryObject.columns,
|
||||||
|
);
|
||||||
const { truncate_metric } = formData;
|
const { truncate_metric } = formData;
|
||||||
const xAxisLabel = getXAxisLabel(formData);
|
const xAxisLabel = getXAxisLabel(formData);
|
||||||
// remove or rename top level of column name(metric name) in the MultiIndex when
|
// remove or rename top level of column name(metric name) in the MultiIndex when
|
||||||
// 1) only 1 metric
|
// 1) only 1 metric
|
||||||
// 2) exist dimentsion
|
// 2) dimension exist
|
||||||
// 3) exist xAxis
|
// 3) xAxis exist
|
||||||
// 4) exist time comparison, and comparison type is "actual values"
|
// 4) time comparison exist, and comparison type is "actual values"
|
||||||
// 5) truncate_metric in form_data and truncate_metric is true
|
// 5) truncate_metric in form_data and truncate_metric is true
|
||||||
if (
|
if (
|
||||||
metrics.length === 1 &&
|
metrics.length === 1 &&
|
||||||
|
@ -31,6 +31,7 @@ export const timeComparePivotOperator: PostProcessingFactory<PostProcessingPivot
|
|||||||
(formData, queryObject) => {
|
(formData, queryObject) => {
|
||||||
const metricOffsetMap = getMetricOffsetsMap(formData, queryObject);
|
const metricOffsetMap = getMetricOffsetsMap(formData, queryObject);
|
||||||
const xAxisLabel = getXAxisLabel(formData);
|
const xAxisLabel = getXAxisLabel(formData);
|
||||||
|
const columns = queryObject.series_columns || queryObject.columns;
|
||||||
|
|
||||||
if (isTimeComparison(formData, queryObject) && xAxisLabel) {
|
if (isTimeComparison(formData, queryObject) && xAxisLabel) {
|
||||||
const aggregates = Object.fromEntries(
|
const aggregates = Object.fromEntries(
|
||||||
@ -45,7 +46,7 @@ export const timeComparePivotOperator: PostProcessingFactory<PostProcessingPivot
|
|||||||
operation: 'pivot',
|
operation: 'pivot',
|
||||||
options: {
|
options: {
|
||||||
index: [xAxisLabel],
|
index: [xAxisLabel],
|
||||||
columns: ensureIsArray(queryObject.columns).map(getColumnLabel),
|
columns: ensureIsArray(columns).map(getColumnLabel),
|
||||||
drop_missing_columns: !formData?.show_empty_columns,
|
drop_missing_columns: !formData?.show_empty_columns,
|
||||||
aggregates,
|
aggregates,
|
||||||
},
|
},
|
||||||
|
@ -64,7 +64,7 @@ test('skip pivot', () => {
|
|||||||
).toEqual(undefined);
|
).toEqual(undefined);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('pivot by __timestamp without groupby', () => {
|
test('pivot by __timestamp without columns', () => {
|
||||||
expect(
|
expect(
|
||||||
pivotOperator(
|
pivotOperator(
|
||||||
{ ...formData, granularity_sqla: 'time_column' },
|
{ ...formData, granularity_sqla: 'time_column' },
|
||||||
@ -84,7 +84,7 @@ test('pivot by __timestamp without groupby', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
test('pivot by __timestamp with groupby', () => {
|
test('pivot by __timestamp with columns', () => {
|
||||||
expect(
|
expect(
|
||||||
pivotOperator(
|
pivotOperator(
|
||||||
{ ...formData, granularity_sqla: 'time_column' },
|
{ ...formData, granularity_sqla: 'time_column' },
|
||||||
@ -107,6 +107,29 @@ test('pivot by __timestamp with groupby', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('pivot by __timestamp with series_columns', () => {
|
||||||
|
expect(
|
||||||
|
pivotOperator(
|
||||||
|
{ ...formData, granularity_sqla: 'time_column' },
|
||||||
|
{
|
||||||
|
...queryObject,
|
||||||
|
series_columns: ['foo', 'bar'],
|
||||||
|
},
|
||||||
|
),
|
||||||
|
).toEqual({
|
||||||
|
operation: 'pivot',
|
||||||
|
options: {
|
||||||
|
index: ['__timestamp'],
|
||||||
|
columns: ['foo', 'bar'],
|
||||||
|
aggregates: {
|
||||||
|
'count(*)': { operator: 'mean' },
|
||||||
|
'sum(val)': { operator: 'mean' },
|
||||||
|
},
|
||||||
|
drop_missing_columns: false,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
test('pivot by x_axis with groupby', () => {
|
test('pivot by x_axis with groupby', () => {
|
||||||
expect(
|
expect(
|
||||||
pivotOperator(
|
pivotOperator(
|
||||||
@ -116,7 +139,7 @@ test('pivot by x_axis with groupby', () => {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
...queryObject,
|
...queryObject,
|
||||||
columns: ['foo', 'bar'],
|
series_columns: ['foo', 'bar'],
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
).toEqual({
|
).toEqual({
|
||||||
@ -146,7 +169,7 @@ test('pivot by adhoc x_axis', () => {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
...queryObject,
|
...queryObject,
|
||||||
columns: ['foo', 'bar'],
|
series_columns: ['foo', 'bar'],
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
).toEqual({
|
).toEqual({
|
||||||
|
@ -49,7 +49,7 @@ test('should skip renameOperator if exists multiple metrics', () => {
|
|||||||
).toEqual(undefined);
|
).toEqual(undefined);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should skip renameOperator if does not exist series', () => {
|
test('should skip renameOperator if series does not exist', () => {
|
||||||
expect(
|
expect(
|
||||||
renameOperator(formData, {
|
renameOperator(formData, {
|
||||||
...queryObject,
|
...queryObject,
|
||||||
@ -105,7 +105,7 @@ test('should add renameOperator', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should add renameOperator if does not exist x_axis', () => {
|
test('should add renameOperator if x_axis does not exist', () => {
|
||||||
expect(
|
expect(
|
||||||
renameOperator(
|
renameOperator(
|
||||||
{
|
{
|
||||||
@ -120,6 +120,25 @@ test('should add renameOperator if does not exist x_axis', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('should add renameOperator if based on series_columns', () => {
|
||||||
|
expect(
|
||||||
|
renameOperator(
|
||||||
|
{
|
||||||
|
...formData,
|
||||||
|
...{ x_axis: null, granularity_sqla: 'time column' },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
...queryObject,
|
||||||
|
columns: [],
|
||||||
|
series_columns: ['gender', 'dttm'],
|
||||||
|
},
|
||||||
|
),
|
||||||
|
).toEqual({
|
||||||
|
operation: 'rename',
|
||||||
|
options: { columns: { 'count(*)': null }, inplace: true, level: 0 },
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
test('should add renameOperator if exist "actual value" time comparison', () => {
|
test('should add renameOperator if exist "actual value" time comparison', () => {
|
||||||
expect(
|
expect(
|
||||||
renameOperator(
|
renameOperator(
|
||||||
|
@ -136,6 +136,45 @@ test('should pivot on x-axis', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('should pivot on x-axis with series_columns', () => {
|
||||||
|
expect(
|
||||||
|
timeComparePivotOperator(
|
||||||
|
{
|
||||||
|
...formData,
|
||||||
|
comparison_type: 'values',
|
||||||
|
time_compare: ['1 year ago', '1 year later'],
|
||||||
|
x_axis: 'ds',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
...queryObject,
|
||||||
|
columns: ['ds', 'foo', 'bar'],
|
||||||
|
series_columns: ['foo', 'bar'],
|
||||||
|
},
|
||||||
|
),
|
||||||
|
).toEqual({
|
||||||
|
operation: 'pivot',
|
||||||
|
options: {
|
||||||
|
aggregates: {
|
||||||
|
'count(*)': { operator: 'mean' },
|
||||||
|
'count(*)__1 year ago': { operator: 'mean' },
|
||||||
|
'count(*)__1 year later': { operator: 'mean' },
|
||||||
|
'sum(val)': {
|
||||||
|
operator: 'mean',
|
||||||
|
},
|
||||||
|
'sum(val)__1 year ago': {
|
||||||
|
operator: 'mean',
|
||||||
|
},
|
||||||
|
'sum(val)__1 year later': {
|
||||||
|
operator: 'mean',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
drop_missing_columns: false,
|
||||||
|
columns: ['foo', 'bar'],
|
||||||
|
index: ['ds'],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
test('should pivot on adhoc x-axis', () => {
|
test('should pivot on adhoc x-axis', () => {
|
||||||
expect(
|
expect(
|
||||||
timeComparePivotOperator(
|
timeComparePivotOperator(
|
||||||
|
@ -67,8 +67,8 @@ export default function buildQuery(formData: QueryFormData) {
|
|||||||
fd,
|
fd,
|
||||||
queryObject,
|
queryObject,
|
||||||
)
|
)
|
||||||
? timeComparePivotOperator(fd, { ...queryObject, columns: fd.groupby })
|
? timeComparePivotOperator(fd, queryObject)
|
||||||
: pivotOperator(fd, { ...queryObject, columns: fd.groupby });
|
: pivotOperator(fd, queryObject);
|
||||||
|
|
||||||
const tmpQueryObject = {
|
const tmpQueryObject = {
|
||||||
...queryObject,
|
...queryObject,
|
||||||
@ -78,10 +78,7 @@ export default function buildQuery(formData: QueryFormData) {
|
|||||||
rollingWindowOperator(fd, queryObject),
|
rollingWindowOperator(fd, queryObject),
|
||||||
timeCompareOperator(fd, queryObject),
|
timeCompareOperator(fd, queryObject),
|
||||||
resampleOperator(fd, queryObject),
|
resampleOperator(fd, queryObject),
|
||||||
renameOperator(fd, {
|
renameOperator(fd, queryObject),
|
||||||
...queryObject,
|
|
||||||
columns: fd.groupby,
|
|
||||||
}),
|
|
||||||
flattenOperator(fd, queryObject),
|
flattenOperator(fd, queryObject),
|
||||||
],
|
],
|
||||||
} as QueryObject;
|
} as QueryObject;
|
||||||
|
Loading…
Reference in New Issue
Block a user