mirror of
https://github.com/apache/superset.git
synced 2024-09-16 10:39:55 -04:00
feat(generic-x-axis): add x sorting on series limit metric (#23274)
This commit is contained in:
parent
71a9d0d403
commit
1b139d0748
@ -24,12 +24,16 @@ import {
|
|||||||
getXAxisLabel,
|
getXAxisLabel,
|
||||||
} from '@superset-ui/core';
|
} from '@superset-ui/core';
|
||||||
import { PostProcessingFactory } from './types';
|
import { PostProcessingFactory } from './types';
|
||||||
|
import { extractExtraMetrics } from './utils';
|
||||||
|
|
||||||
export const pivotOperator: PostProcessingFactory<PostProcessingPivot> = (
|
export const pivotOperator: PostProcessingFactory<PostProcessingPivot> = (
|
||||||
formData,
|
formData,
|
||||||
queryObject,
|
queryObject,
|
||||||
) => {
|
) => {
|
||||||
const metricLabels = ensureIsArray(queryObject.metrics).map(getMetricLabel);
|
const metricLabels = [
|
||||||
|
...ensureIsArray(queryObject.metrics),
|
||||||
|
...extractExtraMetrics(formData),
|
||||||
|
].map(getMetricLabel);
|
||||||
const xAxisLabel = getXAxisLabel(formData);
|
const xAxisLabel = getXAxisLabel(formData);
|
||||||
const columns = queryObject.series_columns || queryObject.columns;
|
const columns = queryObject.series_columns || queryObject.columns;
|
||||||
|
|
||||||
|
@ -26,6 +26,7 @@ import {
|
|||||||
PostProcessingSort,
|
PostProcessingSort,
|
||||||
} from '@superset-ui/core';
|
} from '@superset-ui/core';
|
||||||
import { PostProcessingFactory } from './types';
|
import { PostProcessingFactory } from './types';
|
||||||
|
import { extractExtraMetrics } from './utils';
|
||||||
|
|
||||||
export const sortOperator: PostProcessingFactory<PostProcessingSort> = (
|
export const sortOperator: PostProcessingFactory<PostProcessingSort> = (
|
||||||
formData,
|
formData,
|
||||||
@ -34,7 +35,8 @@ export const sortOperator: PostProcessingFactory<PostProcessingSort> = (
|
|||||||
// the sortOperator only used in the barchart v2
|
// the sortOperator only used in the barchart v2
|
||||||
const sortableLabels = [
|
const sortableLabels = [
|
||||||
getXAxisLabel(formData),
|
getXAxisLabel(formData),
|
||||||
...ensureIsArray(formData.metrics).map(metric => getMetricLabel(metric)),
|
...ensureIsArray(formData.metrics).map(getMetricLabel),
|
||||||
|
...extractExtraMetrics(formData).map(getMetricLabel),
|
||||||
].filter(Boolean);
|
].filter(Boolean);
|
||||||
|
|
||||||
if (
|
if (
|
||||||
|
@ -0,0 +1,38 @@
|
|||||||
|
/**
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
import {
|
||||||
|
getMetricLabel,
|
||||||
|
QueryFormData,
|
||||||
|
QueryFormMetric,
|
||||||
|
} from '@superset-ui/core';
|
||||||
|
|
||||||
|
export function extractExtraMetrics(
|
||||||
|
formData: QueryFormData,
|
||||||
|
): QueryFormMetric[] {
|
||||||
|
const { groupby, timeseries_limit_metric, x_axis_sort } = formData;
|
||||||
|
const extra_metrics: QueryFormMetric[] = [];
|
||||||
|
if (
|
||||||
|
!(groupby || []).length &&
|
||||||
|
timeseries_limit_metric &&
|
||||||
|
getMetricLabel(timeseries_limit_metric) === x_axis_sort
|
||||||
|
) {
|
||||||
|
extra_metrics.push(timeseries_limit_metric);
|
||||||
|
}
|
||||||
|
return extra_metrics;
|
||||||
|
}
|
@ -20,4 +20,5 @@
|
|||||||
export { getMetricOffsetsMap } from './getMetricOffsetsMap';
|
export { getMetricOffsetsMap } from './getMetricOffsetsMap';
|
||||||
export { isTimeComparison } from './isTimeComparison';
|
export { isTimeComparison } from './isTimeComparison';
|
||||||
export { isDerivedSeries } from './isDerivedSeries';
|
export { isDerivedSeries } from './isDerivedSeries';
|
||||||
|
export { extractExtraMetrics } from './extractExtraMetrics';
|
||||||
export { TIME_COMPARISON_SEPARATOR } from './constants';
|
export { TIME_COMPARISON_SEPARATOR } from './constants';
|
||||||
|
@ -23,12 +23,16 @@ import {
|
|||||||
getColumnLabel,
|
getColumnLabel,
|
||||||
getMetricLabel,
|
getMetricLabel,
|
||||||
isDefined,
|
isDefined,
|
||||||
isEqualArray,
|
|
||||||
QueryFormColumn,
|
QueryFormColumn,
|
||||||
QueryFormMetric,
|
QueryFormMetric,
|
||||||
t,
|
t,
|
||||||
} from '@superset-ui/core';
|
} from '@superset-ui/core';
|
||||||
import { ControlPanelState, ControlState, ControlStateMapping } from '../types';
|
import {
|
||||||
|
ControlPanelState,
|
||||||
|
ControlState,
|
||||||
|
ControlStateMapping,
|
||||||
|
isDataset,
|
||||||
|
} from '../types';
|
||||||
import { isTemporalColumn } from '../utils';
|
import { isTemporalColumn } from '../utils';
|
||||||
|
|
||||||
export const contributionModeControl = {
|
export const contributionModeControl = {
|
||||||
@ -59,39 +63,42 @@ export const xAxisSortControl = {
|
|||||||
name: 'x_axis_sort',
|
name: 'x_axis_sort',
|
||||||
config: {
|
config: {
|
||||||
type: 'XAxisSortControl',
|
type: 'XAxisSortControl',
|
||||||
label: t('X-Axis Sort By'),
|
label: (state: ControlPanelState) =>
|
||||||
description: t('Whether to sort descending or ascending on the X-Axis.'),
|
state.form_data?.orientation === 'horizontal'
|
||||||
shouldMapStateToProps: (
|
? t('Y-Axis Sort By')
|
||||||
prevState: ControlPanelState,
|
: t('X-Axis Sort By'),
|
||||||
state: ControlPanelState,
|
description: t('Decides which column to sort the base axis by.'),
|
||||||
) => {
|
shouldMapStateToProps: () => true,
|
||||||
const prevOptions = [
|
mapStateToProps: (state: ControlPanelState, controlState: ControlState) => {
|
||||||
getColumnLabel(prevState?.controls?.x_axis?.value as QueryFormColumn),
|
const { controls, datasource } = state;
|
||||||
...ensureIsArray(prevState?.controls?.metrics?.value).map(metric =>
|
const dataset = isDataset(datasource) ? datasource : undefined;
|
||||||
getMetricLabel(metric as QueryFormMetric),
|
const columns = [controls?.x_axis?.value as QueryFormColumn].filter(
|
||||||
),
|
Boolean,
|
||||||
];
|
);
|
||||||
const currOptions = [
|
const metrics = [
|
||||||
getColumnLabel(state?.controls?.x_axis?.value as QueryFormColumn),
|
...ensureIsArray(controls?.metrics?.value as QueryFormMetric),
|
||||||
...ensureIsArray(state?.controls?.metrics?.value).map(metric =>
|
controls?.timeseries_limit_metric?.value as QueryFormMetric,
|
||||||
getMetricLabel(metric as QueryFormMetric),
|
|
||||||
),
|
|
||||||
];
|
|
||||||
return !isEqualArray(prevOptions, currOptions);
|
|
||||||
},
|
|
||||||
mapStateToProps: (
|
|
||||||
{ controls }: { controls: ControlStateMapping },
|
|
||||||
controlState: ControlState,
|
|
||||||
) => {
|
|
||||||
const choices = [
|
|
||||||
getColumnLabel(controls?.x_axis?.value as QueryFormColumn),
|
|
||||||
...ensureIsArray(controls?.metrics?.value).map(metric =>
|
|
||||||
getMetricLabel(metric as QueryFormMetric),
|
|
||||||
),
|
|
||||||
].filter(Boolean);
|
].filter(Boolean);
|
||||||
|
const options = [
|
||||||
|
...columns.map(column => {
|
||||||
|
const value = getColumnLabel(column);
|
||||||
|
return {
|
||||||
|
value,
|
||||||
|
label: dataset?.verbose_map?.[value] || value,
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
...metrics.map(metric => {
|
||||||
|
const value = getMetricLabel(metric);
|
||||||
|
return {
|
||||||
|
value,
|
||||||
|
label: dataset?.verbose_map?.[value] || value,
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
];
|
||||||
|
|
||||||
const shouldReset = !(
|
const shouldReset = !(
|
||||||
typeof controlState.value === 'string' &&
|
typeof controlState.value === 'string' &&
|
||||||
choices.includes(controlState.value) &&
|
options.map(option => option.value).includes(controlState.value) &&
|
||||||
!isTemporalColumn(
|
!isTemporalColumn(
|
||||||
getColumnLabel(controls?.x_axis?.value as QueryFormColumn),
|
getColumnLabel(controls?.x_axis?.value as QueryFormColumn),
|
||||||
controls?.datasource?.datasource,
|
controls?.datasource?.datasource,
|
||||||
@ -100,10 +107,7 @@ export const xAxisSortControl = {
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
shouldReset,
|
shouldReset,
|
||||||
options: choices.map(entry => ({
|
options,
|
||||||
value: entry,
|
|
||||||
label: entry,
|
|
||||||
})),
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
visibility: xAxisSortVisibility,
|
visibility: xAxisSortVisibility,
|
||||||
@ -114,9 +118,12 @@ export const xAxisSortAscControl = {
|
|||||||
name: 'x_axis_sort_asc',
|
name: 'x_axis_sort_asc',
|
||||||
config: {
|
config: {
|
||||||
type: 'CheckboxControl',
|
type: 'CheckboxControl',
|
||||||
label: t('X-Axis Sort Ascending'),
|
label: (state: ControlPanelState) =>
|
||||||
|
state.form_data?.orientation === 'horizontal'
|
||||||
|
? t('Y-Axis Sort Ascending')
|
||||||
|
: t('X-Axis Sort Ascending'),
|
||||||
default: true,
|
default: true,
|
||||||
description: t('Whether to sort descending or ascending on the X-Axis.'),
|
description: t('Whether to sort ascending or descending on the base Axis.'),
|
||||||
visibility: xAxisSortVisibility,
|
visibility: xAxisSortVisibility,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -185,3 +185,33 @@ test('pivot by adhoc x_axis', () => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('pivot by x_axis with extra metrics', () => {
|
||||||
|
expect(
|
||||||
|
pivotOperator(
|
||||||
|
{
|
||||||
|
...formData,
|
||||||
|
x_axis: 'foo',
|
||||||
|
x_axis_sort: 'bar',
|
||||||
|
groupby: [],
|
||||||
|
timeseries_limit_metric: 'bar',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
...queryObject,
|
||||||
|
series_columns: [],
|
||||||
|
},
|
||||||
|
),
|
||||||
|
).toEqual({
|
||||||
|
operation: 'pivot',
|
||||||
|
options: {
|
||||||
|
index: ['foo'],
|
||||||
|
columns: [],
|
||||||
|
aggregates: {
|
||||||
|
'count(*)': { operator: 'mean' },
|
||||||
|
'sum(val)': { operator: 'mean' },
|
||||||
|
bar: { operator: 'mean' },
|
||||||
|
},
|
||||||
|
drop_missing_columns: false,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
@ -146,3 +146,28 @@ test('should sort by axis', () => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('should sort by extra metric', () => {
|
||||||
|
Object.defineProperty(supersetCoreModule, 'hasGenericChartAxes', {
|
||||||
|
value: true,
|
||||||
|
});
|
||||||
|
expect(
|
||||||
|
sortOperator(
|
||||||
|
{
|
||||||
|
...formData,
|
||||||
|
x_axis_sort: 'my_limit_metric',
|
||||||
|
x_axis_sort_asc: true,
|
||||||
|
x_axis: 'Categorical Column',
|
||||||
|
groupby: [],
|
||||||
|
timeseries_limit_metric: 'my_limit_metric',
|
||||||
|
},
|
||||||
|
queryObject,
|
||||||
|
),
|
||||||
|
).toEqual({
|
||||||
|
operation: 'sort',
|
||||||
|
options: {
|
||||||
|
by: 'my_limit_metric',
|
||||||
|
ascending: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
@ -0,0 +1,94 @@
|
|||||||
|
/**
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
import { QueryFormData, QueryFormMetric } from '@superset-ui/core';
|
||||||
|
import { extractExtraMetrics } from '@superset-ui/chart-controls';
|
||||||
|
|
||||||
|
const baseFormData: QueryFormData = {
|
||||||
|
datasource: 'dummy',
|
||||||
|
viz_type: 'table',
|
||||||
|
metrics: ['a', 'b'],
|
||||||
|
columns: ['foo', 'bar'],
|
||||||
|
limit: 100,
|
||||||
|
metrics_b: ['c', 'd'],
|
||||||
|
columns_b: ['hello', 'world'],
|
||||||
|
limit_b: 200,
|
||||||
|
};
|
||||||
|
|
||||||
|
const metric: QueryFormMetric = {
|
||||||
|
expressionType: 'SQL',
|
||||||
|
sqlExpression: 'case when 1 then 1 else 2 end',
|
||||||
|
label: 'foo',
|
||||||
|
};
|
||||||
|
|
||||||
|
test('returns empty array if relevant controls missing', () => {
|
||||||
|
expect(
|
||||||
|
extractExtraMetrics({
|
||||||
|
...baseFormData,
|
||||||
|
}),
|
||||||
|
).toEqual([]);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('returns empty array if x_axis_sort is not same as timeseries_limit_metric', () => {
|
||||||
|
expect(
|
||||||
|
extractExtraMetrics({
|
||||||
|
...baseFormData,
|
||||||
|
timeseries_limit_metric: 'foo',
|
||||||
|
x_axis_sort: 'bar',
|
||||||
|
}),
|
||||||
|
).toEqual([]);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('returns correct column if sort columns match', () => {
|
||||||
|
expect(
|
||||||
|
extractExtraMetrics({
|
||||||
|
...baseFormData,
|
||||||
|
timeseries_limit_metric: 'foo',
|
||||||
|
x_axis_sort: 'foo',
|
||||||
|
}),
|
||||||
|
).toEqual(['foo']);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('handles adhoc metrics correctly', () => {
|
||||||
|
expect(
|
||||||
|
extractExtraMetrics({
|
||||||
|
...baseFormData,
|
||||||
|
timeseries_limit_metric: metric,
|
||||||
|
x_axis_sort: 'foo',
|
||||||
|
}),
|
||||||
|
).toEqual([metric]);
|
||||||
|
|
||||||
|
expect(
|
||||||
|
extractExtraMetrics({
|
||||||
|
...baseFormData,
|
||||||
|
timeseries_limit_metric: metric,
|
||||||
|
x_axis_sort: 'bar',
|
||||||
|
}),
|
||||||
|
).toEqual([]);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('returns empty array if groupby populated', () => {
|
||||||
|
expect(
|
||||||
|
extractExtraMetrics({
|
||||||
|
...baseFormData,
|
||||||
|
groupby: ['bar'],
|
||||||
|
timeseries_limit_metric: 'foo',
|
||||||
|
x_axis_sort: 'foo',
|
||||||
|
}),
|
||||||
|
).toEqual([]);
|
||||||
|
});
|
@ -19,24 +19,25 @@
|
|||||||
import {
|
import {
|
||||||
buildQueryContext,
|
buildQueryContext,
|
||||||
ensureIsArray,
|
ensureIsArray,
|
||||||
|
getXAxisColumn,
|
||||||
|
isXAxisSet,
|
||||||
normalizeOrderBy,
|
normalizeOrderBy,
|
||||||
PostProcessingPivot,
|
PostProcessingPivot,
|
||||||
QueryFormData,
|
QueryFormData,
|
||||||
getXAxisColumn,
|
|
||||||
isXAxisSet,
|
|
||||||
} from '@superset-ui/core';
|
} from '@superset-ui/core';
|
||||||
import {
|
import {
|
||||||
rollingWindowOperator,
|
contributionOperator,
|
||||||
timeCompareOperator,
|
extractExtraMetrics,
|
||||||
|
flattenOperator,
|
||||||
isTimeComparison,
|
isTimeComparison,
|
||||||
pivotOperator,
|
pivotOperator,
|
||||||
resampleOperator,
|
|
||||||
renameOperator,
|
|
||||||
contributionOperator,
|
|
||||||
prophetOperator,
|
prophetOperator,
|
||||||
timeComparePivotOperator,
|
renameOperator,
|
||||||
flattenOperator,
|
resampleOperator,
|
||||||
|
rollingWindowOperator,
|
||||||
sortOperator,
|
sortOperator,
|
||||||
|
timeComparePivotOperator,
|
||||||
|
timeCompareOperator,
|
||||||
} from '@superset-ui/chart-controls';
|
} from '@superset-ui/chart-controls';
|
||||||
|
|
||||||
export default function buildQuery(formData: QueryFormData) {
|
export default function buildQuery(formData: QueryFormData) {
|
||||||
@ -62,6 +63,9 @@ export default function buildQuery(formData: QueryFormData) {
|
|||||||
2015-03-01 318.0 0.0
|
2015-03-01 318.0 0.0
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
// only add series limit metric if it's explicitly needed e.g. for sorting
|
||||||
|
const extra_metrics = extractExtraMetrics(formData);
|
||||||
|
|
||||||
const pivotOperatorInRuntime: PostProcessingPivot = isTimeComparison(
|
const pivotOperatorInRuntime: PostProcessingPivot = isTimeComparison(
|
||||||
formData,
|
formData,
|
||||||
baseQueryObject,
|
baseQueryObject,
|
||||||
@ -69,15 +73,16 @@ export default function buildQuery(formData: QueryFormData) {
|
|||||||
? timeComparePivotOperator(formData, baseQueryObject)
|
? timeComparePivotOperator(formData, baseQueryObject)
|
||||||
: pivotOperator(formData, baseQueryObject);
|
: pivotOperator(formData, baseQueryObject);
|
||||||
|
|
||||||
|
const columns = [
|
||||||
|
...(isXAxisSet(formData) ? ensureIsArray(getXAxisColumn(formData)) : []),
|
||||||
|
...ensureIsArray(groupby),
|
||||||
|
];
|
||||||
|
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
...baseQueryObject,
|
...baseQueryObject,
|
||||||
columns: [
|
metrics: [...(baseQueryObject.metrics || []), ...extra_metrics],
|
||||||
...(isXAxisSet(formData)
|
columns,
|
||||||
? ensureIsArray(getXAxisColumn(formData))
|
|
||||||
: []),
|
|
||||||
...ensureIsArray(groupby),
|
|
||||||
],
|
|
||||||
series_columns: groupby,
|
series_columns: groupby,
|
||||||
...(isXAxisSet(formData) ? {} : { is_timeseries: true }),
|
...(isXAxisSet(formData) ? {} : { is_timeseries: true }),
|
||||||
// todo: move `normalizeOrderBy to extractQueryFields`
|
// todo: move `normalizeOrderBy to extractQueryFields`
|
||||||
|
@ -19,21 +19,25 @@
|
|||||||
/* eslint-disable camelcase */
|
/* eslint-disable camelcase */
|
||||||
import {
|
import {
|
||||||
AnnotationLayer,
|
AnnotationLayer,
|
||||||
|
AxisType,
|
||||||
CategoricalColorNamespace,
|
CategoricalColorNamespace,
|
||||||
GenericDataType,
|
GenericDataType,
|
||||||
|
getMetricLabel,
|
||||||
getNumberFormatter,
|
getNumberFormatter,
|
||||||
|
getXAxisLabel,
|
||||||
|
isDefined,
|
||||||
isEventAnnotationLayer,
|
isEventAnnotationLayer,
|
||||||
isFormulaAnnotationLayer,
|
isFormulaAnnotationLayer,
|
||||||
isIntervalAnnotationLayer,
|
isIntervalAnnotationLayer,
|
||||||
isTimeseriesAnnotationLayer,
|
|
||||||
TimeseriesChartDataResponseResult,
|
|
||||||
t,
|
|
||||||
AxisType,
|
|
||||||
getXAxisLabel,
|
|
||||||
isPhysicalColumn,
|
isPhysicalColumn,
|
||||||
isDefined,
|
isTimeseriesAnnotationLayer,
|
||||||
|
t,
|
||||||
|
TimeseriesChartDataResponseResult,
|
||||||
} from '@superset-ui/core';
|
} from '@superset-ui/core';
|
||||||
import { isDerivedSeries } from '@superset-ui/chart-controls';
|
import {
|
||||||
|
extractExtraMetrics,
|
||||||
|
isDerivedSeries,
|
||||||
|
} from '@superset-ui/chart-controls';
|
||||||
import { EChartsCoreOption, SeriesOption } from 'echarts';
|
import { EChartsCoreOption, SeriesOption } from 'echarts';
|
||||||
import { ZRLineType } from 'echarts/types/src/util/types';
|
import { ZRLineType } from 'echarts/types/src/util/types';
|
||||||
import {
|
import {
|
||||||
@ -114,39 +118,39 @@ export default function transformProps(
|
|||||||
colorScheme,
|
colorScheme,
|
||||||
contributionMode,
|
contributionMode,
|
||||||
forecastEnabled,
|
forecastEnabled,
|
||||||
|
groupby,
|
||||||
legendOrientation,
|
legendOrientation,
|
||||||
legendType,
|
legendType,
|
||||||
legendMargin,
|
legendMargin,
|
||||||
logAxis,
|
logAxis,
|
||||||
markerEnabled,
|
markerEnabled,
|
||||||
markerSize,
|
markerSize,
|
||||||
opacity,
|
|
||||||
minorSplitLine,
|
minorSplitLine,
|
||||||
|
onlyTotal,
|
||||||
|
opacity,
|
||||||
|
orientation,
|
||||||
|
percentageThreshold,
|
||||||
|
richTooltip,
|
||||||
seriesType,
|
seriesType,
|
||||||
showLegend,
|
showLegend,
|
||||||
stack,
|
|
||||||
truncateYAxis,
|
|
||||||
yAxisFormat,
|
|
||||||
xAxisTimeFormat,
|
|
||||||
yAxisBounds,
|
|
||||||
tooltipTimeFormat,
|
|
||||||
tooltipSortByMetric,
|
|
||||||
zoomable,
|
|
||||||
richTooltip,
|
|
||||||
xAxis: xAxisOrig,
|
|
||||||
xAxisLabelRotation,
|
|
||||||
groupby,
|
|
||||||
showValue,
|
showValue,
|
||||||
onlyTotal,
|
|
||||||
percentageThreshold,
|
|
||||||
xAxisTitle,
|
|
||||||
yAxisTitle,
|
|
||||||
xAxisTitleMargin,
|
|
||||||
yAxisTitleMargin,
|
|
||||||
yAxisTitlePosition,
|
|
||||||
sliceId,
|
sliceId,
|
||||||
timeGrainSqla,
|
timeGrainSqla,
|
||||||
orientation,
|
stack,
|
||||||
|
tooltipTimeFormat,
|
||||||
|
tooltipSortByMetric,
|
||||||
|
truncateYAxis,
|
||||||
|
xAxis: xAxisOrig,
|
||||||
|
xAxisLabelRotation,
|
||||||
|
xAxisTimeFormat,
|
||||||
|
xAxisTitle,
|
||||||
|
xAxisTitleMargin,
|
||||||
|
yAxisBounds,
|
||||||
|
yAxisFormat,
|
||||||
|
yAxisTitle,
|
||||||
|
yAxisTitleMargin,
|
||||||
|
yAxisTitlePosition,
|
||||||
|
zoomable,
|
||||||
}: EchartsTimeseriesFormData = { ...DEFAULT_FORM_DATA, ...formData };
|
}: EchartsTimeseriesFormData = { ...DEFAULT_FORM_DATA, ...formData };
|
||||||
const refs: Refs = {};
|
const refs: Refs = {};
|
||||||
|
|
||||||
@ -168,9 +172,14 @@ export default function transformProps(
|
|||||||
xAxisCol: xAxisLabel,
|
xAxisCol: xAxisLabel,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
const extraMetricLabels = extractExtraMetrics(chartProps.rawFormData).map(
|
||||||
|
getMetricLabel,
|
||||||
|
);
|
||||||
|
|
||||||
const rawSeries = extractSeries(rebasedData, {
|
const rawSeries = extractSeries(rebasedData, {
|
||||||
fillNeighborValue: stack && !forecastEnabled ? 0 : undefined,
|
fillNeighborValue: stack && !forecastEnabled ? 0 : undefined,
|
||||||
xAxis: xAxisLabel,
|
xAxis: xAxisLabel,
|
||||||
|
extraMetricLabels,
|
||||||
removeNulls: seriesType === EchartsTimeseriesSeriesType.Scatter,
|
removeNulls: seriesType === EchartsTimeseriesSeriesType.Scatter,
|
||||||
stack,
|
stack,
|
||||||
totalStackedValues,
|
totalStackedValues,
|
||||||
|
@ -113,6 +113,7 @@ export function extractSeries(
|
|||||||
opts: {
|
opts: {
|
||||||
fillNeighborValue?: number;
|
fillNeighborValue?: number;
|
||||||
xAxis?: string;
|
xAxis?: string;
|
||||||
|
extraMetricLabels?: string[];
|
||||||
removeNulls?: boolean;
|
removeNulls?: boolean;
|
||||||
stack?: StackType;
|
stack?: StackType;
|
||||||
totalStackedValues?: number[];
|
totalStackedValues?: number[];
|
||||||
@ -122,6 +123,7 @@ export function extractSeries(
|
|||||||
const {
|
const {
|
||||||
fillNeighborValue,
|
fillNeighborValue,
|
||||||
xAxis = DTTM_ALIAS,
|
xAxis = DTTM_ALIAS,
|
||||||
|
extraMetricLabels = [],
|
||||||
removeNulls = false,
|
removeNulls = false,
|
||||||
stack = false,
|
stack = false,
|
||||||
totalStackedValues = [],
|
totalStackedValues = [],
|
||||||
@ -135,6 +137,7 @@ export function extractSeries(
|
|||||||
|
|
||||||
return Object.keys(rows[0])
|
return Object.keys(rows[0])
|
||||||
.filter(key => key !== xAxis && key !== DTTM_ALIAS)
|
.filter(key => key !== xAxis && key !== DTTM_ALIAS)
|
||||||
|
.filter(key => !extraMetricLabels.includes(key))
|
||||||
.map(key => ({
|
.map(key => ({
|
||||||
id: key,
|
id: key,
|
||||||
name: key,
|
name: key,
|
||||||
|
Loading…
Reference in New Issue
Block a user