Skip to content

Commit

Permalink
feat(legend): hide legend item if hideLegendItem on series spec is tr…
Browse files Browse the repository at this point in the history
…ue (#147)
  • Loading branch information
emmacunningham authored Apr 4, 2019
1 parent 9bae64b commit 6761c2b
Show file tree
Hide file tree
Showing 14 changed files with 107 additions and 25 deletions.
4 changes: 4 additions & 0 deletions src/components/_legend.scss
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,10 @@ $elasticChartsLegendMaxHeight: $euiSize * 4;
text-decoration: underline;
}
}

&.elasticChartsLegendList__item--hidden {
display: none;
}
}

.elasticChartsLegendListItem__title {
Expand Down
14 changes: 8 additions & 6 deletions src/components/legend.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -68,18 +68,20 @@ class LegendComponent extends React.Component<ReactiveChartProps> {
responsive={false}
>
{[...legendItems.values()].map((item) => {
const { color, label, isSeriesVisible, isLegendItemVisible } = item;

const legendItemProps = {
key: item.key,
className: 'elasticChartsLegendList__item',
className: classNames('elasticChartsLegendList__item', {
'elasticChartsLegendList__item--hidden': !isLegendItemVisible,
}),
onMouseEnter: this.onLegendItemMouseover(item.key),
onMouseLeave: this.onLegendItemMouseout,
};

const { color, label, isVisible } = item;

return (
<EuiFlexItem {...legendItemProps}>
{this.renderLegendElement({ color, label, isVisible }, item.key)}
{this.renderLegendElement({ color, label, isSeriesVisible }, item.key)}
</EuiFlexItem>
);
})}
Expand All @@ -98,10 +100,10 @@ class LegendComponent extends React.Component<ReactiveChartProps> {
}

private renderLegendElement = (
{ color, label, isVisible }: Partial<LegendItem>,
{ color, label, isSeriesVisible }: Partial<LegendItem>,
legendItemKey: string,
) => {
const props = { color, label, isVisible, legendItemKey };
const props = { color, label, isSeriesVisible, legendItemKey };

return <LegendElement {...props} />;
}
Expand Down
10 changes: 5 additions & 5 deletions src/components/legend_element.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ interface LegendElementProps {
legendItemKey: string;
color: string | undefined;
label: string | undefined;
isVisible?: boolean;
isSeriesVisible?: boolean;
}

interface LegendElementState {
Expand Down Expand Up @@ -52,7 +52,7 @@ class LegendElementComponent extends React.Component<LegendElementProps, LegendE

render() {
const { legendItemKey } = this.props;
const { color, label, isVisible } = this.props;
const { color, label, isSeriesVisible } = this.props;

const onTitleClick = this.onLegendTitleClick(legendItemKey);

Expand Down Expand Up @@ -88,7 +88,7 @@ class LegendElementComponent extends React.Component<LegendElementProps, LegendE
</EuiPopover>
</EuiFlexItem>
<EuiFlexItem grow={false}>
{this.renderVisibilityButton(legendItemKey, isVisible)}
{this.renderVisibilityButton(legendItemKey, isSeriesVisible)}
</EuiFlexItem>
<EuiFlexItem grow={false} className={titleClassNames} onClick={onTitleClick}>
<EuiPopover
Expand Down Expand Up @@ -156,8 +156,8 @@ class LegendElementComponent extends React.Component<LegendElementProps, LegendE
}
}

private renderVisibilityButton = (legendItemKey: string, isVisible: boolean = true) => {
const iconType = isVisible ? 'eye' : 'eyeClosed';
private renderVisibilityButton = (legendItemKey: string, isSeriesVisible: boolean = true) => {
const iconType = isSeriesVisible ? 'eye' : 'eyeClosed';
return (
<EuiButtonIcon
onClick={this.onVisibilityClick(legendItemKey)}
Expand Down
28 changes: 18 additions & 10 deletions src/lib/series/legend.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ const spec1: BasicSeriesSpec = {
yAccessors: ['y'],
yScaleToDataExtent: false,
data: [],
hideInLegend: false,
};
const spec2: BasicSeriesSpec = {
id: getSpecId('spec2'),
Expand All @@ -42,6 +43,7 @@ const spec2: BasicSeriesSpec = {
yAccessors: ['y'],
yScaleToDataExtent: false,
data: [],
hideInLegend: false,
};

describe('Legends', () => {
Expand All @@ -65,7 +67,8 @@ describe('Legends', () => {
color: 'red',
label: 'Spec 1 title',
value: { colorValues: [], specId: 'spec1' },
isVisible: true,
isSeriesVisible: true,
isLegendItemVisible: true,
key: 'colorSeries1a',
},
];
Expand All @@ -80,14 +83,16 @@ describe('Legends', () => {
color: 'red',
label: 'Spec 1 title',
value: { colorValues: [], specId: 'spec1' },
isVisible: true,
isSeriesVisible: true,
isLegendItemVisible: true,
key: 'colorSeries1a',
},
{
color: 'blue',
label: 'a - b',
value: { colorValues: ['a', 'b'], specId: 'spec1' },
isVisible: true,
isSeriesVisible: true,
isLegendItemVisible: true,
key: 'colorSeries1b',
},
];
Expand All @@ -102,14 +107,16 @@ describe('Legends', () => {
color: 'red',
label: 'Spec 1 title',
value: { colorValues: [], specId: 'spec1' },
isVisible: true,
isSeriesVisible: true,
isLegendItemVisible: true,
key: 'colorSeries1a',
},
{
color: 'green',
label: 'spec2',
value: { colorValues: [], specId: 'spec2' },
isVisible: true,
isSeriesVisible: true,
isLegendItemVisible: true,
key: 'colorSeries2a',
},
];
Expand All @@ -129,7 +136,8 @@ describe('Legends', () => {
color: 'violet',
label: 'Spec 1 title',
value: { colorValues: [], specId: 'spec1' },
isVisible: true,
isSeriesVisible: true,
isLegendItemVisible: true,
key: 'colorSeries1a',
},
];
Expand All @@ -146,9 +154,9 @@ describe('Legends', () => {

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

const visibility = [...legend.values()].map((item) => item.isVisible);
const visibility = [...legend.values()].map((item) => item.isSeriesVisible);

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

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

const visibility = [...legend.values()].map((item) => item.isVisible);
expect(visibility).toEqual([false, false, true, true]);
const visibility = [...legend.values()].map((item) => item.isSeriesVisible);
expect(visibility).toEqual([false, false, true]);
});
it('returns the right series label for a color series', () => {
let label = getSeriesColorLabel([], true);
Expand Down
12 changes: 8 additions & 4 deletions src/lib/series/legend.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ export interface LegendItem {
color: string;
label: string;
value: DataSeriesColorsValues;
isVisible?: boolean;
isSeriesVisible?: boolean;
isLegendItemVisible?: boolean;
}
export function computeLegend(
seriesColor: Map<string, DataSeriesColorsValues>,
Expand All @@ -24,20 +25,23 @@ export function computeLegend(
const color = seriesColorMap.get(key) || defaultColor;
const hasSingleSeries = seriesColor.size === 1;
const label = getSeriesColorLabel(series.colorValues, hasSingleSeries, spec);
const isVisible = deselectedDataSeries
const isSeriesVisible = deselectedDataSeries
? findDataSeriesByColorValues(deselectedDataSeries, series) < 0
: true;

if (!label) {
if (!label || !spec) {
return;
}

const { hideInLegend } = spec;

legendItems.set(key, {
key,
color,
label,
value: series,
isVisible,
isSeriesVisible,
isLegendItemVisible: !hideInLegend,
});
});
return legendItems;
Expand Down
6 changes: 6 additions & 0 deletions src/lib/series/series.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ describe('Series', () => {
yAccessors: ['y'],
yScaleToDataExtent: false,
data: TestDataset.BARCHART_1Y0G,
hideInLegend: false,
};
const spec2: BasicSeriesSpec = {
id: getSpecId('spec2'),
Expand All @@ -193,6 +194,7 @@ describe('Series', () => {
stackAccessors: ['x'],
yScaleToDataExtent: false,
data: TestDataset.BARCHART_2Y0G,
hideInLegend: false,
};
seriesSpecs.set(spec1.id, spec1);
seriesSpecs.set(spec2.id, spec2);
Expand All @@ -212,6 +214,7 @@ describe('Series', () => {
yAccessors: ['y'],
yScaleToDataExtent: false,
data: TestDataset.BARCHART_1Y0G,
hideInLegend: false,
};
const spec2: BasicSeriesSpec = {
id: getSpecId('spec2'),
Expand All @@ -224,6 +227,7 @@ describe('Series', () => {
stackAccessors: ['x'],
yScaleToDataExtent: false,
data: TestDataset.BARCHART_2Y0G,
hideInLegend: false,
};
seriesSpecs.set(spec1.id, spec1);
seriesSpecs.set(spec2.id, spec2);
Expand All @@ -245,6 +249,7 @@ describe('Series', () => {
yAccessors: ['y'],
yScaleToDataExtent: false,
data: TestDataset.BARCHART_1Y0G,
hideInLegend: false,
};

const specs = new Map();
Expand Down Expand Up @@ -293,6 +298,7 @@ describe('Series', () => {
stackAccessors: ['x'],
yScaleToDataExtent: false,
data: TestDataset.BARCHART_2Y0G,
hideInLegend: false,
};

seriesSpecs.set(splitSpec.id, splitSpec);
Expand Down
4 changes: 4 additions & 0 deletions src/lib/series/specs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ export interface SeriesSpec {
seriesType: 'bar' | 'line' | 'area' | 'basic';
/** Custom colors for series */
customSeriesColors?: CustomSeriesColorsMap;
/** If the series should appear in the legend
* @default false
*/
hideInLegend?: boolean;
}

export type CustomSeriesColorsMap = Map<DataSeriesColorsValues, string>;
Expand Down
1 change: 1 addition & 0 deletions src/specs/area_series.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export class AreaSeriesSpecComponent extends PureComponent<AreaSpecProps> {
xAccessor: 'x',
yAccessors: ['y'],
yScaleToDataExtent: false,
hideInLegend: false,
};
componentDidMount() {
const { chartStore, children, ...config } = this.props;
Expand Down
1 change: 1 addition & 0 deletions src/specs/bar_series.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export class BarSeriesSpecComponent extends PureComponent<BarSpecProps> {
xAccessor: 'x',
yAccessors: ['y'],
yScaleToDataExtent: false,
hideInLegend: false,
};
componentDidMount() {
const { chartStore, children, ...config } = this.props;
Expand Down
1 change: 1 addition & 0 deletions src/specs/basic_series.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export class BasicSeriesSpecComponent extends PureComponent<BasicSpecProps> {
xAccessor: 'x',
yAccessors: ['y'],
yScaleToDataExtent: false,
hideInLegend: false,
};
componentDidMount() {
const { chartStore, children, ...config } = this.props;
Expand Down
1 change: 1 addition & 0 deletions src/specs/line_series.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export class LineSeriesSpecComponent extends PureComponent<LineSpecProps> {
xAccessor: 'x',
yAccessors: ['y'],
yScaleToDataExtent: false,
hideInLegend: false,
};
componentDidMount() {
const { chartStore, children, ...config } = this.props;
Expand Down
1 change: 1 addition & 0 deletions src/state/chart_state.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ describe('Chart Store', () => {
yAccessors: ['y'],
xScaleType: ScaleType.Linear,
yScaleType: ScaleType.Linear,
hideInLegend: false,
};

const firstLegendItem = {
Expand Down
2 changes: 2 additions & 0 deletions src/state/test/interactions.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ const ordinalBarSeries: BarSeriesSpec = {
yAccessors: [1],
xScaleType: ScaleType.Ordinal,
yScaleType: ScaleType.Linear,
hideInLegend: false,
};
const linearBarSeries: BarSeriesSpec = {
id: SPEC_ID,
Expand All @@ -33,6 +34,7 @@ const linearBarSeries: BarSeriesSpec = {
yAccessors: [1],
xScaleType: ScaleType.Linear,
yScaleType: ScaleType.Linear,
hideInLegend: false,
};
const chartTop = 10;
const chartLeft = 10;
Expand Down
Loading

0 comments on commit 6761c2b

Please sign in to comment.