Skip to content

Commit

Permalink
feat: add timezone support to logs explorer chart (built with Chartjs)
Browse files Browse the repository at this point in the history
  • Loading branch information
ahmadshaheer committed Dec 1, 2024
1 parent a7da3f3 commit 612dd06
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 3 deletions.
3 changes: 2 additions & 1 deletion frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,14 +60,15 @@
"babel-preset-react-app": "^10.0.1",
"chart.js": "3.9.1",
"chartjs-adapter-date-fns": "^2.0.0",
"chartjs-adapter-dayjs-3": "1.2.3",
"chartjs-plugin-annotation": "^1.4.0",
"classnames": "2.3.2",
"color": "^4.2.1",
"color-alpha": "1.1.3",
"cross-env": "^7.0.3",
"css-loader": "5.0.0",
"css-minimizer-webpack-plugin": "5.0.1",
"dayjs": "^1.10.7",
"dayjs": "1.11.13",
"dompurify": "3.1.3",
"dotenv": "8.2.0",
"event-source-polyfill": "1.0.31",
Expand Down
36 changes: 36 additions & 0 deletions frontend/src/components/Graph/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import 'chartjs-adapter-date-fns';

import {
_adapters,
BarController,
BarElement,
CategoryScale,
Expand All @@ -18,8 +21,10 @@ import {
} from 'chart.js';
import annotationPlugin from 'chartjs-plugin-annotation';
import { generateGridTitle } from 'container/GridPanelSwitch/utils';
import dayjs from 'dayjs';
import { useIsDarkMode } from 'hooks/useDarkMode';
import isEqual from 'lodash-es/isEqual';
import { useTimezone } from 'providers/Timezone';
import {
forwardRef,
memo,
Expand Down Expand Up @@ -62,6 +67,17 @@ Chart.register(

Tooltip.positioners.custom = TooltipPositionHandler;

// Map of Chart.js time formats to dayjs format strings
const formatMap = {
'HH:mm:ss': 'HH:mm:ss',
'HH:mm': 'HH:mm',
'MM/DD HH:mm': 'MM/DD HH:mm',
'MM/dd HH:mm': 'MM/DD HH:mm',
'MM/DD': 'MM/DD',
'YY-MM': 'YY-MM',
YY: 'YY',
};

const Graph = forwardRef<ToggleGraphProps | undefined, GraphProps>(
(
{
Expand All @@ -80,11 +96,13 @@ const Graph = forwardRef<ToggleGraphProps | undefined, GraphProps>(
dragSelectColor,
},
ref,
// eslint-disable-next-line sonarjs/cognitive-complexity
): JSX.Element => {
const nearestDatasetIndex = useRef<null | number>(null);
const chartRef = useRef<HTMLCanvasElement>(null);
const isDarkMode = useIsDarkMode();
const gridTitle = useMemo(() => generateGridTitle(title), [title]);
const { timezone } = useTimezone();

const currentTheme = isDarkMode ? 'dark' : 'light';
const xAxisTimeUnit = useXAxisTimeUnit(data); // Computes the relevant time unit for x axis by analyzing the time stamp data
Expand Down Expand Up @@ -112,6 +130,22 @@ const Graph = forwardRef<ToggleGraphProps | undefined, GraphProps>(
return 'rgba(231,233,237,0.8)';
}, [currentTheme]);

// Override Chart.js date adapter to use dayjs with timezone support
useEffect(() => {
_adapters._date.override({
format(time: number | Date, fmt: string) {
const dayjsTime = dayjs(time).tz(timezone?.value);
const format = formatMap[fmt as keyof typeof formatMap];
if (!format) {
console.warn(`Missing datetime format for ${fmt}`);
return dayjsTime.format('YYYY-MM-DD HH:mm:ss'); // fallback format
}

return dayjsTime.format(format);
},
});
}, [timezone]);

const buildChart = useCallback(() => {
if (lineChartRef.current !== undefined) {
lineChartRef.current.destroy();
Expand All @@ -132,6 +166,7 @@ const Graph = forwardRef<ToggleGraphProps | undefined, GraphProps>(
isStacked,
onClickHandler,
data,
timezone,
);

const chartHasData = hasData(data);
Expand Down Expand Up @@ -166,6 +201,7 @@ const Graph = forwardRef<ToggleGraphProps | undefined, GraphProps>(
isStacked,
onClickHandler,
data,
timezone,
name,
type,
]);
Expand Down
4 changes: 3 additions & 1 deletion frontend/src/components/Graph/utils.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Chart, ChartConfiguration, ChartData, Color } from 'chart.js';
import * as chartjsAdapter from 'chartjs-adapter-date-fns';
import { Timezone } from 'components/CustomTimePicker/timezoneUtils';
import dayjs from 'dayjs';
import { MutableRefObject } from 'react';

Expand Down Expand Up @@ -50,6 +51,7 @@ export const getGraphOptions = (
isStacked: boolean | undefined,
onClickHandler: GraphOnClickHandler | undefined,
data: ChartData,
timezone: Timezone,
// eslint-disable-next-line sonarjs/cognitive-complexity
): CustomChartOptions => ({
animation: {
Expand Down Expand Up @@ -97,7 +99,7 @@ export const getGraphOptions = (
callbacks: {
title(context): string | string[] {
const date = dayjs(context[0].parsed.x);
return date.format('MMM DD, YYYY, HH:mm:ss');
return date.tz(timezone?.value).format('MMM DD, YYYY, HH:mm:ss');
},
label(context): string | string[] {
let label = context.dataset.label || '';
Expand Down
12 changes: 11 additions & 1 deletion frontend/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -6280,6 +6280,11 @@ chartjs-adapter-date-fns@^2.0.0:
resolved "https://registry.npmjs.org/chartjs-adapter-date-fns/-/chartjs-adapter-date-fns-2.0.1.tgz"
integrity sha512-v3WV9rdnQ05ce3A0ZCjzUekJCAbfm6+3HqSoeY2BIkdMYZoYr/4T+ril1tZyDl869lz6xdNVMXejUFT9YKpw4A==

[email protected]:
version "1.2.3"
resolved "https://registry.yarnpkg.com/chartjs-adapter-dayjs-3/-/chartjs-adapter-dayjs-3-1.2.3.tgz#c3c4c61ec2b4d3a5532e80f159c0e78b92f2bf2c"
integrity sha512-H8m1c2cFi9zdiJ0IfY7txUSSZusnS671sUuE6dbmvcaHmSFTMNoWH5lJvNj+oM1hLRsiP5pSTiB7InAMDJP+rQ==

chartjs-plugin-annotation@^1.4.0:
version "1.4.0"
resolved "https://registry.npmjs.org/chartjs-plugin-annotation/-/chartjs-plugin-annotation-1.4.0.tgz"
Expand Down Expand Up @@ -7219,7 +7224,12 @@ [email protected]:
resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-3.6.0.tgz#f20ca4fe94f8b754951b24240676e8618c0206bf"
integrity sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww==

dayjs@^1.10.7, dayjs@^1.11.1:
[email protected]:
version "1.11.13"
resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.13.tgz#92430b0139055c3ebb60150aa13e860a4b5a366c"
integrity sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==

dayjs@^1.11.1:
version "1.11.7"
resolved "https://registry.npmjs.org/dayjs/-/dayjs-1.11.7.tgz"
integrity sha512-+Yw9U6YO5TQohxLcIkrXBeY73WP3ejHWVvx8XCk3gxvQDCTEmS48ZrSZCKciI7Bhl/uCMyxYtE9UqRILmFphkQ==
Expand Down

0 comments on commit 612dd06

Please sign in to comment.