- 
                Notifications
    You must be signed in to change notification settings 
- Fork 32
Added Configurable Time Stamp Formatting in Chart Panel #481
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
| @emrberk Please take a look and review this. | 
| // Detect timestamp columns by type or name patterns | ||
| return col.type === 'TIMESTAMP' || | ||
| col.type === 'TIMESTAMP_NS' || | ||
| /timestamp|time|date|created|updated/i.test(col.name) | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We cannot rely on column name for detecting the timestamp. Types are already enough for this purpose. We have an utility function in ImportCSVFiles, so you can move it to src/utils/... and use it here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll work on this.
| const parsed = Date.parse(value) | ||
| return !isNaN(parsed) && parsed > 0 | ||
| } | ||
| if (typeof value === 'number') { | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In which cases does QuestDB return a number for a timestamp column? Why do we have this check?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the time is stored in milliseconds since epoch for example.
| date = new Date(timestamp) | ||
| } else if (typeof timestamp === 'number') { | ||
| date = new Date(timestamp) | ||
| } else { | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Which case is covered in this branch? Can you give an example?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you are asking about number, then like before it could be the milliseconds type. Or an ISO Format String.
| return timestamp.toString() | ||
| } | ||
|  | ||
| if (isNaN(date.getTime())) { | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Which case is covered in this branch? Can you give an example?
| // Helper function to pad numbers with leading zeros | ||
| const pad = (num: number): string => num.toString().padStart(2, '0') | ||
|  | ||
| switch (format) { | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We already have date-fns dependency and it provides useful functions for this purpose.
This one can be replaced with format function from that package.
| return `${Math.floor(absDiff/86400000)}d ago` | ||
| } | ||
|  | ||
| function autoDetectTimeFormat(timestamp: number): string { | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same issue, use date-fns.
| function formatRelativeTime(timestamp: number): string { | ||
| const now = new Date().getTime() | ||
| const diff = now - timestamp | ||
| const absDiff = Math.abs(diff) | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Which case do we cover with abs call?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
An edge case where future timestamps may be stored in a table. Like forecasts, for example.
| // Time format picker options | ||
| const timeFormatOptions = [ | ||
| { text: "Auto", value: "auto" }, | ||
| { text: "2021-11-21 14:04:09", value: "yyyy-MM-dd HH:mm:ss" }, | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The value string is explicit enough so that we can use it in text as well. These numbers are arbitrary.
|  | ||
| // Event listener for X-axis selection to toggle time format visibility | ||
| xAxisPicker.onChange = (info: any) => { | ||
| if (cachedResponse && cachedResponse.columns) { | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Time format picker is shown in the first render regardless of the contents of the x-axis and y-axis elements.
If you remove timestamp from x-axis, then the picker visibility is not responsive.
If you rely on the cached response, the visibility will depend on the previous draw, which is not expected.
| btnDraw.click(btnDrawClick) | ||
|  | ||
| // Event listener for X-axis selection to toggle time format visibility | ||
| xAxisPicker.onChange = (info: any) => { | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What happens if i specify a format from format picker, and include a timestamp column in y-axis?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The timestamp values will be displayed as data points.
This PR fixes #211 and implements user-selectable timestamp formatting for chart panel X-axis labels in the QuestDB Web Console, addressing the need for multiple timestamp display formats when visualizing time-series data.
Changes Made
Core Files Modified:
packages/web-console/src/js/console/quick-vis.ts- Added timestamp formatting logicpackages/web-console/src/scenes/Result/index.tsx- Added time format selector UIpackages/web-console/src/styles/_quick-vis.scss- Added styling for format controlsNew Features
Smart Time Column Detection: Automatically identifies timestamp columns in query results
7 Format Options: User can select from:
Real-time Chart Updates: Chart re-renders immediately when format changes
Technical Implementation
detectTimeColumns()function identifies TIMESTAMP columns and time-related field namesformatTimestamp()with precise formattingautoDetectTimeFormat()intelligently selects format based on data ageScreen.Recording.2025-10-05.205830.mp4