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];
}