diff --git a/packages/osd-charts/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-line-chart-multi-series-with-log-values-visually-looks-correct-1-snap.png b/packages/osd-charts/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-line-chart-multi-series-with-log-values-visually-looks-correct-1-snap.png index 996ee961f549..17e6d545ef12 100644 Binary files a/packages/osd-charts/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-line-chart-multi-series-with-log-values-visually-looks-correct-1-snap.png and b/packages/osd-charts/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-line-chart-multi-series-with-log-values-visually-looks-correct-1-snap.png differ diff --git a/packages/osd-charts/integration/tests/__image_snapshots__/axis-stories-test-ts-axis-stories-should-hide-consecutive-duplicate-ticks-1-snap.png b/packages/osd-charts/integration/tests/__image_snapshots__/axis-stories-test-ts-axis-stories-should-hide-consecutive-duplicate-ticks-1-snap.png new file mode 100644 index 000000000000..1590f04bbbc2 Binary files /dev/null and b/packages/osd-charts/integration/tests/__image_snapshots__/axis-stories-test-ts-axis-stories-should-hide-consecutive-duplicate-ticks-1-snap.png differ diff --git a/packages/osd-charts/integration/tests/axis_stories.test.ts b/packages/osd-charts/integration/tests/axis_stories.test.ts index 23ebce1a85db..d30dbdf83cf3 100644 --- a/packages/osd-charts/integration/tests/axis_stories.test.ts +++ b/packages/osd-charts/integration/tests/axis_stories.test.ts @@ -65,4 +65,9 @@ describe('Axis stories', () => { 'http://localhost:9001/?path=/story/axes--custom-mixed&knob-left min=2&knob-xDomain max=2', ); }); + it('should hide consecutive duplicate ticks', async() => { + await common.expectChartAtUrlToMatchScreenshot( + 'http://localhost:9001/?path=/story/axes--duplicate-ticks&knob-formatter=hourly&knob-Show duplicate ticks in x axis=true', + ); + }); }); diff --git a/packages/osd-charts/src/chart_types/xy_chart/utils/axis_utils.test.ts b/packages/osd-charts/src/chart_types/xy_chart/utils/axis_utils.test.ts index 07d0716c5af9..00f47012a74e 100644 --- a/packages/osd-charts/src/chart_types/xy_chart/utils/axis_utils.test.ts +++ b/packages/osd-charts/src/chart_types/xy_chart/utils/axis_utils.test.ts @@ -55,7 +55,7 @@ import { enableDuplicatedTicks, } from './axis_utils'; import { computeXScale } from './scales'; -import { AxisSpec, DomainRange, AxisStyle, DEFAULT_GLOBAL_ID } from './specs'; +import { AxisSpec, DomainRange, AxisStyle, DEFAULT_GLOBAL_ID, TickFormatter } from './specs'; describe('Axis computational utils', () => { const mockedRect = { @@ -1435,6 +1435,49 @@ describe('Axis computational utils', () => { { value: 1547596800000, label: '2019-01-16', position: 568.2958333333333 }, ]); }); + test('should show unique consecutive ticks if duplicateTicks is set to false', () => { + const formatter: TickFormatter = (d, options = { timeZone: 'utc+1' }) => DateTime.fromMillis(d, { setZone: true, zone: options.timeZone }).toFormat('HH:mm'); + const axisSpec: AxisSpec = { + id: 'bottom', + position: 'bottom', + showDuplicatedTicks: false, + chartType: 'xy_axis', + specType: 'axis', + groupId: DEFAULT_GLOBAL_ID, + hide: false, + showOverlappingLabels: false, + showOverlappingTicks: false, + tickSize: 10, + tickPadding: 10, + tickLabelRotation: 0, + tickFormat: formatter, + }; + const xDomainTime: XDomain = { + type: 'xDomain', + isBandScale: false, + timeZone: 'utc+1', + domain: [1547190000000, 1547622000000], + minInterval: 86400000, + scaleType: ScaleType.Time, + }; + const scale: Scale = computeXScale({ xDomain: xDomainTime, totalBarsInCluster: 0, range: [0, 603.5] }); + const offset = 0; + const tickFormatOption = { timeZone: xDomainTime.timeZone }; + const ticks = enableDuplicatedTicks(axisSpec, scale, offset, tickFormatOption); + const tickLabels = ticks.map(({ label }) => ({ label })); + expect(tickLabels).toEqual([ + { label: '12:00' }, + { label: '00:00' }, + { label: '12:00' }, + { label: '00:00' }, + { label: '12:00' }, + { label: '00:00' }, + { label: '12:00' }, + { label: '00:00' }, + { label: '12:00' }, + { label: '00:00' }, + ]); + }); test('should show duplicate tick labels if duplicateTicks is set to true', () => { const now = DateTime.fromISO('2019-01-11T00:00:00.000') .setZone('utc+1') diff --git a/packages/osd-charts/src/chart_types/xy_chart/utils/axis_utils.ts b/packages/osd-charts/src/chart_types/xy_chart/utils/axis_utils.ts index dac8845330ed..5c8abfdceb80 100644 --- a/packages/osd-charts/src/chart_types/xy_chart/utils/axis_utils.ts +++ b/packages/osd-charts/src/chart_types/xy_chart/utils/axis_utils.ts @@ -471,7 +471,7 @@ export function enableDuplicatedTicks( if (axisSpec.showDuplicatedTicks === true) { return allTicks; } - return getUniqueValues(allTicks, 'label'); + return getUniqueValues(allTicks, 'label', true); } /** @internal */ diff --git a/packages/osd-charts/src/utils/commons.ts b/packages/osd-charts/src/utils/commons.ts index c21dd22fbd90..273b24e083bc 100644 --- a/packages/osd-charts/src/utils/commons.ts +++ b/packages/osd-charts/src/utils/commons.ts @@ -331,7 +331,7 @@ export function mergePartial( } /** @internal */ -export function getUniqueValues(fullArray: T[], uniqueProperty: keyof T): T[] { +export function getUniqueValues(fullArray: T[], uniqueProperty: keyof T, filterConsecutives = false): T[] { return fullArray.reduce<{ filtered: T[]; uniqueValues: Set; @@ -341,7 +341,12 @@ export function getUniqueValues(fullArray: T[], uniqueProperty: keyof T): T[] if (acc.uniqueValues.has(uniqueValue)) { return acc; } - acc.uniqueValues.add(uniqueValue); + if (filterConsecutives) { + acc.uniqueValues.clear(); + acc.uniqueValues.add(uniqueValue); + } else { + acc.uniqueValues.add(uniqueValue); + } acc.filtered.push(currentValue); return acc; }, diff --git a/packages/osd-charts/stories/axes/12_duplicate_ticks.tsx b/packages/osd-charts/stories/axes/12_duplicate_ticks.tsx index 903db1c9d1b2..0048f8175589 100644 --- a/packages/osd-charts/stories/axes/12_duplicate_ticks.tsx +++ b/packages/osd-charts/stories/axes/12_duplicate_ticks.tsx @@ -17,12 +17,12 @@ * under the License. */ -import { boolean } from '@storybook/addon-knobs'; +import { boolean, select } from '@storybook/addon-knobs'; import { DateTime } from 'luxon'; import moment from 'moment-timezone'; import React from 'react'; -import { Axis, Chart, LineSeries, Position, ScaleType, niceTimeFormatter } from '../../src'; +import { Axis, Chart, LineSeries, Position, ScaleType, niceTimeFormatter, TickFormatter } from '../../src'; import { KIBANA_METRICS } from '../../src/utils/data_samples/test_dataset_kibana'; export const Example = () => { @@ -31,11 +31,16 @@ export const Example = () => { .toMillis(); const oneDay = moment.duration(1, 'd'); const twoDays = moment.duration(2, 'd'); - const oneMonth = moment.duration(31, 'd'); const threeDays = moment.duration(3, 'd'); const fourDays = moment.duration(4, 'd'); const fiveDays = moment.duration(5, 'd'); - const formatter = niceTimeFormatter([now, oneMonth.add(now).asMilliseconds()]); + const formatters: Record = { + daily: niceTimeFormatter([now, moment.duration(31, 'd').add(now).asMilliseconds()]), + hourly: (d) => moment(d).format('HH:mm'), + }; + const formatterSelect = select('formatter', ['daily', 'hourly'], 'daily'); + const formatter = formatters[formatterSelect]; + const duplicateTicksInAxis = boolean('Show duplicate ticks in x axis', false); return (