1
import React, { PureComponent, SyntheticEvent } from 'react';
2
import SeriesName from './SeriesName';
3
import { GraphSeries } from './Graph';
6
chartData: GraphSeries[];
8
onLegendMouseOut: (ev: SyntheticEvent<HTMLDivElement>) => void;
9
onSeriesToggle: (selected: number[], index: number) => void;
10
onHover: (index: number) => (ev: SyntheticEvent<HTMLDivElement>) => void;
13
interface LegendState {
14
selectedIndexes: number[];
17
export class Legend extends PureComponent<LegendProps, LegendState> {
19
selectedIndexes: [] as number[],
21
componentDidUpdate(prevProps: LegendProps): void {
22
if (this.props.shouldReset && prevProps.shouldReset !== this.props.shouldReset) {
23
this.setState({ selectedIndexes: [] });
28
(ev: React.MouseEvent<HTMLDivElement, MouseEvent>): void => {
29
// TODO: add proper event type
30
const { selectedIndexes } = this.state;
32
let selected = [index];
33
if (ev.ctrlKey || ev.metaKey) {
34
const { chartData } = this.props;
35
if (selectedIndexes.includes(index)) {
36
selected = selectedIndexes.filter((idx) => idx !== index);
39
// Flip the logic - In case none is selected ctrl + click should deselect clicked series.
40
selectedIndexes.length === 0
41
? chartData.reduce<number[]>((acc, _, i) => (i === index ? acc : [...acc, i]), [])
42
: [...selectedIndexes, index]; // Select multiple.
44
} else if (selectedIndexes.length === 1 && selectedIndexes.includes(index)) {
48
this.setState({ selectedIndexes: selected });
49
this.props.onSeriesToggle(selected, index);
52
render(): JSX.Element {
53
const { chartData, onLegendMouseOut, onHover } = this.props;
54
const { selectedIndexes } = this.state;
55
const canUseHover = chartData.length > 1 && selectedIndexes.length === 0;
58
<div className="graph-legend" onMouseOut={canUseHover ? onLegendMouseOut : undefined}>
59
{chartData.map(({ index, color, labels }) => (
61
style={{ opacity: selectedIndexes.length === 0 || selectedIndexes.includes(index) ? 1 : 0.5 }}
62
onClick={chartData.length > 1 ? this.handleSeriesSelect(index) : undefined}
63
onMouseOver={canUseHover ? onHover(index) : undefined}
65
className="legend-item"
67
<span className="legend-swatch" style={{ backgroundColor: color }}></span>
68
<SeriesName labels={labels} format />
71
{chartData.length > 1 && (
72
<div className="pl-1 mt-1 text-muted" style={{ fontSize: 13 }}>
73
Click: select series, {navigator.platform.includes('Mac') ? 'CMD' : 'CTRL'} + click: toggle multiple series