diff --git a/superset-frontend/src/explore/components/controls/TimeSeriesColumnControl/TimeSeriesColumnControl.test.tsx b/superset-frontend/src/explore/components/controls/TimeSeriesColumnControl/TimeSeriesColumnControl.test.tsx index 589ef9173a496..631c34f3f8a8a 100644 --- a/superset-frontend/src/explore/components/controls/TimeSeriesColumnControl/TimeSeriesColumnControl.test.tsx +++ b/superset-frontend/src/explore/components/controls/TimeSeriesColumnControl/TimeSeriesColumnControl.test.tsx @@ -104,6 +104,19 @@ test('triggers onChange when time lag changes', () => { expect(onChange).toHaveBeenCalledWith(expect.objectContaining({ timeLag })); }); +test('time lag allows negative values', () => { + const timeLag = '-1'; + const onChange = jest.fn(); + render(); + userEvent.click(screen.getByRole('button')); + const timeLagInput = screen.getByPlaceholderText('Time Lag'); + userEvent.clear(timeLagInput); + userEvent.type(timeLagInput, timeLag); + expect(onChange).not.toHaveBeenCalled(); + userEvent.click(screen.getByRole('button', { name: 'Save' })); + expect(onChange).toHaveBeenCalledWith(expect.objectContaining({ timeLag })); +}); + test('triggers onChange when color bounds changes', () => { const min = 1; const max = 5; diff --git a/superset-frontend/src/explore/components/controls/TimeSeriesColumnControl/index.jsx b/superset-frontend/src/explore/components/controls/TimeSeriesColumnControl/index.jsx index 29ac223cf3e03..e51a2f496015b 100644 --- a/superset-frontend/src/explore/components/controls/TimeSeriesColumnControl/index.jsx +++ b/superset-frontend/src/explore/components/controls/TimeSeriesColumnControl/index.jsx @@ -248,7 +248,9 @@ export default class TimeSeriesColumnControl extends React.Component { {['time', 'avg'].indexOf(this.state.colType) >= 0 && this.formRow( t('Time lag'), - t('Number of periods to compare against'), + t( + 'Number of periods to compare against. You can use negative numbers to compare from the beginning of the time range.', + ), 'time-lag', = totalLag) { + if (Math.abs(timeLag) >= totalLag) { errorMsg = `The time lag set at ${timeLag} is too large for the length of data at ${reversedEntries.length}. No data available.`; + } else if (timeLag < 0) { + v = reversedEntries[totalLag + timeLag][valueField]; } else { v = reversedEntries[timeLag][valueField]; }