diff --git a/integration/tests/__image_snapshots__/axis-stories-test-ts-axis-stories-can-render-multilayer-time-axis-on-top-1-snap.png b/integration/tests/__image_snapshots__/axis-stories-test-ts-axis-stories-can-render-multilayer-time-axis-on-top-1-snap.png index 22320eff47..a9e6a644c2 100644 Binary files a/integration/tests/__image_snapshots__/axis-stories-test-ts-axis-stories-can-render-multilayer-time-axis-on-top-1-snap.png and b/integration/tests/__image_snapshots__/axis-stories-test-ts-axis-stories-can-render-multilayer-time-axis-on-top-1-snap.png differ diff --git a/integration/tests/__image_snapshots__/axis-stories-test-ts-axis-stories-uses-proper-english-ending-at-a-daily-resolution-10th-25th-1-snap.png b/integration/tests/__image_snapshots__/axis-stories-test-ts-axis-stories-uses-proper-english-ending-at-a-daily-resolution-10th-25th-1-snap.png new file mode 100644 index 0000000000..700a1043cd Binary files /dev/null and b/integration/tests/__image_snapshots__/axis-stories-test-ts-axis-stories-uses-proper-english-ending-at-a-daily-resolution-10th-25th-1-snap.png differ diff --git a/integration/tests/__image_snapshots__/axis-stories-test-ts-axis-stories-uses-proper-english-ending-at-a-daily-resolution-30th-14th-1-snap.png b/integration/tests/__image_snapshots__/axis-stories-test-ts-axis-stories-uses-proper-english-ending-at-a-daily-resolution-30th-14th-1-snap.png new file mode 100644 index 0000000000..2742c93489 Binary files /dev/null and b/integration/tests/__image_snapshots__/axis-stories-test-ts-axis-stories-uses-proper-english-ending-at-a-daily-resolution-30th-14th-1-snap.png differ diff --git a/integration/tests/__image_snapshots__/axis-stories-test-ts-axis-stories-uses-proper-english-ending-at-a-weekly-resolution-1-snap.png b/integration/tests/__image_snapshots__/axis-stories-test-ts-axis-stories-uses-proper-english-ending-at-a-weekly-resolution-1-snap.png new file mode 100644 index 0000000000..079d56c10c Binary files /dev/null and b/integration/tests/__image_snapshots__/axis-stories-test-ts-axis-stories-uses-proper-english-ending-at-a-weekly-resolution-1-snap.png differ diff --git a/integration/tests/axis_stories.test.ts b/integration/tests/axis_stories.test.ts index a75dd9f279..b134a9504d 100644 --- a/integration/tests/axis_stories.test.ts +++ b/integration/tests/axis_stories.test.ts @@ -33,16 +33,6 @@ describe('Axis stories', () => { 'http://localhost:9001/?path=/story/area-chart--timeslip&globals=theme:light&knob-Minor%20grid%20lines=true&knob-Shift%20time=8.5&knob-Shorter%20X%20axis%20minor%20whiskers=true&knob-Stretch%20time=4.8&knob-Time%20zoom=120&knob-X%20axis%20minor%20whiskers=true&knob-showOverlappingLabels%20time%20axis=true&knob-showOverlappingTicks%20time%20axis=true', ); }); - it('should extend the domain on the right with one bin width with custom bin width', async () => { - await common.expectChartAtUrlToMatchScreenshot( - 'http://localhost:9001/?path=/story/bar-chart--test-discover&globals=theme:light&knob-Minor%20grid%20lines=true&knob-Pan%20time=0&knob-Shift%20time=0&knob-Shorter%20X%20axis%20minor%20whiskers=true&knob-Stretch%20time=3.8&knob-Time%20zoom=120&knob-X%20axis%20minor%20whiskers=true&knob-layerCount=3&knob-showOverlappingLabels%20time%20axis=true&knob-showOverlappingTicks%20time%20axis=true&knob-use%20custom%20minInterval%20of%2030s=true&knob-use%20multilayer%20time%20axis=true', - ); - }); - it('should extend the domain on the right with one bin width without custom bin width', async () => { - await common.expectChartAtUrlToMatchScreenshot( - 'http://localhost:9001/?path=/story/bar-chart--test-discover&globals=theme:light&knob-Minor%20grid%20lines=true&knob-Pan%20time=0&knob-Shift%20time=0&knob-Shorter%20X%20axis%20minor%20whiskers=true&knob-Stretch%20time=3.8&knob-Time%20zoom=120&knob-X%20axis%20minor%20whiskers=true&knob-layerCount=3&knob-showOverlappingLabels%20time%20axis=true&knob-showOverlappingTicks%20time%20axis=true&knob-use%20custom%20minInterval%20of%2030s=false&knob-use%20multilayer%20time%20axis=true', - ); - }); it('should not show a raster that is finer than the bin width (minInterval)', async () => { await common.expectChartAtUrlToMatchScreenshot( 'http://localhost:9001/?path=/story/area-chart--timeslip&Bin%20width%20in%20ms%20(0:%20none%20specifed)=60000&Minor%20grid%20lines=on&Shift%20time=0&Stretch%20time=-0.4&Time%20zoom=2&globals=theme:light&knob-Bin%20width%20in%20ms%20(0:%20none%20specifed)=60000&knob-Minor%20grid%20lines=true&knob-Shift%20time=0&knob-Stretch%20time=-0.4&knob-Time%20zoom=2&knob-layerCount=3&layerCount=3', @@ -58,6 +48,31 @@ describe('Axis stories', () => { 'http://localhost:9001/?path=/story/area-chart--timeslip&globals=theme:light&knob-Bin width in ms (0: none specifed)=0&knob-Minor grid lines=true&knob-Shift time=8.5&knob-Shorter X axis minor whiskers=true&knob-Stretch time=6.8&knob-Time zoom=120&knob-X axis minor whiskers=true&knob-fallback placement=left-start&knob-layerCount=3&knob-placement=left&knob-placement offset=5&knob-showOverlappingLabels time axis=true&knob-showOverlappingTicks time axis=true&knob-stickTo=MousePosition&knob-Horizontal axis title=&knob-Top X axis=true', ); }); + it('uses proper english ending at a daily resolution, 30th....14th', async () => { + await common.expectChartAtUrlToMatchScreenshot( + 'http://localhost:9001/?path=/story/area-chart--timeslip&globals=theme:light&knob-Bin width in ms (0: none specifed)=0&knob-Minor grid lines=true&knob-Shift time=-7.1&knob-Stretch time=6.6&knob-Time zoom=120&knob-layerCount=3&knob-Horizontal axis title=&knob-Top X axis=&knob-showOverlappingTicks time axis=&knob-showOverlappingLabels time axis=', + ); + }); + it('uses proper english ending at a daily resolution, 10th...25th', async () => { + await common.expectChartAtUrlToMatchScreenshot( + 'http://localhost:9001/?path=/story/area-chart--timeslip&globals=theme:light&knob-Bin width in ms (0: none specifed)=0&knob-Minor grid lines=true&knob-Shift time=-9.8&knob-Stretch time=6.6&knob-Time zoom=120&knob-layerCount=3&knob-Horizontal axis title=&knob-Top X axis=&knob-showOverlappingTicks time axis=&knob-showOverlappingLabels time axis=', + ); + }); + it('uses proper english ending at a weekly resolution', async () => { + await common.expectChartAtUrlToMatchScreenshot( + 'http://localhost:9001/?path=/story/area-chart--timeslip&globals=theme:light&knob-Bin width in ms (0: none specifed)=0&knob-Minor grid lines=true&knob-Shift time=-8.3&knob-Stretch time=10&knob-Time zoom=120&knob-layerCount=3&knob-Horizontal axis title=&knob-Top X axis=&knob-showOverlappingTicks time axis=&knob-showOverlappingLabels time axis=', + ); + }); + it('should extend the domain on the right with one bin width with custom bin width', async () => { + await common.expectChartAtUrlToMatchScreenshot( + 'http://localhost:9001/?path=/story/bar-chart--test-discover&globals=theme:light&knob-Minor%20grid%20lines=true&knob-Pan%20time=0&knob-Shift%20time=0&knob-Shorter%20X%20axis%20minor%20whiskers=true&knob-Stretch%20time=3.8&knob-Time%20zoom=120&knob-X%20axis%20minor%20whiskers=true&knob-layerCount=3&knob-showOverlappingLabels%20time%20axis=true&knob-showOverlappingTicks%20time%20axis=true&knob-use%20custom%20minInterval%20of%2030s=true&knob-use%20multilayer%20time%20axis=true', + ); + }); + it('should extend the domain on the right with one bin width without custom bin width', async () => { + await common.expectChartAtUrlToMatchScreenshot( + 'http://localhost:9001/?path=/story/bar-chart--test-discover&globals=theme:light&knob-Minor%20grid%20lines=true&knob-Pan%20time=0&knob-Shift%20time=0&knob-Shorter%20X%20axis%20minor%20whiskers=true&knob-Stretch%20time=3.8&knob-Time%20zoom=120&knob-X%20axis%20minor%20whiskers=true&knob-layerCount=3&knob-showOverlappingLabels%20time%20axis=true&knob-showOverlappingTicks%20time%20axis=true&knob-use%20custom%20minInterval%20of%2030s=false&knob-use%20multilayer%20time%20axis=true', + ); + }); it('renders multilayer time axis with a single point and an arbitrary non-degenerate domain', async () => { await common.expectChartAtUrlToMatchScreenshot( 'http://localhost:9001/?path=/story/bar-chart--test-single-histogram-bar-chart&globals=theme:light&knob-non-round time domain start=true&knob-use multilayer time axis=true&knob-use lines instead of bars=true', diff --git a/packages/charts/src/chart_types/xy_chart/axes/timeslip/rasters.ts b/packages/charts/src/chart_types/xy_chart/axes/timeslip/rasters.ts index 84b9d59bbc..300f58376b 100644 --- a/packages/charts/src/chart_types/xy_chart/axes/timeslip/rasters.ts +++ b/packages/charts/src/chart_types/xy_chart/axes/timeslip/rasters.ts @@ -86,15 +86,32 @@ const hourFormat: Partial[1]> hour12: false, }; +const englishOrdinalEndings = { + zero: 'th', + one: 'st', + two: 'nd', + few: 'rd', + many: 'th', + other: 'th', +}; +const englishPluralRules = new Intl.PluralRules('en-US', { type: 'ordinal' }); +const englishOrdinalEnding = (signedNumber: number) => englishOrdinalEndings[englishPluralRules.select(signedNumber)]; + /** @internal */ export const rasters = ({ minimumTickPixelDistance, locale }: RasterConfig, timeZone: string) => { - const minorDayFormat = new Intl.DateTimeFormat(locale, { day: 'numeric', timeZone }).format; + const minorDayBaseFormat = new Intl.DateTimeFormat(locale, { day: 'numeric', timeZone }).format; + const minorDayFormat = (d: number) => { + const numberString = minorDayBaseFormat(d); + const number = Number.parseInt(numberString, 10); + return locale.substr(0, 2) === 'en' ? `${numberString}${englishOrdinalEnding(number)}` : numberString; + }; const detailedDayFormat = new Intl.DateTimeFormat(locale, { year: 'numeric', month: 'short', day: 'numeric', timeZone, }).format; + const detailedHourFormatBase = new Intl.DateTimeFormat(locale, { year: 'numeric', month: 'short', @@ -231,21 +248,7 @@ export const rasters = ({ minimumTickPixelDistance, locale }: RasterConfig, time } }, detailedLabelFormat: detailedDayFormat, - minorTickLabelFormat: (d) => { - const numberString = minorDayFormat(d); - const number = Number.parseInt(numberString, 10); - return locale.substr(0, 2) === 'en' - ? `${numberString}${ - number === 1 || number === 21 || number === 31 - ? 'st' - : number === 2 || number === 22 - ? 'nd' - : number === 3 || number === 23 - ? 'rd' - : 'th' - }` - : numberString; - }, + minorTickLabelFormat: minorDayFormat, minimumPixelsPerSecond: NaN, approxWidthInMs: NaN, }; @@ -268,7 +271,7 @@ export const rasters = ({ minimumTickPixelDistance, locale }: RasterConfig, time } } }, - minorTickLabelFormat: (d) => `${minorDayFormat(d)}th`, + minorTickLabelFormat: minorDayFormat, detailedLabelFormat: detailedDayFormat, minimumPixelsPerSecond: NaN, approxWidthInMs: NaN, diff --git a/storybook/parameters.ts b/storybook/parameters.ts index d0f904f7d5..b3dd409759 100644 --- a/storybook/parameters.ts +++ b/storybook/parameters.ts @@ -84,7 +84,7 @@ export const storybookParameters: Parameters = { // See integration/jest_puppeteer.config.js#L19-L22 name: 'VRT Viewport', styles: { - width: '800px', + width: '785px', height: '600px', }, },