3) 게임 후 결과 확인(정보 표시, 가장 최근 데이터만 색상 변경)
▶ chartjs-plugin-datalabels 설치
npm i chartjs-plugin-datalabels
ChartJS.register(BarElement, CategoryScale, LinearScale, Tooltip, Legend);
ChartJS.register(ChartDataLabels); //등록하기
development: {
username: "root",
password: process.env.DB_PASSWORD,
database: "DB이름",
host: "127.0.0.1",
dialect: "mysql",
timestamps: true,
timezone: "Asia/Seoul",
dialectOptions: { //해당 부분 추가
charset: "utf8mb4",
dateStrings: true,
typeCast: true,
},
},
▶ sequelize의 테이블 초기화 할 때 생긴 오류
▶ 참고한 방법
▶ sequelize에서 SET foreign_key_checks = 0; 적용
오류 코드
errno: 3730,
sqlState: 'HY000',
sqlMessage: "Cannot drop table 'games' referenced by a foreign key constraint 'scores_ibfk_2' on table 'scores'.",
sql: 'DROP TABLE IF EXISTSgames
;',
parameters: undefined
db.sequelize.query("SET FOREIGN_KEY_CHECKS = 0"); //해당 부분 추가
db.sequelize
.sync({ force: true })
.then(() => {
console.log("DB 연결 성공");
})
.catch(console.error);
[진행 순서]
▶ 게임이 끝난 후 "결과 저장" 버튼 클릭 시 결과값 저장
▶ 결과가 저장되면 내 정보에서 최근 진행된 게임 결과 확인 가능
▶ (추가할 사항) 시간 초과 됬을 때도 "결과 저장" 버튼 존재
▶ "결과 저장" 버튼을 누르지 않으면 게임 종료 불가능하게 함
await Result.findAll({
limit: 1,
where: {
UserId: req.user.id,
},
order: [["createdAt", "DESC"]],
});
▶ 작성에 도움 준 글
▶ 차트 chart.js로 작성하기
▶ 데이터를 불러와서 차트에 적용하기(loop)
▶ 차트의 x, y축 결정
▶ loadGameRequest로 Result값 불러오기(그 중 오늘 날짜만 불러올 것)
const { Op } = require("sequelize");
const moment = require("moment");
const TODAY_START = moment().format("YYYY-MM-DD 00:00");
const NOW = moment().format("YYYY-MM-DD 23:59");
router.get("/", async (req, res, next) => {
try {
const games = await Result.findAll({
raw: true,
UserId: req.user.id,
where: {
createdAt: {
[Op.between]: [TODAY_START, NOW],
},
},
order: [
["createdAt", "DESC"], //최신 것부터
],
});
res.status(200).json(games);
} catch (error) {
console.error(error);
next(error);
}
});
const games = await Result.findAll({
UserId: req.user.id,
createdAt: {
[Op.gt]: TODAY_START,
[Op.lt]: NOW,
},
order: [
["createdAt", "DESC"], //최신 게시글부터
],
});
const scores = games.map((g) => g.score); //전체 내용 중 score 부분만 전달
res.status(200).json(scores);
import {
Chart as ChartJS,
BarElement,
CategoryScale,
LinearScale,
Tooltip,
Legend,
} from "chart.js";
import ChartDataLabels from "chartjs-plugin-datalabels";
import { Bar } from "react-chartjs-2";
import { useCallback, useEffect } from "react";
import { loadGamesRequest } from "../../redux/feature/gameSlice";
import { useDispatch, useSelector } from "react-redux";
import { useRouter } from "next/router";
ChartJS.register(BarElement, CategoryScale, LinearScale, Tooltip, Legend);
ChartJS.register(ChartDataLabels);
const TodayChart = () => {
const dispatch = useDispatch();
const router = useRouter();
const { gameScoreLists } = useSelector((state) => state.game);
useEffect(() => {
dispatch(loadGamesRequest());
}, []);
const ResultArray = [];
gameScoreLists.map((lists, i) => {
const splitTimes = lists.createdAt.split(" ");
const time = splitTimes[1].split(":");
const result = time[0] + "시" + time[1] + "분" + time[2] + "초";
ResultArray.push({
score: `[${parseInt(lists.score)}]`,
time: result,
});
});
var lineChartData = {
labels: [""],
datasets: [],
};
const colors = ["rgba(240, 187, 98, 0.5)", "rgba(78, 108, 80, 0.5)"];
ResultArray.forEach((a, i) => {
lineChartData.datasets.push({
label: `${a.time}`,
//가장 처음 값만 다르게 색상 표시
fillColor: `${ResultArray[0].score === a.score ? colors[0] : colors[1]}`,
borderColor: `${
ResultArray[0].score === a.score ? colors[0] : colors[1]
}`,
backgroundColor: `${
ResultArray[0].score === a.score ? colors[0] : colors[1]
}`,
borderWidth: 1,
data: JSON.parse(a.score),
datalabels: {
// This code is used to display data values
anchor: "end",
align: "top",
formatter: Math.round,
font: {
weight: "bold",
size: 16,
},
},
});
});
const data = {
labels: lineChartData.labels,
datasets: lineChartData.datasets,
};
console.log("data", data);
const options = {
scales: {
y: {
suggestedMin: 0,
suggestedMax: 100,
},
x: {
suggestedMin: 0,
suggestedMax: 100,
},
},
};
const onGoGame = useCallback(() => {
router.push("/game");
}, []);
return (
<div>
{lineChartData.datasets.length === 0 && (
<div className="mt-5 mb-5">
<p>오늘 게임에 참여한 적이 없습니다.</p>
<button
onClick={onGoGame}
className="mt-2 font-bold bg-light-green text-white hover:bg-gray-100 hover:text-light-green px-4 py-2 rounded"
>
게임 시작하기
</button>
</div>
)}
{lineChartData.datasets.length !== 0 && (
<div>
<h1 className="font-bold">오늘의 결과</h1>
<p>(점수가 0인 경우 표에 표시되지 않습니다.)</p>
<Bar data={data} options={options}></Bar>
</div>
)}
</div>
);
};
export default TodayChart;