[React] 라이브러리를 사용한 데이터 시각화(armChart, D3, Recharts)
2022. 8. 27.ㆍ공부/React
728x90
목적은 규모있는 공공데이터(CSV 또는 json)를 이용한 데이터 시각화였는데, 라이브러리는 3가지 정도를 보았다.
1. armChart (https://www.amcharts.com/demos/)
사이트 들어가보면 Demos가 시각화부터 애니메이션까지 매우 잘 되어있다. 그러나 대용량 데이터 처리에는 다른 것이 적합할 것 같아서 사용하지 않았다. 간단한 json으로 만들었으면 이것을 썼을듯..?
2. D3 (https://observablehq.com/@d3/gallery)
리서치했을 때 블로그에서 가장 자주 보이던 라이브러리. 인터페이스 세련미 넘친다. 다음 프로젝트에 D3를 이용한 데이터 시각화 넣고 싶을 정도로.. 그런데 이번에는 실제로 3-4시간 동안 D3로 코드 작업을 하다보니 작업하고 있는 프로젝트에는 적합하지 않은 것 같아서 중단하였다. 라이브러리에서 데이터 핸들링이 어렵고 비주얼을 쌓는 기능 위주로 구성되어 있다고 느꼈다.
function d3() {
var margin = {top: 40, right: 20, bottom: 30, left: 40},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var x = d3.scale.ordinal()
.rangeRoundBands([0, width], .1);
var y = d3.scale.linear()
.range([height, 1]);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(y)
.orient("left");
var svg = d3.select("section").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
d3.csv("http://localhost:3000/dummy/rentcar2021.csv", function(d) {
x.domain(d.map(function(a) { return a.VHCLE_NM; }));
y.domain([0, d3.max(d, function(a) { return a.USE_TIME_CO; })]);
/* x축 */
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
/* y축 */
svg.append("g")
.attr("class", "y axis")
.call(yAxis)
.append("text")
.attr("transform", "rotate(-90)")
.style("text-anchor", "end")
.text("이용 시간");
svg.select("body").selectAll("div")
.data(d)
.enter().append("div")
.attr("class", "bar")
.attr("x", function(a) { return x(a.VHCLE_NM); })
.attr("width", x.rangeBand())
.attr("y", function(a) { return y(a.USE_TIME_CO); })
.attr("height", function(a) { return height - y(a.USE_TIME_CO); })
});
function type(d) {
d.USE_TIME_CO = +d.USE_TIME_CO;
return d;
}
};
export default d3;
3. Recharts (https://recharts.org/en-US)
결국 이 라이브러리를 사용했는데, 리액트의 상태값으로 데이터 시각화가 가능해서 너무 좋았다. 사이트 들어가보면 API 문서도 매우 자세하게 되어있고, UI도 심플하고 촌스럽지 않다. hover 시 나오는 툴팁도 D3에서는 D3-tip이라는 것을 따로 설치해야 구현할 수 있었는데 Recharts에서는 지원하고있는 툴팁 컨포넌트로 손쉽게 구현이 가능하다.
import { useState } from "react";
import { BarChart, Cell, Bar, XAxis, YAxis, Tooltip, CartesianGrid, ResponsiveContainer, Legend } from "recharts";
const data = [
{name:"코나 일렉트릭 EV",USE_TIME_CO:"1996"}
,
{name:"K5 2세대",USE_TIME_CO:"1752"}
,
{name:"쏘나타 DN8",USE_TIME_CO:"1568"}
,
.... 생략
export default function App(dataImg) {
const [ activeIndex, setState ] = useState(0);
const [ imgUrl, setUrl ] = useState( "/assets/sub/rent/kona-electric.jpg");
const handleClick = (data, index) => {
setState(index);
setUrl(dataImg.dataImg[index].img);
console.log(imgUrl);
}
return (
<>
<li className="like-list-item" id="rent-card">
<div className="tag"><strong>{activeIndex + 1}</strong>위</div>
<div className="like-list-item-contents">
<div className="like-card-left-sec">
<h1 claassName="info-tit" id="info-tit">
{data[activeIndex].name}
</h1>
<p>
제주도를 찾는 여행객과
<strong>{data[activeIndex].USE_TIME_CO}</strong>
<span>시간 함께하였습니다.</span>
</p>
</div>
<div className="like-card-right-sec">
<div className="like-list-item-ic-cart" id="rent-img">
<img src={`${process.env.PUBLIC_URL}${imgUrl}`} alt="차량이미지" style={{width:'100px', height:'100px', objectFit:'cover'}}/>
</div>
</div>
</div>
</li>
<ResponsiveContainer width={1800} height={350}>
<BarChart width={1800}
height={400}
data={data.slice(0,13)}
barSize={40}
margin={{top: 180,left:200}}>
<XAxis padding={{left: 60}}
tickMargin="10"
tickSize="10"
interval="preserveStart"
width={1200}
scale="point"
type="category"
tick={{fontSize: 13, padding: "6px"}}
dataKey="name"/>
<YAxis hide={true}
padding={{bottom: 10}}
domain={[0, '2000']}
type="number"
tickFormatter={(value) => `${value}시간`}
tick={{fontSize: "13px"}}
dataKey="USE_TIME_CO"/>
<CartesianGrid strokeDasharray="3 3" vertical={false}/>
<Bar dataKey="USE_TIME_CO"
onClick={handleClick}
label={{fontSize: 13, position: "top"}}>
{data.slice(0,13).map((entry, index) =>
(<Cell cursor="pointer"
fill={index === activeIndex ? '#82ca9d' : '#4e6a75'}
key={`cell-${index}`} />))}
</Bar>
<Tooltip />
</BarChart>
</ResponsiveContainer>
</>
);
}
'공부 > React' 카테고리의 다른 글
[React] CORS 해결하기 (0) | 2022.09.03 |
---|---|
[React] React Router DOM (0) | 2022.08.27 |
[React] 가격 컴포넌트(가격 표시 UI) 만들기 (0) | 2022.08.25 |
[React] 댓글 기능 구현 (0) | 2022.08.23 |
[React] 별점 컴포넌트 만들기 (0) | 2022.08.21 |