(수정)일주일간 생성한 단어 개수 그래프로 확인(오늘 생성한 단어도 결과에 포함)

개발공부·2023년 1월 12일
0

* 결과

1) 그래프 확인하기

2) 과거 단어 삭제 시 그래프 변동(맨 오른쪽 8 -> 7)

▶ 수정(오늘 생성한 단어도 결과 확인됨)

* 참고한 글

chart.js 동영상

배열 요소 중복 횟수 구하기

const getElCount = (arr) =>
    arr.reduce((ac, v) => ({ ...ac, [v]: (ac[v] || 0) + 1 }), {});

  const result = getElCount(weekData);
  console.log("result", result); 
  //{'01-09' : 2, '01-10': 3, '01-11': 8}

객체의 value값만 가져오기

const wordData = Object.values(result);
// [2, 3, 8]

* 고려할 점

1. 그래프가 createdAt에 따라 변동성이 있을 것

▶ moment 사용함

const moment = require("moment");

2. 전체 데이터를 가져오면 속도가 느려지니, "createdAt"을 제외한 나머지는 가져오지 말 것

const moment = require("moment");

router.get("/weekend", async (req, res, next) => {
  try {
    today = moment().format();
    dateFrom = moment().subtract(7, "d").format("YYYY-MM-DD");
    console.log("dateFrom", dateFrom);
    const words = await Word.findAll({
      where: {
        createdAt: {
          [Op.between]: [dateFrom, today], //일주일 동안의 값
        },
      },
      order: [
        ["createdAt"], //날짜 순
      ],
      attributes: {
        exclude: [
          "id",
          "english",
          "korean",
          "type",
          "status",
          "updatedAt",
          "UserId",
        ],
      },
    });
    res.status(200).json(words);
  } catch (error) {
    console.error(error);
    next(error);
  }
});

3. 일주일 동안의 데이터를 가져올 것(1과 동일)

loadWordsWeekendSuccess: (state, action) => {
      const data = action.payload;
      state.loadWordsWeekendLoading = false;
      state.loadWordsWeekendComplete = true;
      //전체 word
      state.weekendResult.length = 0;
      state.weekendResult = state.weekendResult.concat(data);
    }

4. 가져온 데이터는 labels이 되는 문자열과 실제 값이 되는 데이터, 2가지의 배열이 필요

const weekData = [];

  weekendResult.map((week, i) => {
    const createdAt = week.createdAt.substr(5, 5);
    const changeDate = createdAt.replace("-", "/");
    weekData.push(changeDate);
  });

  const getElCount = (arr) =>
    arr.reduce((ac, v) => ({ ...ac, [v]: (ac[v] || 0) + 1 }), {});

  const result = getElCount(weekData);
  const wordData = Object.values(result);
  const maxValue = Math.max.apply(null, wordData);
  const minValue = Math.min.apply(null, wordData);

  console.log("wordData", wordData);
  const weekDatas = new Set(weekData);
  const oneWeek = [...weekDatas];

  const data = {
    labels: oneWeek,
    datasets: [
      {
        data: wordData,
        backgroundColor: "transparent",
        borderColor: "#F0BB62",
        pointBorderColor: "transparent",
        pointBorderWidth: 4,
        tension: 0.5,
      },
    ],
  };

* 코드

[components/WeekendWordChart.js]

import { Line } from "react-chartjs-2";
import {
  Chart as ChartJS,
  LineElement,
  CategoryScale,
  LinearScale,
  PointElement,
} from "chart.js";

ChartJS.register(LineElement, CategoryScale, LinearScale, PointElement);

const WeekendWordChart = ({ weekendResult }) => {
  const weekData = [];

  weekendResult.map((week, i) => {
    const createdAt = week.createdAt.substr(5, 5);
    const changeDate = createdAt.replace("-", "/");
    weekData.push(changeDate);
  });

  const getElCount = (arr) =>
    arr.reduce((ac, v) => ({ ...ac, [v]: (ac[v] || 0) + 1 }), {});

  const result = getElCount(weekData);
  const wordData = Object.values(result);
  const maxValue = Math.max.apply(null, wordData);
  const minValue = Math.min.apply(null, wordData);

  console.log("wordData", wordData);
  const weekDatas = new Set(weekData);
  const oneWeek = [...weekDatas];

  const data = {
    labels: oneWeek,
    datasets: [
      {
        data: wordData,
        backgroundColor: "transparent",
        borderColor: "#F0BB62",
        pointBorderColor: "transparent",
        pointBorderWidth: 4,
        tension: 0.5,
      },
    ],
  };
  const options = {
    plugins: {
      legend: false,
    },
    scales: {
      x: {
        grid: {
          display: false,
        },
      },
      y: {
        min: minValue,
        max: maxValue,
      },
    },
  };

  return (
    <>
      <p className="text-center">
        전체 유저들의 <br />
        <span className="font-bold text-light-orange">
          주간({oneWeek[0]} ~ {oneWeek[oneWeek.length - 1]})
        </span>{" "}
        단어 작성 개수
      </p>
      <div className="h-48 lg:w-80">
        <Line data={data} options={options}></Line>
      </div>
    </>
  );
};

export default WeekendWordChart;
profile
개발 블로그, 티스토리(https://ba-gotocode131.tistory.com/)로 갈아탐

0개의 댓글