서비스가 주식 관련 서비스이다 보니 차트를 사용할 일이 잦다.

차트를 직접 구현하자니 너무 공수가 많이 들 것 같아 Recharts 라이브러리를 자주 사용하고 있다.

하지만 공식문서에서 모든게 나와있지 않아서 ChatGPT의 도움도 많이 받고 있다. 그래도 꽤 쓸만한 라이브러리이다.

오늘은 Recharts 라이브러리로 legend에 hover했을 때, hover된 데이터만 highlight 되도록 구현해볼 것이다.

chart

우선 기본적인 Line 차트를 렌더링한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
import { useState } from "react";
import {
LineChart,
Line,
XAxis,
YAxis,
Tooltip,
Legend,
ResponsiveContainer,
} from "recharts";

const data = [
{
name: "Page A",
uv: 4000,
pv: 2400,
amt: 2400,
},
{
name: "Page B",
uv: 3000,
pv: 1398,
amt: 2210,
},
{
name: "Page C",
uv: 2000,
pv: 9800,
amt: 2290,
},
{
name: "Page D",
uv: 2780,
pv: 3908,
amt: 2000,
},
{
name: "Page E",
uv: 1890,
pv: 4800,
amt: 2181,
},
{
name: "Page F",
uv: 2390,
pv: 3800,
amt: 2500,
},
{
name: "Page G",
uv: 3490,
pv: 4300,
amt: 2100,
},
];

function MultiLineCharts() {
const [opacity, setOpacity] = useState({ uv: 1, pv: 1 });

const handleMouseEnter = (o) => {
const { dataKey } = o;

const entries = Object.entries(opacity).map(([key, value]) =>
key === dataKey ? [key, 1] : [key, 0.2]
);

const mappedObj = entries.reduce((prev, curr) => {
const [key, value] = curr;
prev = { ...prev, [key]: value };
return prev;
}, {});

setOpacity(mappedObj);
};

const handleMouseLeave = (o) => {
const { dataKey } = o;

const entries = Object.entries(opacity).map(([key, value]) => [key, 1]);

const mappedObj = entries.reduce((prev, curr) => {
const [key, value] = curr;
prev = { ...prev, [key]: value };
return prev;
}, {});

setOpacity(mappedObj);
};
return (
<ResponsiveContainer width="100%" height="100%">
<ResponsiveContainer width="100%" height={300}>
<LineChart
width={500}
height={300}
data={data}
margin={{
top: 5,
right: 30,
left: 20,
bottom: 5,
}}
>
<XAxis dataKey="name" />
<YAxis />
<Tooltip />
<Legend
onMouseEnter={handleMouseEnter}
onMouseLeave={handleMouseLeave}
/>
<Line
type="monotone"
dataKey="pv"
strokeOpacity={opacity.pv}
stroke="#8884d8"
activeDot={{ r: 8 }}
/>
<Line
type="monotone"
dataKey="uv"
strokeOpacity={opacity.uv}
stroke="#82ca9d"
/>
</LineChart>
</ResponsiveContainer>
</ResponsiveContainer>
);
}

export default MultiLineCharts;
  • Line 그래프의 opacityuseState로 관리한다.
  • Legend에 onMouseEnter, onMouseLeave 이벤트를 할당한다.
  • 여기서 유저가 이벤트를 발생시킨 요소만 opacity를 두고 나머지 데이터들의 opacity를 줄여주기 위해 opacity 객체를 재구성했다.
  • Object.entries()reduce()를 사용하여 편리하게 객체를 재구성할 수 있다.

결과

hover chart

  • 보라색 Legend Hover 시

hover_chart2

  • 연두색 Legend Hover 시