fix(charts): apply resample before rolling window in post-processing pipeline (#37987)

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Varun Chawla
2026-03-04 11:25:42 -08:00
committed by GitHub
parent 27d54f8421
commit 796c206ee7
6 changed files with 12 additions and 10 deletions

View File

@@ -64,8 +64,8 @@ describe('BigNumberWithTrendline buildQuery', () => {
expect(queryContext.queries.length).toBe(1);
expect(queryContext.queries[0].post_processing).toEqual([
{ operation: 'pivot' },
{ operation: 'rolling' },
{ operation: 'resample' },
{ operation: 'rolling' },
{ operation: 'flatten' },
]);
});
@@ -79,8 +79,8 @@ describe('BigNumberWithTrendline buildQuery', () => {
expect(queryContext.queries.length).toBe(1);
expect(queryContext.queries[0].post_processing).toEqual([
{ operation: 'pivot' },
{ operation: 'rolling' },
{ operation: 'resample' },
{ operation: 'rolling' },
{ operation: 'flatten' },
]);
});

View File

@@ -47,8 +47,8 @@ export default function buildQuery(formData: QueryFormData) {
...(timeColumn.length ? {} : { is_timeseries: true }),
post_processing: [
pivotOperator(formData, baseQueryObject),
rollingWindowOperator(formData, baseQueryObject),
resampleOperator(formData, baseQueryObject),
rollingWindowOperator(formData, baseQueryObject),
flattenOperator(formData, baseQueryObject),
].filter(Boolean),
},

View File

@@ -75,9 +75,9 @@ export default function buildQuery(formData: QueryFormData) {
time_offsets: isTimeComparison(fd, queryObject) ? fd.time_compare : [],
post_processing: [
pivotOperatorInRuntime,
resampleOperator(fd, queryObject),
rollingWindowOperator(fd, queryObject),
timeCompareOperator(fd, queryObject),
resampleOperator(fd, queryObject),
renameOperator(fd, queryObject),
flattenOperator(fd, queryObject),
],

View File

@@ -94,13 +94,15 @@ export default function buildQuery(formData: QueryFormData) {
time_offsets,
/* Note that:
1. The resample, rolling, cum, timeCompare operators should be after pivot.
2. the flatOperator makes multiIndex Dataframe into flat Dataframe
2. Resample must come before rolling so that imputed values are
included in the rolling window calculation.
3. the flatOperator makes multiIndex Dataframe into flat Dataframe
*/
post_processing: [
pivotOperatorInRuntime,
resampleOperator(formData, baseQueryObject),
rollingWindowOperator(formData, baseQueryObject),
timeCompareOperator(formData, baseQueryObject),
resampleOperator(formData, baseQueryObject),
renameOperator(formData, baseQueryObject),
contributionOperator(formData, baseQueryObject, time_offsets),
sortOperator(formData, baseQueryObject),

View File

@@ -431,5 +431,5 @@ test('should add a formula annotation when X-axis column has dataset-level label
expect(formulaSeries).toBeDefined();
expect(formulaSeries?.data).toBeDefined();
expect(Array.isArray(formulaSeries?.data)).toBe(true);
expect((formulaSeries?.data as unknown[])?.length).toBeGreaterThan(0);
expect((formulaSeries!.data as unknown[]).length).toBeGreaterThan(0);
});

View File

@@ -306,8 +306,8 @@ describe('EchartsTimeseries transformProps', () => {
expect(formulaSeries).toBeDefined();
expect(formulaSeries?.data).toBeDefined();
expect(Array.isArray(formulaSeries?.data)).toBe(true);
expect((formulaSeries?.data as unknown[])?.length).toBeGreaterThan(0);
const firstDataPoint = (formulaSeries?.data as [number, number][])?.[0];
expect((formulaSeries!.data as unknown[]).length).toBeGreaterThan(0);
const firstDataPoint = (formulaSeries!.data as [number, number][])[0];
expect(firstDataPoint).toBeDefined();
expect(firstDataPoint[1]).toBe(firstDataPoint[0] * 2);
});
@@ -386,7 +386,7 @@ describe('EchartsTimeseries transformProps', () => {
result.echartOptions.series as SeriesOption[] | undefined
)?.find((s: SeriesOption) => s.name === 'My Formula');
expect(formulaSeries).toBeDefined();
const firstDataPoint = (formulaSeries?.data as [number, number][])?.[0];
const firstDataPoint = (formulaSeries!.data as [number, number][])[0];
expect(firstDataPoint).toBeDefined();
expect(firstDataPoint[0]).toBe(firstDataPoint[1] * 2);
});