Skip to content

Commit 46b8fea

Browse files
authored
WOOA7S-534: Show ticks for day (#45390)
* WOOA7S-534: Show ticks in hours when the interval is < 24 hours. * changelog
1 parent c0890ac commit 46b8fea

File tree

3 files changed

+33
-12
lines changed

3 files changed

+33
-12
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Significance: minor
2+
Type: added
3+
4+
Show ticks in hours when the interval is less than 24 hours.

projects/js-packages/charts/src/components/line-chart/line-chart.tsx

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { scaleTime } from '@visx/scale';
55
import { XYChart, AreaSeries, Grid, Axis, DataContext } from '@visx/xychart';
66
import { __ } from '@wordpress/i18n';
77
import clsx from 'clsx';
8+
import { differenceInHours } from 'date-fns';
89
import { useMemo, useContext, forwardRef, useImperativeHandle, useState, useRef } from 'react';
910
import {
1011
useXYChartTheme,
@@ -108,9 +109,18 @@ const formatDateTick = ( timestamp: number ) => {
108109
} );
109110
};
110111

112+
const formatHourTick = ( timestamp: number ) => {
113+
const date = new Date( timestamp );
114+
return date.toLocaleTimeString( undefined, {
115+
hour: 'numeric',
116+
hour12: true,
117+
} );
118+
};
119+
111120
const guessOptimalNumTicks = (
112121
data: ReturnType< typeof useChartDataTransform >,
113-
chartWidth: number
122+
chartWidth: number,
123+
tickFormatter: ( timestamp: number ) => string
114124
) => {
115125
const minX = Math.min( ...data.map( datom => datom.data.at( 0 )?.date ) );
116126
const maxX = Math.max( ...data.map( datom => datom.data.at( -1 )?.date ) );
@@ -121,7 +131,7 @@ const guessOptimalNumTicks = (
121131
let secondBestGuess = 1; // a tick number that's no greater than upperBound
122132

123133
for ( let numTicks = upperBound; numTicks > 1; --numTicks ) {
124-
const ticks = xScale.ticks( numTicks ).map( d => formatDateTick( d.getTime() ) );
134+
const ticks = xScale.ticks( numTicks ).map( d => tickFormatter( d.getTime() ) );
125135

126136
// The .ticks() function doesn't properly respect the requested number of ticks, so we need to check the length
127137
if ( ticks.length > upperBound ) {
@@ -268,12 +278,19 @@ const LineChartInternal = forwardRef< SingleChartRef, LineChartProps >(
268278
} );
269279

270280
const chartOptions = useMemo( () => {
281+
const minX = Math.min( ...dataSorted.map( datom => datom.data.at( 0 )?.date ) );
282+
const maxX = Math.max( ...dataSorted.map( datom => datom.data.at( -1 )?.date ) );
283+
const diffInHours = Math.abs( differenceInHours( maxX, minX ) );
284+
285+
// Show the difference in hours if less than 24 hours; otherwise, display the date.
286+
const formatter = diffInHours <= 24 ? formatHourTick : formatDateTick;
287+
271288
return {
272289
axis: {
273290
x: {
274291
orientation: 'bottom' as const,
275-
numTicks: guessOptimalNumTicks( dataSorted, width ),
276-
tickFormat: formatDateTick,
292+
numTicks: guessOptimalNumTicks( dataSorted, width, formatter ),
293+
tickFormat: formatter,
277294
...options?.axis?.x,
278295
},
279296
y: {

projects/js-packages/charts/src/components/line-chart/test/line-chart.test.tsx

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -367,25 +367,25 @@ describe( 'LineChart', () => {
367367
} );
368368

369369
describe( 'X-Axis Ticks', () => {
370-
test( 'renders only one tick.', () => {
370+
test( 'renders ticks in hours.', () => {
371371
renderWithTheme( {
372372
width: 800,
373373
data: [
374374
{
375375
label: 'Series A',
376376
data: [
377-
{ date: new Date( '2024-01-01' ), value: 10 },
378-
{ date: new Date( '2024-01-01' ), value: 20 },
379-
{ date: new Date( '2024-01-01' ), value: 30 },
380-
{ date: new Date( '2024-01-01' ), value: 40 },
381-
{ date: new Date( '2024-01-01' ), value: 50 },
377+
{ date: new Date( '2024-01-01:1:' ), value: 10 },
378+
{ date: new Date( '2024-01-01:3:' ), value: 20 },
379+
{ date: new Date( '2024-01-01:5:' ), value: 30 },
380+
{ date: new Date( '2024-01-01:7:' ), value: 40 },
381+
{ date: new Date( '2024-01-01:23:' ), value: 50 },
382382
],
383383
},
384384
],
385385
} );
386386

387-
const ticks = screen.getAllByText( /Jan \d+/ );
388-
expect( ticks ).toHaveLength( 1 );
387+
const ticks = screen.getAllByText( /\d+ [AM|PM]/ );
388+
expect( ticks.length ).toBeGreaterThan( 1 );
389389
} );
390390

391391
test( 'renders optimal number of ticks.', () => {

0 commit comments

Comments
 (0)