From d635ca62985113e17ae60b2ff8314d1f891425b8 Mon Sep 17 00:00:00 2001 From: Marco Vettorello Date: Mon, 11 Apr 2022 16:15:42 +0200 Subject: [PATCH 1/4] Expose legend sort function --- packages/charts/api/charts.api.md | 7 +++++-- .../src/chart_types/xy_chart/legend/legend.ts | 18 +++++++++--------- .../xy_chart/state/selectors/compute_legend.ts | 6 ++---- packages/charts/src/index.ts | 1 + packages/charts/src/specs/settings.tsx | 4 ++++ 5 files changed, 21 insertions(+), 15 deletions(-) diff --git a/packages/charts/api/charts.api.md b/packages/charts/api/charts.api.md index b4f106fcd6..1464aee3fc 100644 --- a/packages/charts/api/charts.api.md +++ b/packages/charts/api/charts.api.md @@ -1407,6 +1407,7 @@ export interface LegendSpec { legendMaxDepth: number; legendPosition: Position | LegendPositionConfig; legendSize: number; + legendSort?: SeriesCompareFn; legendStrategy?: LegendStrategy; // (undocumented) onLegendItemClick?: LegendItemListener; @@ -2052,6 +2053,9 @@ export type SeriesColorAccessorFn = (seriesIdentifier: XYChartSeriesIdentifier) // @public (undocumented) export type SeriesColorsArray = string[]; +// @public +export type SeriesCompareFn = (siA: SeriesIdentifier, siB: SeriesIdentifier) => number; + // @public export type SeriesIdentifier = { specId: SpecId; @@ -2137,7 +2141,7 @@ export const Settings: (props: SFProps; +export const settingsBuildProps: BuildProps; // @public (undocumented) export type SettingsProps = ComponentProps; @@ -2269,7 +2273,6 @@ export function sortIndexAccessor(n: ArrayEntry): number; // @public export interface SortSeriesByConfig { default?: SeriesCompareFn; - // Warning: (ae-forgotten-export) The symbol "SeriesCompareFn" needs to be exported by the entry point index.d.ts legend?: SeriesCompareFn; rendering?: SeriesCompareFn; tooltip?: SeriesCompareFn; diff --git a/packages/charts/src/chart_types/xy_chart/legend/legend.ts b/packages/charts/src/chart_types/xy_chart/legend/legend.ts index ea5b038223..0392d591d6 100644 --- a/packages/charts/src/chart_types/xy_chart/legend/legend.ts +++ b/packages/charts/src/chart_types/xy_chart/legend/legend.ts @@ -10,10 +10,10 @@ import { Color } from '../../../common/colors'; import { LegendItem } from '../../../common/legend'; import { SeriesKey, SeriesIdentifier } from '../../../common/series_id'; import { ScaleType } from '../../../scales/constants'; -import { TickFormatterOptions } from '../../../specs'; -import { mergePartial, Rotation } from '../../../utils/common'; +import { SettingsSpec, TickFormatterOptions } from '../../../specs'; +import { mergePartial } from '../../../utils/common'; import { BandedAccessorType } from '../../../utils/geometry'; -import { getLegendCompareFn } from '../../../utils/series_sort'; +import { getLegendCompareFn, SeriesCompareFn } from '../../../utils/series_sort'; import { PointStyle, Theme } from '../../../utils/themes/theme'; import { getXScaleTypeFromSpec } from '../scales/get_api_scales'; import { getAxesSpecForSpecId, getSpecsById } from '../state/utils/spec'; @@ -100,11 +100,10 @@ export function computeLegend( seriesColors: Map, specs: BasicSeriesSpec[], axesSpecs: AxisSpec[], - showLegendExtra: boolean, + settingsSpec: SettingsSpec, serialIdentifierDataSeriesMap: Record, deselectedDataSeries: SeriesIdentifier[] = [], theme: Theme, - chartRotation: Rotation, ): LegendItem[] { const legendItems: LegendItem[] = []; const defaultColor = theme.colors.defaultVizColor; @@ -133,7 +132,7 @@ export function computeLegend( const labelY1 = banded ? getBandedLegendItemLabel(name, BandedAccessorType.Y1, postFixes) : name; // Use this to get axis spec w/ tick formatter - const { yAxis } = getAxesSpecForSpecId(axesSpecs, spec.groupId, chartRotation); + const { yAxis } = getAxesSpecForSpecId(axesSpecs, spec.groupId, settingsSpec.rotation); const formatter = spec.tickFormat ?? yAxis?.tickFormat ?? defaultTickFormatter; const { hideInLegend } = spec; @@ -151,7 +150,7 @@ export function computeLegend( isSeriesHidden, isItemHidden: hideInLegend, isToggleable: true, - defaultExtra: getLegendExtra(showLegendExtra, xScaleType, formatter, 'y1', lastValue), + defaultExtra: getLegendExtra(settingsSpec.showLegendExtra, xScaleType, formatter, 'y1', lastValue), path: [{ index: 0, value: seriesIdentifier.key }], keys: [specId, spec.groupId, yAccessor, ...series.splitAccessors.values()], pointStyle, @@ -166,7 +165,7 @@ export function computeLegend( isSeriesHidden, isItemHidden: hideInLegend, isToggleable: true, - defaultExtra: getLegendExtra(showLegendExtra, xScaleType, formatter, 'y0', lastValue), + defaultExtra: getLegendExtra(settingsSpec.showLegendExtra, xScaleType, formatter, 'y0', lastValue), path: [{ index: 0, value: seriesIdentifier.key }], keys: [specId, spec.groupId, yAccessor, ...series.splitAccessors.values()], pointStyle, @@ -179,9 +178,10 @@ export function computeLegend( const bDs = serialIdentifierDataSeriesMap[b.key]; return defaultXYLegendSeriesSort(aDs, bDs); }); + const sortFn: SeriesCompareFn = settingsSpec.legendSort ? settingsSpec.legendSort : legendSortFn; return groupBy( - legendItems.sort((a, b) => legendSortFn(a.seriesIdentifiers[0], b.seriesIdentifiers[0])), + legendItems.sort((a, b) => sortFn(a.seriesIdentifiers[0], b.seriesIdentifiers[0])), ({ keys, childId }) => { return [...keys, childId].join('__'); // childId is used for band charts }, diff --git a/packages/charts/src/chart_types/xy_chart/state/selectors/compute_legend.ts b/packages/charts/src/chart_types/xy_chart/state/selectors/compute_legend.ts index 5b018beb67..7cd38709d7 100644 --- a/packages/charts/src/chart_types/xy_chart/state/selectors/compute_legend.ts +++ b/packages/charts/src/chart_types/xy_chart/state/selectors/compute_legend.ts @@ -41,18 +41,16 @@ export const computeLegendSelector = createCustomCachedSelector( settings, siDataSeriesMap: Record, ): LegendItem[] => { - const lastValues = getLastValues(formattedDataSeries, xDomain); return computeLegend( formattedDataSeries, - lastValues, + getLastValues(formattedDataSeries, xDomain), seriesColors, seriesSpecs, axesSpecs, - settings.showLegendExtra, + settings, siDataSeriesMap, deselectedDataSeries, chartTheme, - settings.rotation, ); }, ); diff --git a/packages/charts/src/index.ts b/packages/charts/src/index.ts index 2e9829452e..52e4ef5a24 100644 --- a/packages/charts/src/index.ts +++ b/packages/charts/src/index.ts @@ -33,6 +33,7 @@ export { CurveType } from './utils/curves'; export { ContinuousDomain, OrdinalDomain } from './utils/domain'; export { Dimensions, SimplePadding, Padding, PerSideDistance, Margins } from './utils/dimensions'; export { timeFormatter, niceTimeFormatter, niceTimeFormatByDay } from './utils/data/formatters'; +export { SeriesCompareFn } from './utils/series_sort'; export { SeriesIdentifier, SeriesKey } from './common/series_id'; export { XYChartSeriesIdentifier, DataSeriesDatum, FilledValues } from './chart_types/xy_chart/utils/series'; export { diff --git a/packages/charts/src/specs/settings.tsx b/packages/charts/src/specs/settings.tsx index 30eea5c766..7b7c417526 100644 --- a/packages/charts/src/specs/settings.tsx +++ b/packages/charts/src/specs/settings.tsx @@ -484,6 +484,10 @@ export interface LegendSpec { */ legendAction?: LegendAction; legendColorPicker?: LegendColorPicker; + /** + * A SeriesSortFn to sort the legend values (top-bottom) + */ + legendSort?: SeriesCompareFn; } /** From 6104210294bffab94e970fed4e7c0d2d1a7db3af Mon Sep 17 00:00:00 2001 From: Marco Vettorello Date: Tue, 12 Apr 2022 09:45:05 +0200 Subject: [PATCH 2/4] Add legend sort test --- .../stories/legend/15_legend_sort.story.tsx | 69 +++++++++++++++++++ storybook/stories/legend/legend.stories.tsx | 1 + 2 files changed, 70 insertions(+) create mode 100644 storybook/stories/legend/15_legend_sort.story.tsx diff --git a/storybook/stories/legend/15_legend_sort.story.tsx b/storybook/stories/legend/15_legend_sort.story.tsx new file mode 100644 index 0000000000..10884c9314 --- /dev/null +++ b/storybook/stories/legend/15_legend_sort.story.tsx @@ -0,0 +1,69 @@ +/* + * 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 { boolean } from '@storybook/addon-knobs'; +import React from 'react'; + +import { Axis, BarSeries, Chart, Position, ScaleType, Settings } from '@elastic/charts'; + +import { XYChartSeriesIdentifier } from '../../../packages/charts/src/chart_types/xy_chart/utils/series'; +import { SeriesIdentifier } from '../../../packages/charts/src/common/series_id'; +import { useBaseTheme } from '../../use_base_theme'; + +export const Example = () => { + const data: Array<[number, string, number]> = [ + [2010, 'Apple', 10], + [2010, 'Orange', 6], + [2010, 'Banana', 4], + [2011, 'Apple', 9], + [2011, 'Orange', 6], + [2011, 'Banana', 2], + [2012, 'Apple', 7], + [2012, 'Orange', 3], + [2012, 'Banana', 3], + [2013, 'Apple', 12], + [2013, 'Orange', 10], + [2013, 'Banana', 5], + ]; + // the sorting value can be part of the dataset or externally defined + const categoricalIndex: Array = ['Apple', 'Orange', 'Banana']; + + const reverseSort = boolean('reverse', true); + const defaultSort = boolean('default sort', false); + + const legendSort = (a: SeriesIdentifier, b: SeriesIdentifier) => { + // extract the value from the accessors to identify the current selected series + // the SeriesIdentifier can be casted to the chart type specific one + const categoryA = (a as XYChartSeriesIdentifier)?.splitAccessors?.get(1) ?? ''; + const categoryB = (b as XYChartSeriesIdentifier)?.splitAccessors?.get(1) ?? ''; + // find the index of each series + const catAIndex = categoricalIndex.indexOf(categoryA); + const catBIndex = categoricalIndex.indexOf(categoryB); + // compare the indices and return the order + return reverseSort ? catAIndex - catBIndex : catBIndex - catAIndex; + }; + return ( + + + + `${d} tons`} /> + + + + ); +}; diff --git a/storybook/stories/legend/legend.stories.tsx b/storybook/stories/legend/legend.stories.tsx index 9a8a700dde..d72f80e706 100644 --- a/storybook/stories/legend/legend.stories.tsx +++ b/storybook/stories/legend/legend.stories.tsx @@ -25,3 +25,4 @@ export { Example as piechartRepeatedLabels } from './10_sunburst_repeated_label. export { Example as actions } from './11_legend_actions.story'; export { Example as margins } from './12_legend_margins.story'; export { Example as singleSeries } from './14_single_series.story'; +export { Example as sortItems } from './15_legend_sort.story'; From 7a5de277de01a1366be962037e2dd3b250a7fb11 Mon Sep 17 00:00:00 2001 From: Marco Vettorello Date: Tue, 12 Apr 2022 09:53:01 +0200 Subject: [PATCH 3/4] Add legend sort VRT --- ...sort-items-visually-looks-correct-1-snap.png | Bin 0 -> 13008 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-legend-sort-items-visually-looks-correct-1-snap.png diff --git a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-legend-sort-items-visually-looks-correct-1-snap.png b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-legend-sort-items-visually-looks-correct-1-snap.png new file mode 100644 index 0000000000000000000000000000000000000000..8856073ab327aa931659438a3a1b564a6967d607 GIT binary patch literal 13008 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 NN>N=Q_uB1;{{`t996 Date: Wed, 13 Apr 2022 10:01:03 +0200 Subject: [PATCH 4/4] Use null coalescing operator Co-authored-by: Nick Partridge --- packages/charts/src/chart_types/xy_chart/legend/legend.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/charts/src/chart_types/xy_chart/legend/legend.ts b/packages/charts/src/chart_types/xy_chart/legend/legend.ts index 0392d591d6..028af76392 100644 --- a/packages/charts/src/chart_types/xy_chart/legend/legend.ts +++ b/packages/charts/src/chart_types/xy_chart/legend/legend.ts @@ -178,7 +178,7 @@ export function computeLegend( const bDs = serialIdentifierDataSeriesMap[b.key]; return defaultXYLegendSeriesSort(aDs, bDs); }); - const sortFn: SeriesCompareFn = settingsSpec.legendSort ? settingsSpec.legendSort : legendSortFn; + const sortFn: SeriesCompareFn = settingsSpec.legendSort ?? legendSortFn; return groupBy( legendItems.sort((a, b) => sortFn(a.seriesIdentifiers[0], b.seriesIdentifiers[0])),