我們在前經歷過二十來天的訓練,我們已經學習了後端、前端開發以及進階的開發方式,接下來我想要來挑戰繪製圖表,畢竟在記帳裡面,圖表是最重要的功能,這能夠讓我們知道這段時間的花費變化,直觀地找出花得最多與最少的時間,而且一般來說大家都教如何開發,比較少人教大家如何使用插件,所以這也是一個新的嘗試。
首先我們先輸入以下的程式碼安裝
npm install react-chartjs-2 chart.js
我們可以在package-lock.json中查看安裝的情況
安裝完成之後,我們就要來開發這個頁面
在Component這個資料夾中新增一個ChartComponent.jsxy,因為要使用插件,所以需要匯入比較多插件的相關功能,整個匯入的插件資訊如下
import {
Chart as ChartJS,
CategoryScale,
LinearScale,
BarElement,
Title,
Tooltip,
Legend,
} from 'chart.js';
ChartJS.register(
CategoryScale,
LinearScale,
BarElement,
Title,
Tooltip,
Legend
);
這些功能的說明如下
Chart as ChartJS:
import React, { useEffect, useState } from 'react';
import { Bar } from 'react-chartjs-2';
import { getAccountsByWeek } from '../Service/AccountService';
import {
Chart as ChartJS,
CategoryScale,
LinearScale,
BarElement,
Title,
Tooltip,
Legend,
} from 'chart.js';
ChartJS.register(
CategoryScale,
LinearScale,
BarElement,
Title,
Tooltip,
Legend
);
const ChartComponent = () => {
const [year, setYear] = useState('');
const [week, setWeek] = useState('');
const [chartData, setChartData] = useState({
labels: [],
datasets: [{
label: '',
data: [],
backgroundColor: [],
borderColor: [],
borderWidth: 1
}]
});
useEffect(() => {
// 取得當前年份和週數
const currentDate = new Date();
const currentYear = currentDate.getFullYear();
const currentWeek = getWeekNumber(currentDate);
setYear(currentYear);
setWeek(currentWeek);
// 取得該週的帳戶資料並計算每天的金額加總
getAccountsByWeek(currentYear, currentWeek).then((response) => {
const dailyTotals = calculateDailyTotals(response.data);
setChartData({
labels: ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'],
datasets: [
{
label: 'Daily Expenses',
data: dailyTotals,
backgroundColor: 'rgba(75, 192, 192, 0.6)',
borderColor: 'rgba(75, 192, 192, 1)',
borderWidth: 1,
},
],
});
}).catch((error) => {
console.error(error);
});
}, []);
// 計算每天的金額加總
const calculateDailyTotals = (accounts) => {
const totals = Array(7).fill(0); // 初始化每週 7 天的金額加總為 0
accounts.forEach((account) => {
const dayOfWeek = new Date(account.createDate).getDay(); // 取得當前日期是星期幾 (0 是 Sunday)
const index = dayOfWeek === 0 ? 6 : dayOfWeek - 1; // 將 Sunday 對應到 index 6
totals[index] += account.amount;
});
return totals;
};
// Helper function to get the week number
const getWeekNumber = (date) => {
const firstDayOfYear = new Date(date.getFullYear(), 0, 1);
const pastDaysOfYear = (date - firstDayOfYear) / 86400000;
return Math.ceil((pastDaysOfYear + firstDayOfYear.getDay() + 1) / 7);
};
return (
<div className='container'>
<h2 className='text-center'>Weekly Expense Chart</h2>
<div className='d-flex justify-content-center'>
<div className='chart-container' style={{ height: '400px', width: '600px' }}>
<Bar data={chartData} options={{ maintainAspectRatio: false }} />
</div>
</div>
</div>
);
};
export default ChartComponent;
接下來我們回到App.jsx,來新增這個轉址。
import { useState } from 'react'
import reactLogo from './assets/react.svg'
import viteLogo from '/vite.svg'
import './App.css'
import HelloWorld from './Helloworld'
import HeaderComponent from './Component/HeaderComponent'
import FooterComponent from './Component/FooterComponent'
import AccountComponent from './Component/AccountComponent'
import ListAccountComponent from './Component/ListAccountComponent'
import { BrowserRouter, Routes,Route} from 'react-router-dom'
import SortAccountComponent from './Component/SortAccountComponent'
import WeeklyAccountComponent from './Component/WeeklyAccountComponent'
import ChartComponent from './Component/ChartComponent'
function App() {
return (
<>
<BrowserRouter>
<HeaderComponent />
<Routes>
{/* http://localhost:8080/ */}
<Route path='/' element={<ListAccountComponent />}></Route>
{/* http://localhost:8080/chart-account */}
<Route path='/chart-account' element={<ChartComponent />}></Route>
{/* http://localhost:8080/weekly-account' */}
<Route path='/week-account' element={<WeeklyAccountComponent />}></Route>
{/* http://localhost:8080/list-account */}
<Route path='/lsit-account' element={<ListAccountComponent />}></Route>
{/* http://localhost:8080/add-account */}
<Route path='/add-account' element={<AccountComponent />}></Route>
{/* http://localhost:8080/add-account/1 */}
<Route path='/update-account/:id' element={<AccountComponent />}></Route>
{/* http://localhost:8080/sort-account/ */}
<Route path='/sort-account' element={<SortAccountComponent />}></Route>
</Routes>
<FooterComponent />
</BrowserRouter>
</>
)
}
export default App
新增完成之後,我們來到Header頁面新增這個連結
/* eslint-disable no-unused-vars */
import React, { useState } from 'react'
import { NavLink } from 'react-router-dom'
const HeaderComponent = () => {
return (
<div>
<header>
<nav className='navbar navbar-expand-md navbar-dark bg-dark'>
<div>
<a href='http://localhost:5173/' className='navbar-brand'>
Account Manager Application</a>
</div>
<div className='collapse navbar-collapse'>
<ul className='navbar-nav'>
<li className='nav-item'>
<NavLink to="/lsit-account" className="nav-link">Account List</NavLink>
</li>
<li className='nav-item'>
<NavLink to="/sort-account" className="nav-link">Sort Account</NavLink>
</li>
<li className='nav-item'>
<NavLink to="/week-account" className="nav-link">Week Account</NavLink>
</li>
<li className='nav-item'>
<NavLink to="/chart-account" className="nav-link">Chart Account</NavLink>
</li>
</ul>
</div>
</nav>
</header>
</div>
)
}
export default HeaderComponent
結果如下
到了這裡,我們就成功的把進階的資料,用我們引入的插件,用圖表的方式呈現出我們的資料了!
到這裡,相信大家已經熟練地完成後端、前端,以及前後端整合的練習了,但網頁開發除了這些需求開發之外,還有安全性的開發與設置,在這裏,我們將使用Spring boot Security來為我們的網站增加安全性
那各位夥伴,我們就明天見囉!