Skip to content

Commit fc6430b

Browse files
nickofthymemarkov00
authored andcommitted
feat: specify series name with a function on SeriesSpec (opensearch-project#539)
Refactor name prop on SeriesSpec to take custom naming props to name series. BREAKING CHANGE: Remove `customSubSeriesName` prop on series specs in favor of cleaner api using just the `name` prop on `SeriesSpec`. The types `SeriesStringPredicate`, `SubSeriesStringPredicate` have been removed.
1 parent b043374 commit fc6430b

18 files changed

+518
-232
lines changed

packages/osd-charts/.playground/playground.tsx

Lines changed: 29 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,39 @@
11
import React from 'react';
2-
import { Chart, ScaleType, Position, Axis, getAxisId, timeFormatter, getSpecId, AreaSeries, Settings } from '../src';
3-
import { KIBANA_METRICS } from '../src/utils/data_samples/test_dataset_kibana';
4-
export class Playground extends React.Component {
5-
chartRef: React.RefObject<Chart> = React.createRef();
6-
onBrushEnd = (min: number, max: number) => {
7-
// eslint-disable-next-line no-console
8-
console.log({ min, max });
9-
};
102

3+
import { Chart, LineSeries, ScaleType, Position, Axis } from '../src';
4+
import { SeededDataGenerator } from '../src/mocks/utils';
5+
6+
export class Playground extends React.Component<{}, { isSunburstShown: boolean }> {
117
render() {
8+
const dg = new SeededDataGenerator();
9+
const data = dg.generateGroupedSeries(10, 2).map((item) => ({
10+
...item,
11+
y1: item.y + 100,
12+
}));
13+
1214
return (
1315
<>
1416
<div className="chart">
15-
<Chart className={'story-chart'}>
16-
<Settings showLegend={true} />
17-
<Axis
18-
id={getAxisId('bottom')}
19-
title={'timestamp per 1 minute'}
20-
position={Position.Bottom}
21-
showOverlappingTicks={true}
22-
tickFormat={timeFormatter('HH:mm')}
17+
<Chart>
18+
<Axis id="y1" position={Position.Left} title={'y1'} />
19+
<Axis id="y2" domain={{ fit: true }} groupId="g2" position={Position.Right} title={'y2'} />
20+
<Axis id="x" position={Position.Bottom} title={'x'} />
21+
<LineSeries
22+
id="line1"
23+
xScaleType={ScaleType.Linear}
24+
xAccessor={'x'}
25+
yAccessors={['y']}
26+
splitSeriesAccessors={['g']}
27+
data={data}
2328
/>
24-
<Axis
25-
id={getAxisId('left')}
26-
title={KIBANA_METRICS.metrics.kibana_os_load[0].metric.title}
27-
position={Position.Left}
28-
tickFormat={(d) => Number(d).toFixed(2)}
29-
/>
30-
31-
<AreaSeries
32-
id={getSpecId('area')}
33-
xScaleType={ScaleType.Time}
34-
yScaleType={ScaleType.Linear}
35-
xAccessor={0}
36-
yAccessors={[1]}
37-
y0Accessors={[2]}
38-
data={KIBANA_METRICS.metrics.kibana_os_load[0].data.map((d) => {
39-
return [...d, d[1] - 10];
40-
})}
29+
<LineSeries
30+
id="line2"
31+
groupId="g2"
32+
xScaleType={ScaleType.Linear}
33+
xAccessor={'x'}
34+
yAccessors={['y1']}
35+
splitSeriesAccessors={['g']}
36+
data={data}
4137
/>
4238
</Chart>
4339
</div>
Loading

packages/osd-charts/src/chart_types/xy_chart/legend/legend.test.ts

Lines changed: 47 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { getAxisId, getGroupId, getSpecId } from '../../../utils/ids';
22
import { ScaleType } from '../../../scales';
33
import { computeLegend } from './legend';
4-
import { SeriesCollectionValue, getSeriesLabel } from '../utils/series';
4+
import { SeriesCollectionValue, getSeriesName } from '../utils/series';
55
import { AxisSpec, BasicSeriesSpec, SeriesTypes } from '../utils/specs';
66
import { Position } from '../../../utils/commons';
77
import { ChartTypes } from '../..';
@@ -118,7 +118,7 @@ describe('Legends', () => {
118118
const expected = [
119119
{
120120
color: 'red',
121-
label: 'Spec 1 title',
121+
name: 'Spec 1 title',
122122
seriesIdentifier: {
123123
seriesKeys: ['y1'],
124124
specId: 'spec1',
@@ -142,7 +142,7 @@ describe('Legends', () => {
142142
const expected = [
143143
{
144144
color: 'red',
145-
label: 'Spec 1 title',
145+
name: 'Spec 1 title',
146146
seriesIdentifier: {
147147
seriesKeys: ['y1'],
148148
specId: 'spec1',
@@ -158,7 +158,7 @@ describe('Legends', () => {
158158
},
159159
{
160160
color: 'blue',
161-
label: 'a - b',
161+
name: 'a - b',
162162
seriesIdentifier: {
163163
seriesKeys: ['a', 'b', 'y1'],
164164
specId: 'spec1',
@@ -182,7 +182,7 @@ describe('Legends', () => {
182182
const expected = [
183183
{
184184
color: 'red',
185-
label: 'Spec 1 title',
185+
name: 'Spec 1 title',
186186
seriesIdentifier: {
187187
seriesKeys: ['y1'],
188188
specId: 'spec1',
@@ -198,7 +198,7 @@ describe('Legends', () => {
198198
},
199199
{
200200
color: 'green',
201-
label: 'spec2',
201+
name: 'spec2',
202202
seriesIdentifier: {
203203
seriesKeys: ['y1'],
204204
specId: 'spec2',
@@ -227,7 +227,7 @@ describe('Legends', () => {
227227
const expected = [
228228
{
229229
color: 'violet',
230-
label: 'Spec 1 title',
230+
name: 'Spec 1 title',
231231
banded: undefined,
232232
seriesIdentifier: {
233233
seriesKeys: ['y1'],
@@ -272,7 +272,7 @@ describe('Legends', () => {
272272
const visibility = [...legend.values()].map((item) => item.isSeriesVisible);
273273
expect(visibility).toEqual([false, false, true]);
274274
});
275-
it('returns the right series label for a color series', () => {
275+
it('returns the right series name for a color series', () => {
276276
const seriesIdentifier1 = {
277277
specId: getSpecId(''),
278278
yAccessor: 'y1',
@@ -289,38 +289,38 @@ describe('Legends', () => {
289289
};
290290

291291
// null removed, seriesIdentifier has to be at least an empty array
292-
let label = getSeriesLabel(seriesIdentifier1, true, false);
293-
expect(label).toBe('');
294-
label = getSeriesLabel(seriesIdentifier1, true, false, spec1);
295-
expect(label).toBe('Spec 1 title');
296-
label = getSeriesLabel(seriesIdentifier1, true, false, spec2);
297-
expect(label).toBe('spec2');
298-
label = getSeriesLabel(seriesIdentifier2, true, false, spec1);
299-
expect(label).toBe('Spec 1 title');
300-
label = getSeriesLabel(seriesIdentifier2, true, false, spec2);
301-
expect(label).toBe('spec2');
292+
let name = getSeriesName(seriesIdentifier1, true, false);
293+
expect(name).toBe('');
294+
name = getSeriesName(seriesIdentifier1, true, false, spec1);
295+
expect(name).toBe('Spec 1 title');
296+
name = getSeriesName(seriesIdentifier1, true, false, spec2);
297+
expect(name).toBe('spec2');
298+
name = getSeriesName(seriesIdentifier2, true, false, spec1);
299+
expect(name).toBe('Spec 1 title');
300+
name = getSeriesName(seriesIdentifier2, true, false, spec2);
301+
expect(name).toBe('spec2');
302302

303-
label = getSeriesLabel(seriesIdentifier1, false, false, spec1);
304-
expect(label).toBe('Spec 1 title');
305-
label = getSeriesLabel(seriesIdentifier1, false, false, spec2);
306-
expect(label).toBe('spec2');
307-
label = getSeriesLabel(seriesIdentifier2, false, false, spec1);
308-
expect(label).toBe('a - b');
309-
label = getSeriesLabel(seriesIdentifier2, false, false, spec2);
310-
expect(label).toBe('a - b');
303+
name = getSeriesName(seriesIdentifier1, false, false, spec1);
304+
expect(name).toBe('Spec 1 title');
305+
name = getSeriesName(seriesIdentifier1, false, false, spec2);
306+
expect(name).toBe('spec2');
307+
name = getSeriesName(seriesIdentifier2, false, false, spec1);
308+
expect(name).toBe('a - b');
309+
name = getSeriesName(seriesIdentifier2, false, false, spec2);
310+
expect(name).toBe('a - b');
311311

312-
label = getSeriesLabel(seriesIdentifier1, true, false, spec1);
313-
expect(label).toBe('Spec 1 title');
314-
label = getSeriesLabel(seriesIdentifier1, true, false, spec2);
315-
expect(label).toBe('spec2');
316-
label = getSeriesLabel(seriesIdentifier1, true, false);
317-
expect(label).toBe('');
318-
label = getSeriesLabel(seriesIdentifier1, true, false, spec1);
319-
expect(label).toBe('Spec 1 title');
320-
label = getSeriesLabel(seriesIdentifier1, true, false, spec2);
321-
expect(label).toBe('spec2');
312+
name = getSeriesName(seriesIdentifier1, true, false, spec1);
313+
expect(name).toBe('Spec 1 title');
314+
name = getSeriesName(seriesIdentifier1, true, false, spec2);
315+
expect(name).toBe('spec2');
316+
name = getSeriesName(seriesIdentifier1, true, false);
317+
expect(name).toBe('');
318+
name = getSeriesName(seriesIdentifier1, true, false, spec1);
319+
expect(name).toBe('Spec 1 title');
320+
name = getSeriesName(seriesIdentifier1, true, false, spec2);
321+
expect(name).toBe('spec2');
322322
});
323-
it('use the splitted value as label if has a single series and splitSeries is used', () => {
323+
it('use the splitted value as name if has a single series and splitSeries is used', () => {
324324
const seriesIdentifier1 = {
325325
specId: getSpecId(''),
326326
yAccessor: 'y1',
@@ -347,22 +347,22 @@ describe('Legends', () => {
347347
...spec1,
348348
splitSeriesAccessors: ['g'],
349349
};
350-
let label = getSeriesLabel(seriesIdentifier1, true, false, specWithSplit);
351-
expect(label).toBe('Spec 1 title');
350+
let name = getSeriesName(seriesIdentifier1, true, false, specWithSplit);
351+
expect(name).toBe('Spec 1 title');
352352

353-
label = getSeriesLabel(seriesIdentifier3, true, false, specWithSplit);
354-
expect(label).toBe('a');
353+
name = getSeriesName(seriesIdentifier3, true, false, specWithSplit);
354+
expect(name).toBe('a');
355355

356356
// happens when we have multiple values in splitSeriesAccessor
357357
// or we have also multiple yAccessors
358-
label = getSeriesLabel(seriesIdentifier2, true, false, specWithSplit);
359-
expect(label).toBe('a - b');
358+
name = getSeriesName(seriesIdentifier2, true, false, specWithSplit);
359+
expect(name).toBe('a - b');
360360

361361
// happens when the value of a splitSeriesAccessor is null
362-
label = getSeriesLabel(seriesIdentifier1, true, false, specWithSplit);
363-
expect(label).toBe('Spec 1 title');
362+
name = getSeriesName(seriesIdentifier1, true, false, specWithSplit);
363+
expect(name).toBe('Spec 1 title');
364364

365-
label = getSeriesLabel(seriesIdentifier1, false, false, specWithSplit);
366-
expect(label).toBe('Spec 1 title');
365+
name = getSeriesName(seriesIdentifier1, false, false, specWithSplit);
366+
expect(name).toBe('Spec 1 title');
367367
});
368368
});

packages/osd-charts/src/chart_types/xy_chart/legend/legend.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import {
44
SeriesCollectionValue,
55
getSeriesIndex,
66
getSortedDataSeriesColorsValuesMap,
7-
getSeriesLabel,
7+
getSeriesName,
88
XYChartSeriesIdentifier,
99
} from '../utils/series';
1010
import { AxisSpec, BasicSeriesSpec, Postfixes, isAreaSeriesSpec, isBarSeriesSpec } from '../utils/specs';
@@ -19,7 +19,7 @@ interface FormattedLastValues {
1919
export type LegendItem = Postfixes & {
2020
key: string;
2121
color: string;
22-
label: string;
22+
name: string;
2323
seriesIdentifier: XYChartSeriesIdentifier;
2424
isSeriesVisible?: boolean;
2525
banded?: boolean;
@@ -43,14 +43,14 @@ function getPostfix(spec: BasicSeriesSpec): Postfixes {
4343
}
4444

4545
export function getItemLabel(
46-
{ banded, label, y1AccessorFormat, y0AccessorFormat }: LegendItem,
46+
{ banded, name, y1AccessorFormat, y0AccessorFormat }: LegendItem,
4747
yAccessor: BandedAccessorType,
4848
) {
4949
if (!banded) {
50-
return label;
50+
return name;
5151
}
5252

53-
return yAccessor === BandedAccessorType.Y1 ? `${label}${y1AccessorFormat}` : `${label}${y0AccessorFormat}`;
53+
return yAccessor === BandedAccessorType.Y1 ? `${name}${y1AccessorFormat}` : `${name}${y0AccessorFormat}`;
5454
}
5555

5656
export function computeLegend(
@@ -69,10 +69,10 @@ export function computeLegend(
6969
const spec = getSpecsById<BasicSeriesSpec>(specs, seriesIdentifier.specId);
7070
const color = seriesColors.get(key) || defaultColor;
7171
const hasSingleSeries = seriesCollection.size === 1;
72-
const label = getSeriesLabel(seriesIdentifier, hasSingleSeries, false, spec);
72+
const name = getSeriesName(seriesIdentifier, hasSingleSeries, false, spec);
7373
const isSeriesVisible = deselectedDataSeries ? getSeriesIndex(deselectedDataSeries, seriesIdentifier) < 0 : true;
7474

75-
if (label === '' || !spec) {
75+
if (name === '' || !spec) {
7676
return;
7777
}
7878

@@ -84,7 +84,7 @@ export function computeLegend(
8484
const legendItem: LegendItem = {
8585
key,
8686
color,
87-
label,
87+
name,
8888
banded,
8989
seriesIdentifier,
9090
isSeriesVisible,

packages/osd-charts/src/chart_types/xy_chart/rendering/rendering.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ describe('Rendering utils', () => {
105105
const highlightedLegendItem: LegendItem = {
106106
key: 'somekey',
107107
color: '',
108-
label: '',
108+
name: '',
109109
seriesIdentifier,
110110
isSeriesVisible: true,
111111
isLegendItemVisible: true,

packages/osd-charts/src/chart_types/xy_chart/state/chart_state.specs.test.ts

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ describe('XYChart - specs ordering', () => {
2525
store.dispatch(specParsed());
2626

2727
const legendItems = getLegendItemsSelector(store.getState());
28-
const labels = [...legendItems.values()].map((item) => item.label);
29-
expect(labels).toEqual(['A', 'B', 'C']);
28+
const names = [...legendItems.values()].map((item) => item.name);
29+
expect(names).toEqual(['A', 'B', 'C']);
3030
});
3131
it('the legend respect the insert order [B, A, C]', () => {
3232
store.dispatch(specParsing());
@@ -35,8 +35,8 @@ describe('XYChart - specs ordering', () => {
3535
store.dispatch(upsertSpec(MockSeriesSpec.bar({ id: 'C', data })));
3636
store.dispatch(specParsed());
3737
const legendItems = getLegendItemsSelector(store.getState());
38-
const labels = [...legendItems.values()].map((item) => item.label);
39-
expect(labels).toEqual(['B', 'A', 'C']);
38+
const names = [...legendItems.values()].map((item) => item.name);
39+
expect(names).toEqual(['B', 'A', 'C']);
4040
});
4141
it('the legend respect the order when changing properties of existing specs', () => {
4242
store.dispatch(specParsing());
@@ -46,8 +46,8 @@ describe('XYChart - specs ordering', () => {
4646
store.dispatch(specParsed());
4747

4848
let legendItems = getLegendItemsSelector(store.getState());
49-
let labels = [...legendItems.values()].map((item) => item.label);
50-
expect(labels).toEqual(['A', 'B', 'C']);
49+
let names = [...legendItems.values()].map((item) => item.name);
50+
expect(names).toEqual(['A', 'B', 'C']);
5151

5252
store.dispatch(specParsing());
5353
store.dispatch(upsertSpec(MockSeriesSpec.bar({ id: 'A', data })));
@@ -56,8 +56,8 @@ describe('XYChart - specs ordering', () => {
5656
store.dispatch(specParsed());
5757

5858
legendItems = getLegendItemsSelector(store.getState());
59-
labels = [...legendItems.values()].map((item) => item.label);
60-
expect(labels).toEqual(['A', 'B updated', 'C']);
59+
names = [...legendItems.values()].map((item) => item.name);
60+
expect(names).toEqual(['A', 'B updated', 'C']);
6161
});
6262
it('the legend respect the order when changing the order of the specs', () => {
6363
store.dispatch(specParsing());
@@ -67,8 +67,8 @@ describe('XYChart - specs ordering', () => {
6767
store.dispatch(specParsed());
6868

6969
let legendItems = getLegendItemsSelector(store.getState());
70-
let labels = [...legendItems.values()].map((item) => item.label);
71-
expect(labels).toEqual(['A', 'B', 'C']);
70+
let names = [...legendItems.values()].map((item) => item.name);
71+
expect(names).toEqual(['A', 'B', 'C']);
7272

7373
store.dispatch(specParsing());
7474
store.dispatch(upsertSpec(MockSeriesSpec.bar({ id: 'B', data })));
@@ -77,7 +77,7 @@ describe('XYChart - specs ordering', () => {
7777
store.dispatch(specParsed());
7878

7979
legendItems = getLegendItemsSelector(store.getState());
80-
labels = [...legendItems.values()].map((item) => item.label);
81-
expect(labels).toEqual(['B', 'A', 'C']);
80+
names = [...legendItems.values()].map((item) => item.name);
81+
expect(names).toEqual(['B', 'A', 'C']);
8282
});
8383
});

0 commit comments

Comments
 (0)