diff --git a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-small-multiples-alpha-sorting-visually-looks-correct-1-snap.png b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-small-multiples-alpha-sorting-visually-looks-correct-1-snap.png new file mode 100644 index 00000000000..24749097705 Binary files /dev/null and b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-small-multiples-alpha-sorting-visually-looks-correct-1-snap.png differ diff --git a/packages/charts/api/charts.api.md b/packages/charts/api/charts.api.md index c016f0cd98c..e8ea8fd557d 100644 --- a/packages/charts/api/charts.api.md +++ b/packages/charts/api/charts.api.md @@ -1047,8 +1047,6 @@ export type GroupByKeyFn = (data: T) => string; // @alpha (undocumented) export type GroupByProps = Pick; -// Warning: (ae-forgotten-export) The symbol "Predicate" needs to be exported by the entry point index.d.ts -// // @alpha (undocumented) export type GroupBySort = Predicate; @@ -1783,6 +1781,18 @@ export interface Postfixes { y1AccessorFormat?: string; } +// @public (undocumented) +export const Predicate: Readonly<{ + NumAsc: "numAsc"; + NumDesc: "numDesc"; + AlphaAsc: "alphaAsc"; + AlphaDesc: "alphaDesc"; + DataIndex: "dataIndex"; +}>; + +// @public (undocumented) +export type Predicate = $Values; + // @public export type PrimitiveValue = string | number | null; diff --git a/packages/charts/src/common/predicate.ts b/packages/charts/src/common/predicate.ts index 490c1cf6b6e..fe3f65be54e 100644 --- a/packages/charts/src/common/predicate.ts +++ b/packages/charts/src/common/predicate.ts @@ -41,13 +41,13 @@ export function getPredicateFn(predicate: Predicate, accessor?: keyof T): (a: const bValue = Number(accessor ? b[accessor] : b); return bValue - aValue; }; - default: - case 'dataIndex': case 'numAsc': return (a: T, b: T) => { const aValue = Number(accessor ? a[accessor] : a); const bValue = Number(accessor ? b[accessor] : b); return aValue - bValue; }; + case 'dataIndex': + return () => 0; } } diff --git a/packages/charts/src/index.ts b/packages/charts/src/index.ts index 439979ac41b..cbfe2c494bf 100644 --- a/packages/charts/src/index.ts +++ b/packages/charts/src/index.ts @@ -113,6 +113,7 @@ export { AdditiveNumber } from './utils/accessor'; export { FontStyle, FONT_STYLES } from './common/text_utils'; export { Color } from './common/colors'; export { RGB, A, RgbaTuple } from './common/color_library_wrappers'; +export { Predicate } from './common/predicate'; export { ESCalendarInterval, diff --git a/storybook/stories/small_multiples/1_grid.story.tsx b/storybook/stories/small_multiples/1_grid.story.tsx deleted file mode 100644 index b6643d9048c..00000000000 --- a/storybook/stories/small_multiples/1_grid.story.tsx +++ /dev/null @@ -1,221 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import { action } from '@storybook/addon-actions'; -import { boolean } from '@storybook/addon-knobs'; -import React, { useState } from 'react'; - -import { - ScaleType, - Position, - Chart, - Axis, - LineSeries, - GroupBy, - SmallMultiples, - Settings, - BarSeries, - AreaSeries, - Fit, - LineAnnotation, - BubbleSeries, - AnnotationDomainType, - Rotation, - RectAnnotation, -} from '@elastic/charts'; -import { getRandomNumberGenerator, SeededDataGenerator } from '@elastic/charts/src/mocks/utils'; - -import { useBaseTheme } from '../../use_base_theme'; - -const getRandomNumber = getRandomNumberGenerator(); -const dg = new SeededDataGenerator(); - -const data1 = dg.generateGroupedSeries(10, 3); -const data2 = dg.generateGroupedSeries(10, 3).map((d) => { - return getRandomNumber() > 0.95 ? { ...d, y: null } : d; -}); -const data3 = dg.generateGroupedSeries(10, 3).map((d) => { - return getRandomNumber() > 0.95 ? { ...d, y: null } : d; -}); - -export const Example = () => { - const splitVertically = boolean('vertical split', true); - const splitHorizontally = boolean('horizontal split', true); - const [rotationIndex, setRotationIndex] = useState(0); - const rot: Rotation = ([0, -90, 90, 0] as Rotation[])[rotationIndex]; - const showLegend = boolean('Show Legend', true); - return ( - <> - g - - - - - d.toFixed(2)} - /> - - { - return id; - }} - sort="alphaAsc" - /> - { - return g; - }} - sort="alphaAsc" - /> - - - - } - style={{ - line: { - stroke: 'red', - strokeWidth: 2, - opacity: 0.8, - }, - }} - zIndex={-10} - /> - - } - style={{ - line: { - stroke: 'blue', - strokeWidth: 5, - opacity: 0.8, - }, - }} - zIndex={-10} - /> - - - - - - - - ); -}; -Example.parameters = { - markdown: `If your data is in UTC timezone, your tooltip and axis labels can be configured - to visualize the time translated to your local timezone. You should be able to see the - first value on \`2019-01-01 01:00:00.000 \``, -}; diff --git a/storybook/stories/small_multiples/8_sorting.story.tsx b/storybook/stories/small_multiples/8_sorting.story.tsx new file mode 100644 index 00000000000..4f3c5263275 --- /dev/null +++ b/storybook/stories/small_multiples/8_sorting.story.tsx @@ -0,0 +1,78 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { select } from '@storybook/addon-knobs'; +import React from 'react'; + +import { + ScaleType, + Position, + Chart, + Axis, + GroupBy, + SmallMultiples, + Settings, + BarSeries, + Predicate, +} from '@elastic/charts'; + +/** + * This story is used on VRTs to test the sorting logic of the dataIndex sort predicate + */ +export const Example = () => { + const data: [string, number][] = [ + ['3', 100], + ['5', 80], + ['1', 50], + ['2', 30], + ['6', 12], + ['4', 10], + ['7', 5], + ]; + + return ( + + + + + + { + return datum[0]; + }} + sort={select( + 'Chart sorting', + { + ...Predicate, + }, + Predicate.DataIndex, + )} + /> + + + { + return `#logins day ${si.smVerticalAccessorValue}`; + }} + xScaleType={ScaleType.Ordinal} + yScaleType={ScaleType.Linear} + timeZone="local" + xAccessor={() => ''} + yAccessors={[1]} + data={data} + /> + + ); +}; +Example.parameters = { + markdown: `You can sort your small multiples by the \`GroupBy.by\` value in ascending/descending order. + If the sort is configured with the \`dataIndex\` predicate the small multiples + will keep the order of the passed data array.`, +}; diff --git a/storybook/stories/small_multiples/small_multiples.stories.tsx b/storybook/stories/small_multiples/small_multiples.stories.tsx index ae7570569f7..f890de15622 100644 --- a/storybook/stories/small_multiples/small_multiples.stories.tsx +++ b/storybook/stories/small_multiples/small_multiples.stories.tsx @@ -18,3 +18,5 @@ export { Example as gridLines } from './3_grid_lines.story'; export { Example as histogramBars } from './5_histogram_bars.story'; export { Example as heterogeneous } from './6_heterogeneous_cartesians.story'; export { Example as sunbursts } from './7_sunbursts.story'; + +export { Example as sorting } from './8_sorting.story';