prometheus

Форк
0
79 строк · 2.9 Кб
1
import React, { PureComponent, SyntheticEvent } from 'react';
2
import SeriesName from './SeriesName';
3
import { GraphSeries } from './Graph';
4

5
interface LegendProps {
6
  chartData: GraphSeries[];
7
  shouldReset: boolean;
8
  onLegendMouseOut: (ev: SyntheticEvent<HTMLDivElement>) => void;
9
  onSeriesToggle: (selected: number[], index: number) => void;
10
  onHover: (index: number) => (ev: SyntheticEvent<HTMLDivElement>) => void;
11
}
12

13
interface LegendState {
14
  selectedIndexes: number[];
15
}
16

17
export class Legend extends PureComponent<LegendProps, LegendState> {
18
  state = {
19
    selectedIndexes: [] as number[],
20
  };
21
  componentDidUpdate(prevProps: LegendProps): void {
22
    if (this.props.shouldReset && prevProps.shouldReset !== this.props.shouldReset) {
23
      this.setState({ selectedIndexes: [] });
24
    }
25
  }
26
  handleSeriesSelect =
27
    (index: number) =>
28
    (ev: React.MouseEvent<HTMLDivElement, MouseEvent>): void => {
29
      // TODO: add proper event type
30
      const { selectedIndexes } = this.state;
31

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);
37
        } else {
38
          selected =
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.
43
        }
44
      } else if (selectedIndexes.length === 1 && selectedIndexes.includes(index)) {
45
        selected = [];
46
      }
47

48
      this.setState({ selectedIndexes: selected });
49
      this.props.onSeriesToggle(selected, index);
50
    };
51

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;
56

57
    return (
58
      <div className="graph-legend" onMouseOut={canUseHover ? onLegendMouseOut : undefined}>
59
        {chartData.map(({ index, color, labels }) => (
60
          <div
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}
64
            key={index}
65
            className="legend-item"
66
          >
67
            <span className="legend-swatch" style={{ backgroundColor: color }}></span>
68
            <SeriesName labels={labels} format />
69
          </div>
70
        ))}
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
74
          </div>
75
        )}
76
      </div>
77
    );
78
  }
79
}
80

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.