차트 데이터 연동

세인트킴·2024년 5월 26일

hcmc

목록 보기
8/10


우선 데이터를 입력할 때 Amount옆에 조그맣게 카운터가 있었는데 이는 <input> 태그 안의 type=number가 되어있어서 발생하기에 이를 삭제했다.

그리고 AccountList.js<Select> 태그에서 <Input>의 값이 로딩중에 undefined가 되고 로딩이 끝나면 해결되는 경고 메세지가 떠서 <Select> 태그 안에 value={selectedMonth}를 넣고, onChange={handleMonthChange} 를 넣어서 경고를 해결했다.

Chart.js

import { Chart as ChartJS, ArcElement, Tooltip, Legend } from "chart.js"
ChartJS.register(ArcElement, Tooltip, Legend)

를 등록해서 Doughnut컴포넌트에 들어갈 chart.js 모듈을 등록해준다. 이걸 해야지 도넛 차트를 렌더링 할 수 있고, 없다면 오류가 발생한다.

const processData = (data) => {
  const categories = ["식비", "생필품", "문화/교육비", "기타", "저축"];
  const backgroundColors = [
    "rgb(255, 130, 157)", // 식비
    "rgba(54, 162, 235)", // 생필품
    "rgba(255, 206, 86)", // 문화/교육비
    "rgba(75, 192, 192)", // 기타
    "rgba(60, 179, 113)", // 저축
  ];

  const dataList = categories.reduce((acc, category) => {
    acc[category] = 0;
    return acc;
  }, {});

  data.forEach((item) => {
    if (dataList[item.category] !== undefined) {
      dataList[item.category] += item.amount;
    }
  });

  return {
    labels: categories,
    datasets: [
      {
        data: categories.map((category) => dataList[category]),
        backgroundColor: backgroundColors,
      },
    ],
  };
};

useEffect()에 들어갈 processData(data)도 작성해준다.
dataList에서 categories.reduce((acc, category))를 해준다.item.amount로 추가될 데이터를 위해서 초기화 해줘야 한다. 추가된 데이터를 담을 {} 객체를 이용해서 acc["식비"] = 0, acc["생필품"] = 0, acc["문화/교육비"] = 0, acc["기타"] = 0, acc["저축"] = 0를 담을 수 있다. 만약 {}가 없다면 처음에 들어간 "식비" 객체만 리턴될 수 있다.
{}없을 때

{}있을 때

data.forEach((item))를 해줘서 초기화 된 값을 이용해 item.amount해준 값을 undefined가 아니라면 5개의 객체마다 dataList[category] += item.amount에 추가해준다. 이렇게 해주면 초기화된 값에 axios.get()을 통해 추가된 금액을 넣을 수 있다.
여기서 dataresponse.data랑 같다.

processData(data)의 반환 값으로 레이블에 categories를 넣고,
datasetsdatacategories.map((category) => dataList[category)를 넣어준다. 위의 forEach()로 추가된 값을 "카테고리명": 카테고리에 해당하는 값으로 넣을 수 있다.

const Chart = () => {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    const fetchData = async () => {
      try {
        const response = await axios.get("http://localhost:4000/wallet/money");
        const chartData = processData(response.data);
        setData(chartData);
        setLoading(false);
      } catch (err) {
        console.error(err);
        setLoading(false);
      }
    };
    fetchData();
  }, []); // useEffect에 빈 배열을 두어 컴포넌트가 마운트될 때만 실행되도록 함

  const options = {
    responsive: true,
    plugins: { legend: { position: "right" } },
    layout: { padding: { left: 60 } },
  };

  if (loading) {
    return <div>Loading...</div>;
  }
};
profile
잘하는 건 노력

0개의 댓글