Skip to content

Commit 7518b57

Browse files
committed
Merge branch 'improvement/chart-date-format' into q/1.0
2 parents c53f85d + f74a3b1 commit 7518b57

File tree

12 files changed

+255
-197
lines changed

12 files changed

+255
-197
lines changed

src/lib/components/barchartv2/Barchart.component.test.tsx

Lines changed: 23 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -89,9 +89,9 @@ describe('Barchart', () => {
8989
</Wrapper>,
9090
);
9191

92-
expect(screen.getByText('Fri05Jul')).toBeInTheDocument();
93-
expect(screen.getByText('Sat06Jul')).toBeInTheDocument();
94-
expect(screen.getByText('Sun07Jul')).toBeInTheDocument();
92+
expect(screen.getByText('05 Jul')).toBeInTheDocument();
93+
expect(screen.getByText('06 Jul')).toBeInTheDocument();
94+
expect(screen.getByText('07 Jul')).toBeInTheDocument();
9595
});
9696
it('should render the Barchart component with error state', async () => {
9797
const { Wrapper } = getWrapper();
@@ -153,11 +153,11 @@ describe('Barchart', () => {
153153
</ChartLegendWrapper>
154154
</Wrapper>,
155155
);
156-
expect(screen.getByText('Wed03Jul')).toBeInTheDocument();
157-
expect(screen.getByText('Thu04Jul')).toBeInTheDocument();
158-
expect(screen.getByText('Fri05Jul')).toBeInTheDocument();
159-
expect(screen.getByText('Sat06Jul')).toBeInTheDocument();
160-
expect(screen.getByText('Sun07Jul')).toBeInTheDocument();
156+
expect(screen.getByText('03 Jul')).toBeInTheDocument();
157+
expect(screen.getByText('04 Jul')).toBeInTheDocument();
158+
expect(screen.getByText('05 Jul')).toBeInTheDocument();
159+
expect(screen.getByText('06 Jul')).toBeInTheDocument();
160+
expect(screen.getByText('07 Jul')).toBeInTheDocument();
161161
});
162162
it('should render when there are missing data in the time range', async () => {
163163
const bars = [
@@ -203,10 +203,10 @@ describe('Barchart', () => {
203203

204204
// Check that all days are present
205205
await waitFor(() => {
206-
expect(screen.getByText('Fri05Jul')).toBeInTheDocument();
207-
expect(screen.getByText('Sat06Jul')).toBeInTheDocument();
208-
expect(screen.getByText('Sun07Jul')).toBeInTheDocument();
209-
expect(screen.getByText('Mon08Jul')).toBeInTheDocument();
206+
expect(screen.getByText('05 Jul')).toBeInTheDocument();
207+
expect(screen.getByText('06 Jul')).toBeInTheDocument();
208+
expect(screen.getByText('07 Jul')).toBeInTheDocument();
209+
expect(screen.getByText('08 Jul')).toBeInTheDocument();
210210
});
211211
});
212212
it('should render for a specific time range', async () => {
@@ -244,13 +244,13 @@ describe('Barchart', () => {
244244
</Wrapper>,
245245
);
246246
await waitFor(() => {
247-
expect(screen.getByText('Fri05Jul')).toBeInTheDocument();
248-
expect(screen.getByText('Sat06Jul')).toBeInTheDocument();
249-
expect(screen.getByText('Sun07Jul')).toBeInTheDocument();
250-
expect(screen.getByText('Mon08Jul')).toBeInTheDocument();
251-
expect(screen.getByText('Tue09Jul')).toBeInTheDocument();
252-
expect(screen.getByText('Wed10Jul')).toBeInTheDocument();
253-
expect(screen.getByText('Thu11Jul')).toBeInTheDocument();
247+
expect(screen.getByText('05 Jul')).toBeInTheDocument();
248+
expect(screen.getByText('06 Jul')).toBeInTheDocument();
249+
expect(screen.getByText('07 Jul')).toBeInTheDocument();
250+
expect(screen.getByText('08 Jul')).toBeInTheDocument();
251+
expect(screen.getByText('09 Jul')).toBeInTheDocument();
252+
expect(screen.getByText('10 Jul')).toBeInTheDocument();
253+
expect(screen.getByText('11 Jul')).toBeInTheDocument();
254254
});
255255
});
256256
it('should render the Barchart component with hourly intervals', async () => {
@@ -411,7 +411,7 @@ describe('Barchart', () => {
411411
/>
412412
</Wrapper>,
413413
);
414-
expect(screen.getByText('Fri05Jul 10:00')).toBeInTheDocument();
414+
expect(screen.getByText('05 Jul')).toBeInTheDocument();
415415
});
416416

417417
it('should render the CustomTick component with day format', () => {
@@ -435,7 +435,7 @@ describe('Barchart', () => {
435435
/>
436436
</Wrapper>,
437437
);
438-
expect(screen.getByText('Fri05Jul')).toBeInTheDocument();
438+
expect(screen.getByText('05 Jul')).toBeInTheDocument();
439439
});
440440
it('should render the CustomTick component with hour format', () => {
441441
const { Wrapper } = getWrapper();
@@ -458,7 +458,7 @@ describe('Barchart', () => {
458458
/>
459459
</Wrapper>,
460460
);
461-
expect(screen.getByText('10:00')).toBeInTheDocument();
461+
expect(screen.getByText('05 Jul')).toBeInTheDocument();
462462
});
463463
it('should render the CustomTick component with minute format', () => {
464464
const { Wrapper } = getWrapper();
@@ -481,9 +481,7 @@ describe('Barchart', () => {
481481
/>
482482
</Wrapper>,
483483
);
484-
expect(
485-
screen.getByText(new Date('2024-07-05T10:00:00').getTime()),
486-
).toBeInTheDocument();
484+
expect(screen.getByText('05 Jul')).toBeInTheDocument();
487485
});
488486
});
489487
});

src/lib/components/barchartv2/Barchart.component.tsx

Lines changed: 22 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import {
33
Bar,
44
BarChart,
55
CartesianGrid,
6-
ReferenceLine,
76
ResponsiveContainer,
87
Tooltip,
98
TooltipContentProps,
@@ -112,33 +111,19 @@ interface CustomTickProps {
112111
/* ---------------------------------- COMPONENTS ---------------------------------- */
113112

114113
/**
115-
* Formats a date based on the interval
116-
* @param timestamp - Timestamp
117-
* @param interval - Interval in milliseconds
114+
* Get the format of the date based on the duration
115+
* @param duration - Duration in milliseconds
118116
* @returns Formatted string
119117
*/
120118
export const formatDate = (
121-
timestamp: number,
122-
interval: number,
123-
): React.ReactNode => {
124-
const date = new Date(timestamp);
125-
// More than 24 hours interval - use day and time format
126-
if (interval > 24 * 60 * 60 * 1000) {
127-
return (
128-
<>
129-
<FormattedDateTime format="chart-date" value={date} />{' '}
130-
<FormattedDateTime format="time" value={date} />
131-
</>
132-
);
133-
} else if (interval === 24 * 60 * 60 * 1000) {
134-
// Daily interval - use day format
135-
return <FormattedDateTime format="chart-date" value={date} />;
136-
} else if (interval >= 60 * 1000) {
137-
//Hourly and minute intervals - use minute format
138-
return <FormattedDateTime format="time" value={date} />;
119+
duration: number,
120+
): 'time' | 'day-month-abbreviated' | 'chart-long-term-date' => {
121+
if (duration <= 24 * 60 * 60 * 1000) {
122+
return 'time';
123+
} else if (duration <= 7 * 24 * 60 * 60 * 1000) {
124+
return 'day-month-abbreviated';
139125
} else {
140-
// minute interval or less - use full timestamp
141-
return timestamp;
126+
return 'chart-long-term-date';
142127
}
143128
};
144129

@@ -155,6 +140,11 @@ export const CustomTick = ({
155140
width / visibleTicksCount - CHART_CONSTANTS.TICK_WIDTH_OFFSET;
156141
const centerX = x - tickWidth / 2;
157142

143+
const duration =
144+
type.type === 'time'
145+
? type.timeRange.endDate.getTime() - type.timeRange.startDate.getTime()
146+
: 0;
147+
158148
return (
159149
<foreignObject
160150
x={centerX}
@@ -167,9 +157,14 @@ export const CustomTick = ({
167157
color="textSecondary"
168158
text={
169159
<Text variant="Smaller">
170-
{type.type === 'time'
171-
? formatDate(payload.value, type.timeRange.interval)
172-
: String(payload.value)}
160+
{type.type === 'time' ? (
161+
<FormattedDateTime
162+
format={formatDate(duration)}
163+
value={new Date(payload.value)}
164+
/>
165+
) : (
166+
String(payload.value)
167+
)}
173168
</Text>
174169
}
175170
centered

src/lib/components/barchartv2/BarchartTooltip.test.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ describe('ChartTooltip', () => {
3030
longDate: () => screen.queryByText(/01 July 2024/),
3131
date: () => screen.queryByText(/\b01 Jul\b/),
3232
time: () => screen.queryByText(/00:00:00/),
33+
dateTime: () => screen.queryByText(/01 Jul 00:00:00/),
3334
};
3435
it('should render the BarchartTooltip component', () => {
3536
render(
@@ -89,9 +90,8 @@ describe('ChartTooltip', () => {
8990
expect(selectors.successValue()).toBeInTheDocument();
9091
expect(selectors.failed()).toBeInTheDocument();
9192
expect(selectors.failedValue()).toBeInTheDocument();
92-
expect(selectors.date()).not.toBeInTheDocument();
93-
expect(selectors.longDate()).toBeInTheDocument();
94-
expect(selectors.time()).not.toBeInTheDocument();
93+
94+
expect(selectors.dateTime()).toBeInTheDocument();
9595
});
9696
it('should render time tooltip when type is time and interval is one hour', () => {
9797
const label = date;

src/lib/components/barchartv2/BarchartTooltip.tsx

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
1+
import { TooltipContentProps } from 'recharts';
2+
import { LegendShape } from '../chartlegend/ChartLegend';
3+
import {
4+
ChartTooltipContainer,
5+
ChartTooltipHeader,
6+
ChartTooltipItem,
7+
ChartTooltipItemsContainer,
8+
TooltipHeader,
9+
} from '../charttooltip/ChartTooltip';
110
import {
211
BarchartBars,
312
BarchartTooltipFn,
413
CategoryType,
514
TimeType,
615
} from './Barchart.component';
7-
import { FormattedDateTime } from '../date/FormattedDateTime';
8-
import { TooltipContentProps } from 'recharts';
916
import { getCurrentPoint } from './utils';
10-
import {
11-
ChartTooltipContainer,
12-
ChartTooltipItem,
13-
ChartTooltipHeader,
14-
ChartTooltipItemsContainer,
15-
} from '../charttooltip/ChartTooltip';
16-
import { LegendShape } from '../chartlegend/ChartLegend';
1717

1818
export const BarchartTooltip = <T extends BarchartBars>({
1919
type,
@@ -40,19 +40,15 @@ export const BarchartTooltip = <T extends BarchartBars>({
4040
if (tooltip) {
4141
return tooltip(currentPoint);
4242
}
43-
43+
const duration =
44+
type.type === 'time'
45+
? type.timeRange.startDate.getTime() - type.timeRange.endDate.getTime()
46+
: 0;
4447
return (
4548
<ChartTooltipContainer>
4649
<ChartTooltipHeader>
4750
{type.type === 'time' ? (
48-
<FormattedDateTime
49-
format={
50-
type.timeRange.interval < 24 * 60 * 60 * 1000
51-
? 'day-month-abbreviated-hour-minute-second'
52-
: 'long-date-without-weekday'
53-
}
54-
value={new Date(currentPoint.category)}
55-
/>
51+
<TooltipHeader duration={duration} value={currentPoint.category} />
5652
) : (
5753
currentPoint.category
5854
)}

src/lib/components/barchartv2/utils.ts

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,4 @@
1-
import {
2-
BarchartProps,
3-
BarchartBars,
4-
BarchartTooltipFn,
5-
} from './Barchart.component';
1+
import { BarchartProps, BarchartBars } from './Barchart.component';
62
import { TooltipContentProps } from 'recharts';
73
import { chartColors, ChartColors } from '../../style/theme';
84
import { useChartLegend } from '../chartlegend/ChartLegendWrapper';

src/lib/components/charttooltip/ChartTooltip.tsx

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import React from 'react';
22
import styled from 'styled-components';
33
import { spacing } from '../../spacing';
44
import { fontSize, fontWeight } from '../../style/theme';
5+
import { FormattedDateTime } from '../date/FormattedDateTime';
56

67
export const ChartTooltipContainer = styled.div`
78
border: 1px solid ${({ theme }) => theme.border};
@@ -81,3 +82,42 @@ export const ChartTooltipItemsContainer = styled.div`
8182
gap: ${spacing.r8};
8283
width: 100%;
8384
`;
85+
86+
export const ChartTooltipSeparator = styled.div`
87+
height: 1px;
88+
background-color: ${({ theme }) => theme.border};
89+
margin: ${spacing.r4} 0;
90+
width: 100%;
91+
`;
92+
93+
export type TooltipDateFormat =
94+
| 'day-month-abbreviated-year-hour-minute'
95+
| 'day-month-abbreviated-hour-minute-second'
96+
| 'day-month-abbreviated-hour-minute';
97+
98+
const getTooltipDateFormat: (duration: number) => TooltipDateFormat = (
99+
duration: number,
100+
) => {
101+
if (duration <= 60 * 60 * 1000) {
102+
return 'day-month-abbreviated-hour-minute-second';
103+
} else if (duration <= 7 * 24 * 60 * 60 * 1000) {
104+
return 'day-month-abbreviated-hour-minute';
105+
} else {
106+
return 'day-month-abbreviated-year-hour-minute';
107+
}
108+
};
109+
110+
export const TooltipHeader = ({
111+
duration,
112+
value,
113+
}: {
114+
duration: number;
115+
value: string | number;
116+
}) => {
117+
const timeFormat = getTooltipDateFormat(duration);
118+
return (
119+
<ChartTooltipHeader>
120+
<FormattedDateTime format={timeFormat} value={new Date(value)} />
121+
</ChartTooltipHeader>
122+
);
123+
};

0 commit comments

Comments
 (0)