Skip to content

Commit

Permalink
fix(line-chart): Formula Annotations on Line Charts are broken (#20687)
Browse files Browse the repository at this point in the history
  • Loading branch information
stephenLYZ committed Jul 13, 2022
1 parent bd6037e commit acdb271
Show file tree
Hide file tree
Showing 7 changed files with 63 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,14 @@ export default function transformProps(
.forEach((layer: AnnotationLayer) => {
if (isFormulaAnnotationLayer(layer))
series.push(
transformFormulaAnnotation(layer, data1, colorScale, sliceId),
transformFormulaAnnotation(
layer,
data1,
xAxisCol,
xAxisType,
colorScale,
sliceId,
),
);
else if (isIntervalAnnotationLayer(layer)) {
series.push(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,14 @@ export default function transformProps(
.forEach((layer: AnnotationLayer) => {
if (isFormulaAnnotationLayer(layer))
series.push(
transformFormulaAnnotation(layer, data, colorScale, sliceId),
transformFormulaAnnotation(
layer,
data,
xAxisCol,
xAxisType,
colorScale,
sliceId,
),
);
else if (isIntervalAnnotationLayer(layer)) {
series.push(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,12 @@ import {
import { MarkLine1DDataItemOption } from 'echarts/types/src/component/marker/MarkLineModel';

import { extractForecastSeriesContext } from '../utils/forecast';
import { ForecastSeriesEnum, LegendOrientation, StackType } from '../types';
import {
AxisType,
ForecastSeriesEnum,
LegendOrientation,
StackType,
} from '../types';
import { EchartsTimeseriesSeriesType } from './types';

import {
Expand Down Expand Up @@ -250,6 +255,8 @@ export function transformSeries(
export function transformFormulaAnnotation(
layer: FormulaAnnotationLayer,
data: TimeseriesDataRecord[],
xAxisCol: string,
xAxisType: AxisType,
colorScale: CategoricalColorScale,
sliceId?: number,
): SeriesOption {
Expand All @@ -267,7 +274,7 @@ export function transformFormulaAnnotation(
},
type: 'line',
smooth: true,
data: evalFormula(layer, data),
data: evalFormula(layer, data, xAxisCol, xAxisType),
symbolSize: 0,
};
}
Expand Down
2 changes: 2 additions & 0 deletions superset-frontend/plugins/plugin-chart-echarts/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,4 +127,6 @@ export interface EchartsTitleFormData {

export type StackType = boolean | null | Partial<AreaChartExtraControlsValue>;

export type AxisType = 'time' | 'value' | 'category';

export * from './Timeseries/types';
Original file line number Diff line number Diff line change
Expand Up @@ -25,26 +25,31 @@ import {
AnnotationLayer,
AnnotationOpacity,
AnnotationType,
DataRecord,
evalExpression,
FormulaAnnotationLayer,
isRecordAnnotationResult,
isTableAnnotationLayer,
isTimeseriesAnnotationResult,
TimeseriesDataRecord,
} from '@superset-ui/core';
import { EchartsTimeseriesChartProps } from '../types';
import { AxisType, EchartsTimeseriesChartProps } from '../types';
import { EchartsMixedTimeseriesProps } from '../MixedTimeseries/types';

export function evalFormula(
formula: FormulaAnnotationLayer,
data: TimeseriesDataRecord[],
): [number, number][] {
data: DataRecord[],
xAxis: string,
xAxisType: AxisType,
): [any, number][] {
const { value: expression } = formula;

return data.map(row => [
Number(row.__timestamp),
evalExpression(expression, row.__timestamp as number),
]);
return data.map(row => {
let value = row[xAxis];
if (xAxisType === 'time') {
value = new Date(value as string).getTime();
}
return [value, evalExpression(expression, (value || 0) as number)];
});
}

export function parseAnnotationOpacity(opacity?: AnnotationOpacity): number {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import {
NULL_STRING,
TIMESERIES_CONSTANTS,
} from '../constants';
import { LegendOrientation, LegendType, StackType } from '../types';
import { AxisType, LegendOrientation, LegendType, StackType } from '../types';
import { defaultLegendPadding } from '../defaults';

function isDefined<T>(value: T | undefined | null): boolean {
Expand Down Expand Up @@ -307,9 +307,7 @@ export const currentSeries = {
legend: '',
};

export function getAxisType(
dataType?: GenericDataType,
): 'time' | 'value' | 'category' {
export function getAxisType(dataType?: GenericDataType): AxisType {
if (dataType === GenericDataType.TEMPORAL) {
return 'time';
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import {
AnnotationType,
FormulaAnnotationLayer,
TimeseriesDataRecord,
DataRecord,
} from '@superset-ui/core';
import {
evalFormula,
Expand Down Expand Up @@ -160,7 +161,7 @@ describe('evalFormula', () => {
{ __timestamp: 10 },
];

expect(evalFormula(layer, data)).toEqual([
expect(evalFormula(layer, data, '__timestamp', 'time')).toEqual([
[0, 1],
[10, 11],
]);
Expand All @@ -172,9 +173,27 @@ describe('evalFormula', () => {
{ __timestamp: 10 },
];

expect(evalFormula({ ...layer, value: 'y = x* 2 -1' }, data)).toEqual([
expect(
evalFormula(
{ ...layer, value: 'y = x* 2 -1' },
data,
'__timestamp',
'time',
),
).toEqual([
[0, -1],
[10, 19],
]);
});

it('Should evaluate a formula if axis type is category', () => {
const data: DataRecord[] = [{ gender: 'boy' }, { gender: 'girl' }];

expect(
evalFormula({ ...layer, value: 'y = 1000' }, data, 'gender', 'category'),
).toEqual([
['boy', 1000],
['girl', 1000],
]);
});
});

0 comments on commit acdb271

Please sign in to comment.