Skip to content

Commit 6761c2b

Browse files
feat(legend): hide legend item if hideLegendItem on series spec is true (#147)
1 parent 9bae64b commit 6761c2b

File tree

14 files changed

+107
-25
lines changed

14 files changed

+107
-25
lines changed

src/components/_legend.scss

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,10 @@ $elasticChartsLegendMaxHeight: $euiSize * 4;
9797
text-decoration: underline;
9898
}
9999
}
100+
101+
&.elasticChartsLegendList__item--hidden {
102+
display: none;
103+
}
100104
}
101105

102106
.elasticChartsLegendListItem__title {

src/components/legend.tsx

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -68,18 +68,20 @@ class LegendComponent extends React.Component<ReactiveChartProps> {
6868
responsive={false}
6969
>
7070
{[...legendItems.values()].map((item) => {
71+
const { color, label, isSeriesVisible, isLegendItemVisible } = item;
72+
7173
const legendItemProps = {
7274
key: item.key,
73-
className: 'elasticChartsLegendList__item',
75+
className: classNames('elasticChartsLegendList__item', {
76+
'elasticChartsLegendList__item--hidden': !isLegendItemVisible,
77+
}),
7478
onMouseEnter: this.onLegendItemMouseover(item.key),
7579
onMouseLeave: this.onLegendItemMouseout,
7680
};
7781

78-
const { color, label, isVisible } = item;
79-
8082
return (
8183
<EuiFlexItem {...legendItemProps}>
82-
{this.renderLegendElement({ color, label, isVisible }, item.key)}
84+
{this.renderLegendElement({ color, label, isSeriesVisible }, item.key)}
8385
</EuiFlexItem>
8486
);
8587
})}
@@ -98,10 +100,10 @@ class LegendComponent extends React.Component<ReactiveChartProps> {
98100
}
99101

100102
private renderLegendElement = (
101-
{ color, label, isVisible }: Partial<LegendItem>,
103+
{ color, label, isSeriesVisible }: Partial<LegendItem>,
102104
legendItemKey: string,
103105
) => {
104-
const props = { color, label, isVisible, legendItemKey };
106+
const props = { color, label, isSeriesVisible, legendItemKey };
105107

106108
return <LegendElement {...props} />;
107109
}

src/components/legend_element.tsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ interface LegendElementProps {
2121
legendItemKey: string;
2222
color: string | undefined;
2323
label: string | undefined;
24-
isVisible?: boolean;
24+
isSeriesVisible?: boolean;
2525
}
2626

2727
interface LegendElementState {
@@ -52,7 +52,7 @@ class LegendElementComponent extends React.Component<LegendElementProps, LegendE
5252

5353
render() {
5454
const { legendItemKey } = this.props;
55-
const { color, label, isVisible } = this.props;
55+
const { color, label, isSeriesVisible } = this.props;
5656

5757
const onTitleClick = this.onLegendTitleClick(legendItemKey);
5858

@@ -88,7 +88,7 @@ class LegendElementComponent extends React.Component<LegendElementProps, LegendE
8888
</EuiPopover>
8989
</EuiFlexItem>
9090
<EuiFlexItem grow={false}>
91-
{this.renderVisibilityButton(legendItemKey, isVisible)}
91+
{this.renderVisibilityButton(legendItemKey, isSeriesVisible)}
9292
</EuiFlexItem>
9393
<EuiFlexItem grow={false} className={titleClassNames} onClick={onTitleClick}>
9494
<EuiPopover
@@ -156,8 +156,8 @@ class LegendElementComponent extends React.Component<LegendElementProps, LegendE
156156
}
157157
}
158158

159-
private renderVisibilityButton = (legendItemKey: string, isVisible: boolean = true) => {
160-
const iconType = isVisible ? 'eye' : 'eyeClosed';
159+
private renderVisibilityButton = (legendItemKey: string, isSeriesVisible: boolean = true) => {
160+
const iconType = isSeriesVisible ? 'eye' : 'eyeClosed';
161161
return (
162162
<EuiButtonIcon
163163
onClick={this.onVisibilityClick(legendItemKey)}

src/lib/series/legend.test.ts

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ const spec1: BasicSeriesSpec = {
3131
yAccessors: ['y'],
3232
yScaleToDataExtent: false,
3333
data: [],
34+
hideInLegend: false,
3435
};
3536
const spec2: BasicSeriesSpec = {
3637
id: getSpecId('spec2'),
@@ -42,6 +43,7 @@ const spec2: BasicSeriesSpec = {
4243
yAccessors: ['y'],
4344
yScaleToDataExtent: false,
4445
data: [],
46+
hideInLegend: false,
4547
};
4648

4749
describe('Legends', () => {
@@ -65,7 +67,8 @@ describe('Legends', () => {
6567
color: 'red',
6668
label: 'Spec 1 title',
6769
value: { colorValues: [], specId: 'spec1' },
68-
isVisible: true,
70+
isSeriesVisible: true,
71+
isLegendItemVisible: true,
6972
key: 'colorSeries1a',
7073
},
7174
];
@@ -80,14 +83,16 @@ describe('Legends', () => {
8083
color: 'red',
8184
label: 'Spec 1 title',
8285
value: { colorValues: [], specId: 'spec1' },
83-
isVisible: true,
86+
isSeriesVisible: true,
87+
isLegendItemVisible: true,
8488
key: 'colorSeries1a',
8589
},
8690
{
8791
color: 'blue',
8892
label: 'a - b',
8993
value: { colorValues: ['a', 'b'], specId: 'spec1' },
90-
isVisible: true,
94+
isSeriesVisible: true,
95+
isLegendItemVisible: true,
9196
key: 'colorSeries1b',
9297
},
9398
];
@@ -102,14 +107,16 @@ describe('Legends', () => {
102107
color: 'red',
103108
label: 'Spec 1 title',
104109
value: { colorValues: [], specId: 'spec1' },
105-
isVisible: true,
110+
isSeriesVisible: true,
111+
isLegendItemVisible: true,
106112
key: 'colorSeries1a',
107113
},
108114
{
109115
color: 'green',
110116
label: 'spec2',
111117
value: { colorValues: [], specId: 'spec2' },
112-
isVisible: true,
118+
isSeriesVisible: true,
119+
isLegendItemVisible: true,
113120
key: 'colorSeries2a',
114121
},
115122
];
@@ -129,7 +136,8 @@ describe('Legends', () => {
129136
color: 'violet',
130137
label: 'Spec 1 title',
131138
value: { colorValues: [], specId: 'spec1' },
132-
isVisible: true,
139+
isSeriesVisible: true,
140+
isLegendItemVisible: true,
133141
key: 'colorSeries1a',
134142
},
135143
];
@@ -146,9 +154,9 @@ describe('Legends', () => {
146154

147155
const legend = computeLegend(seriesColor, emptyColorMap, specs, 'violet', deselectedDataSeries);
148156

149-
const visibility = [...legend.values()].map((item) => item.isVisible);
157+
const visibility = [...legend.values()].map((item) => item.isSeriesVisible);
150158

151-
expect(visibility).toEqual([true, true, true, true]);
159+
expect(visibility).toEqual([true, true, true]);
152160
});
153161
it('selectively sets series to visible when there are deselectedDataSeries items', () => {
154162
seriesColor.set('colorSeries1a', colorValues1a);
@@ -161,8 +169,8 @@ describe('Legends', () => {
161169

162170
const legend = computeLegend(seriesColor, emptyColorMap, specs, 'violet', deselectedDataSeries);
163171

164-
const visibility = [...legend.values()].map((item) => item.isVisible);
165-
expect(visibility).toEqual([false, false, true, true]);
172+
const visibility = [...legend.values()].map((item) => item.isSeriesVisible);
173+
expect(visibility).toEqual([false, false, true]);
166174
});
167175
it('returns the right series label for a color series', () => {
168176
let label = getSeriesColorLabel([], true);

src/lib/series/legend.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ export interface LegendItem {
88
color: string;
99
label: string;
1010
value: DataSeriesColorsValues;
11-
isVisible?: boolean;
11+
isSeriesVisible?: boolean;
12+
isLegendItemVisible?: boolean;
1213
}
1314
export function computeLegend(
1415
seriesColor: Map<string, DataSeriesColorsValues>,
@@ -24,20 +25,23 @@ export function computeLegend(
2425
const color = seriesColorMap.get(key) || defaultColor;
2526
const hasSingleSeries = seriesColor.size === 1;
2627
const label = getSeriesColorLabel(series.colorValues, hasSingleSeries, spec);
27-
const isVisible = deselectedDataSeries
28+
const isSeriesVisible = deselectedDataSeries
2829
? findDataSeriesByColorValues(deselectedDataSeries, series) < 0
2930
: true;
3031

31-
if (!label) {
32+
if (!label || !spec) {
3233
return;
3334
}
3435

36+
const { hideInLegend } = spec;
37+
3538
legendItems.set(key, {
3639
key,
3740
color,
3841
label,
3942
value: series,
40-
isVisible,
43+
isSeriesVisible,
44+
isLegendItemVisible: !hideInLegend,
4145
});
4246
});
4347
return legendItems;

src/lib/series/series.test.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,7 @@ describe('Series', () => {
181181
yAccessors: ['y'],
182182
yScaleToDataExtent: false,
183183
data: TestDataset.BARCHART_1Y0G,
184+
hideInLegend: false,
184185
};
185186
const spec2: BasicSeriesSpec = {
186187
id: getSpecId('spec2'),
@@ -193,6 +194,7 @@ describe('Series', () => {
193194
stackAccessors: ['x'],
194195
yScaleToDataExtent: false,
195196
data: TestDataset.BARCHART_2Y0G,
197+
hideInLegend: false,
196198
};
197199
seriesSpecs.set(spec1.id, spec1);
198200
seriesSpecs.set(spec2.id, spec2);
@@ -212,6 +214,7 @@ describe('Series', () => {
212214
yAccessors: ['y'],
213215
yScaleToDataExtent: false,
214216
data: TestDataset.BARCHART_1Y0G,
217+
hideInLegend: false,
215218
};
216219
const spec2: BasicSeriesSpec = {
217220
id: getSpecId('spec2'),
@@ -224,6 +227,7 @@ describe('Series', () => {
224227
stackAccessors: ['x'],
225228
yScaleToDataExtent: false,
226229
data: TestDataset.BARCHART_2Y0G,
230+
hideInLegend: false,
227231
};
228232
seriesSpecs.set(spec1.id, spec1);
229233
seriesSpecs.set(spec2.id, spec2);
@@ -245,6 +249,7 @@ describe('Series', () => {
245249
yAccessors: ['y'],
246250
yScaleToDataExtent: false,
247251
data: TestDataset.BARCHART_1Y0G,
252+
hideInLegend: false,
248253
};
249254

250255
const specs = new Map();
@@ -293,6 +298,7 @@ describe('Series', () => {
293298
stackAccessors: ['x'],
294299
yScaleToDataExtent: false,
295300
data: TestDataset.BARCHART_2Y0G,
301+
hideInLegend: false,
296302
};
297303

298304
seriesSpecs.set(splitSpec.id, splitSpec);

src/lib/series/specs.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@ export interface SeriesSpec {
3939
seriesType: 'bar' | 'line' | 'area' | 'basic';
4040
/** Custom colors for series */
4141
customSeriesColors?: CustomSeriesColorsMap;
42+
/** If the series should appear in the legend
43+
* @default false
44+
*/
45+
hideInLegend?: boolean;
4246
}
4347

4448
export type CustomSeriesColorsMap = Map<DataSeriesColorsValues, string>;

src/specs/area_series.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ export class AreaSeriesSpecComponent extends PureComponent<AreaSpecProps> {
1616
xAccessor: 'x',
1717
yAccessors: ['y'],
1818
yScaleToDataExtent: false,
19+
hideInLegend: false,
1920
};
2021
componentDidMount() {
2122
const { chartStore, children, ...config } = this.props;

src/specs/bar_series.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ export class BarSeriesSpecComponent extends PureComponent<BarSpecProps> {
1616
xAccessor: 'x',
1717
yAccessors: ['y'],
1818
yScaleToDataExtent: false,
19+
hideInLegend: false,
1920
};
2021
componentDidMount() {
2122
const { chartStore, children, ...config } = this.props;

src/specs/basic_series.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ export class BasicSeriesSpecComponent extends PureComponent<BasicSpecProps> {
1616
xAccessor: 'x',
1717
yAccessors: ['y'],
1818
yScaleToDataExtent: false,
19+
hideInLegend: false,
1920
};
2021
componentDidMount() {
2122
const { chartStore, children, ...config } = this.props;

0 commit comments

Comments
 (0)