저번 포스팅에 react에서 wordcloud를 띄우는 법까지 완성했습니다. 이제 검색한 데이터를 전달해서 wordcloud안에 넣어 완성해보도록 하죠!
이제 해야할건 검색한 review데이터를 d3.js가 존재하는 HotelsResult.js에 전달하는 거겠죠?? 간단하게 props를 이용할 겁니다. 사실 글로벌 상태관리를 많이 찾아보며 redux나 context를 쓰는 것을 생각했습니다. 근데 아직은 폴더가 그리 복잡하지 않아서 그낭 props로 전달하면 될 것 같네요..ㅎ
props를 전달하기 위해 컴포넌트를 정확히 구성해야 했습니다. props는 항상 위에서 아래로 흐른다는 점! 상위 컴포넌트에서 전달해주어야 합니다. 그래서 검색한 결과를 상위컴포넌트에 넣어주어야 합니다.
다음과 같이 간단하게 구성했습니다.
// Hotels/HotelsSearch.js
<div>
<button id="hotels-search" onClick={clickSearch}>검색</button>
<HotelsResult words={reviewWords} />
</div>
HotelsResult의 props로 words={reviewWords}라는 state를 넣어주었고요
props를 받을 때는
// Hotels/HotelsResult.js
function HotelsResult(props) {
console.log(props.words);
}
다음과 같이 받으면 됩니다. 그래서 data부분에 그저 props.words를 넣어주면 끝납니다. ㅎ
전체코드는 다음과 같습니다.
import React, { useEffect } from 'react';
import * as d3 from 'd3';
import cloud from 'd3-cloud';
const width = 400
const height = 400
function HotelsResult(props) {
useEffect(() => {
d3.selectAll('svg').remove();
cloud()
.size([width, height])
.words(props.words.map(function(d) {
return {text: d, size: 10 + Math.random() * 90, test: "haha"};
}))
.padding(5)
.font("Impact")
.fontSize(function(d) { return d.size; })
.on("end", end)
.start();
function end(words) {
d3.select("#word-cloud")
.append("svg")
.attr("width", 500)
.attr("height", 500)
.style("border", "1px solid black")
.append("g")
.attr("transform", "translate(" + 500 / 2 + "," + 500 / 2 + ")")
.selectAll("text")
.data(words)
.enter().append("text")
.style("font-size", function(d) { return d.size + "px"; })
.style("font-family", "Impact")
.attr("text-anchor", "middle")
.attr("transform", function(d) {
return "translate(" + [d.x, d.y] + ")rotate(" + d.rotate + ")";
})
.text(function(d) { return d.text; });
console.log(JSON.stringify(words));
}
})
return (
<div>
<h1>리뷰 분석 결과</h1>
<div id="word-cloud"></div>
</div>
)
}
export default HotelsResult;
그럼 다음과 같이 결과가 잘 나옵니다 ㅎㅎ
여기까지 프로토타입은 완성한거 같네요!! 이제 긍정/부정 단어로 나눈다던지, wordcloud를 이쁘게 만든다던지 하는 부가적인 것들은 추후 하면 될 것 같습니다
의견이나 조언, 질문 있으시면 댓글에 적어주세요! 감사합니다!