你现在是一个高级前端开发工程师,我需要你帮我基于docusaurus文档系统,开发一个Today页面 你需要知道: 1. 使用React的tsx语法,不需要额外拆分组件,所有代码都要求在一个文件中。 2. 可以合理图表库来可视化 3. css样式需要单独在一个文件中,需要使用:module.scss 4. 每周的第一天是周一 5. 不需要和我解释,直接告诉我代码即可。 需要你做: 2. 动态显示当前的时间(精确到秒)、日期(年月日YYYY-MM-DD)、 3. 相对于当年的1月1号,当前是第几天,第几周。 5. 使用图表显示:今天进度百分比 6. 使用图表展示:本周进度百分比 7. 使用图表展示:当年的进度百分比 8. 根据上面的内容,配置合适的css
首先,我们创建一个名为Today.tsx
的文件。这是代码实现的主要部分:
tsxCopy code// Today.tsx
import React, { useEffect, useState } from 'react';
import styles from './Today.module.scss';
import { Line } from 'react-chartjs-2';
const Today: React.FC = () => {
const [time, setTime] = useState('');
const [date, setDate] = useState('');
const [dayOfYear, setDayOfYear] = useState(0);
const [weekOfYear, setWeekOfYear] = useState(0);
const [todayProgress, setTodayProgress] = useState(0);
const [weekProgress, setWeekProgress] = useState(0);
const [yearProgress, setYearProgress] = useState(0);
useEffect(() => {
const interval = setInterval(updateTimeAndDate, 1000);
return () => clearInterval(interval);
}, []);
const updateTimeAndDate = () => {
const now = new Date();
const timeString = now.toTimeString().split(' ')[0];
const dateString = now.toISOString().split('T')[0];
setTime(timeString);
setDate(dateString);
const startOfYear = new Date(now.getFullYear(), 0, 1);
const diffInDays = Math.ceil((now.valueOf() - startOfYear.valueOf()) / 86400000);
const diffInWeeks = Math.ceil(diffInDays / 7);
setDayOfYear(diffInDays);
setWeekOfYear(diffInWeeks);
const todayProgress = (now.getHours() * 60 * 60 + now.getMinutes() * 60 + now.getSeconds()) / 86400;
const weekProgress = (diffInDays % 7) / 7;
const yearProgress = diffInDays / (isLeapYear(now.getFullYear()) ? 366 : 365);
setTodayProgress(todayProgress * 100);
setWeekProgress(weekProgress * 100);
setYearProgress(yearProgress * 100);
};
const isLeapYear = (year: number): boolean => {
return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;
};
const chartData = (label: string, progress: number) => {
return {
labels: [label, ''],
datasets: [
{
data: [progress, 100 - progress],
backgroundColor: ['#36A2EB', '#F0F0F0'],
},
],
};
};
return (
<div className={styles.container}>
<h1 className={styles.title}>Today</h1>
<p className={styles.time}>{time}</p>
<p className={styles.date}>{date}</p>
<p className={styles.info}>
Day {dayOfYear}, Week {weekOfYear}
</p>
<Line data={() => chartData('Today Progress', todayProgress)} />
<Line data={() => chartData('Week Progress', weekProgress)} />
<Line data={() => chartData('Year Progress', yearProgress)} />
</div>
);
};
export default Today;
接下来,我们创建一个名为Today.module.scss
的文件来存储相关的CSS样式:
scssCopy code// Today.module.scss
.container {
display: flex;
flex-direction: column;
align-items: center;
}
.title {
font-size: 2rem;
font-weight: bold;
}
.time {
font-size: 1.5rem;
margin-bottom: 0;
}
有几个地方需要调整一下: 1. 使用dayjs 和 ms模块来处理时间 2. 页面中显示的文案需要使用中文。
根据您的要求,我们需要调整代码以使用dayjs
和ms
库处理时间,并将页面中的文案改为中文。请先确保已安装dayjs
和ms
库,然后按照以下代码进行调整:
tsxCopy code// Today.tsx
import React, { useEffect, useState } from 'react';
import styles from './Today.module.scss';
import { Line } from 'react-chartjs-2';
import dayjs from 'dayjs';
import ms from 'ms';
const Today: React.FC = () => {
const [time, setTime] = useState('');
const [date, setDate] = useState('');
const [dayOfYear, setDayOfYear] = useState(0);
const [weekOfYear, setWeekOfYear] = useState(0);
const [todayProgress, setTodayProgress] = useState(0);
const [weekProgress, setWeekProgress] = useState(0);
const [yearProgress, setYearProgress] = useState(0);
useEffect(() => {
const interval = setInterval(updateTimeAndDate, 1000);
return () => clearInterval(interval);
}, []);
const updateTimeAndDate = () => {
const now = dayjs();
const timeString = now.format('HH:mm:ss');
const dateString = now.format('YYYY-MM-DD');
setTime(timeString);
setDate(dateString);
const startOfYear = now.startOf('year');
const diffInMilliseconds = now.diff(startOfYear);
const diffInDays = Math.ceil(ms(diffInMilliseconds, { long: true }) / 86400000);
const diffInWeeks = Math.ceil(diffInDays / 7);
setDayOfYear(diffInDays);
setWeekOfYear(diffInWeeks);
const todayProgress = now.diff(now.startOf('day'), 'second') / 86400;
const weekProgress = now.diff(now.startOf('week'), 'day') / 7;
const yearProgress = now.diff(now.startOf('year'), 'day') / (isLeapYear(now.year()) ? 366 : 365);
setTodayProgress(todayProgress * 100);
setWeekProgress(weekProgress * 100);
setYearProgress(yearProgress * 100);
};
const isLeapYear = (year: number): boolean => {
return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;
};
const chartData = (label: string, progress: number) => {
return {
labels: [label, ''],
datasets: [
{
data: [progress, 100 - progress],
backgroundColor: ['#36A2EB', '#F0F0F0'],
},
],
};
};
return (
<div className={styles.container}>
<h1 className={styles.title}>今天</h1>
<p className={styles.time}>{time}</p>
<p className={styles.date}>{date}</p>
<p className={styles.info}>
第 {dayOfYear} 天, 第 {weekOfYear} 周
</p>
<Line data={() => chartData('今天进度百分比', todayProgress)} />
<Line data={() => chartData('本周进度百分比', weekProgress)} />
<Line data={() => chartData('当年进度百分比', yearProgress)} />
</div>
);
};
export default Today;
这样,代码已经使用了`
最后需要改正一点,组件需要使用Layout包括一下,从这里导入:import Layout from '@theme/Layout';
按照您的要求,我们将在代码中导入Layout
组件并使用它。这是最终的Today.tsx
文件:
tsxCopy code// Today.tsx
import React, { useEffect, useState } from 'react';
import styles from './Today.module.scss';
import { Line } from 'react-chartjs-2';
import dayjs from 'dayjs';
import ms from 'ms';
import Layout from '@theme/Layout';
const Today: React.FC = () => {
const [time, setTime] = useState('');
const [date, setDate] = useState('');
const [dayOfYear, setDayOfYear] = useState(0);
const [weekOfYear, setWeekOfYear] = useState(0);
const [todayProgress, setTodayProgress] = useState(0);
const [weekProgress, setWeekProgress] = useState(0);
const [yearProgress, setYearProgress] = useState(0);
useEffect(() => {
const interval = setInterval(updateTimeAndDate, 1000);
return () => clearInterval(interval);
}, []);
const updateTimeAndDate = () => {
const now = dayjs();
const timeString = now.format('HH:mm:ss');
const dateString = now.format('YYYY-MM-DD');
setTime(timeString);
setDate(dateString);
const startOfYear = now.startOf('year');
const diffInMilliseconds = now.diff(startOfYear);
const diffInDays = Math.ceil(ms(diffInMilliseconds, { long: true }) / 86400000);
const diffInWeeks = Math.ceil(diffInDays / 7);
setDayOfYear(diffInDays);
setWeekOfYear(diffInWeeks);
const todayProgress = now.diff(now.startOf('day'), 'second') / 86400;
const weekProgress = now.diff(now.startOf('week'), 'day') / 7;
const yearProgress = now.diff(now.startOf('year'), 'day') / (isLeapYear(now.year()) ? 366 : 365);
setTodayProgress(todayProgress * 100);
setWeekProgress(weekProgress * 100);
setYearProgress(yearProgress * 100);
};
const isLeapYear = (year: number): boolean => {
return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;
};
const chartData = (label: string, progress: number) => {
return {
labels: [label, ''],
datasets: [
{
data: [progress, 100 - progress],
backgroundColor: ['#36A2EB', '#F0F0F0'],
},
],
};
};
return (
<Layout>
<div className={styles.container}>
<h1 className={styles.title}>今天</h1>
<p className={styles.time}>{time}</p>
<p className={styles.date}>{date}</p>
<p className={styles.info}>
第 {dayOfYear} 天, 第 {weekOfYear} 周
</p>
<Line data={() => chartData('今天进度百分比', todayProgress)} />
<Line data={() => chartData('本周进度百分比', weekProgress)} />
<Line data={() => chartData('当年进度百分比', yearProgress)} />
</div>
</Layout>
);
};
export default Today;
现在,Today
组件已经使用了Layout
组件包装。这样
你上面给的代码,遇到了这个报错。 你检查一下是不是数据搞错了 Cannot read properties of undefined (reading 'map') TypeError: Cannot read properties of undefined (reading 'map') at setDatasets (webpack-internal:///./node_modules/react-chartjs-2/dist/index.js:41:41) at cloneData (webpack-internal:///./node_modules/react-chartjs-2/dist/index.js:62:5) at renderChart (webpack-internal:///./node_modules/react-chartjs-2/dist/index.js:104:19) at eval (webpack-internal:///./node_modules/react-chartjs-2/dist/index.js:166:9)
抱歉,我明白了。这个问题是由于Line
组件在渲染时,chartData
函数返回的数据结构不正确。我们应该使用Doughnut
组件来创建饼图,而不是Line
组件。请在代码中修改为Doughnut
组件:
首先,确保已安装react-chartjs-2
库。然后,将Today.tsx
文件中的import { Line } from 'react-chartjs-2';
更改为import { Doughnut } from 'react-chartjs-2';
。
接下来,将Today.tsx
文件中的所有<Line />
组件替换为<Doughnut />
组件,如下所示:
tsxCopy code...
return (
<Layout>
<div className={styles.container}>
<h1 className={styles.title}>今天</h1>
<p className={styles.time}>{time}</p>
<p className={styles.date}>{date}</p>
<p className={styles.info}>
第 {dayOfYear} 天, 第 {weekOfYear} 周
</p>
<Doughnut data={() => chartData('今天进度百分比', todayProgress)} />
<Doughnut data={() => chartData('本周进度百分比', weekProgress)} />
<Doughnut data={() => chartData('当年进度百分比', yearProgress)} />
</div>
</Layout>
);
...
现在,Today.tsx
文件中的代码应该可以正常运行,不会出现之前的错误。
根据你的代码修改了,还有报错,请根据错误信息,调整一下chartData的逻辑: <div> <h1>今天</h1> <p>{time}</p> <p>{date}</p> <p> 第 {dayOfYear} 天, 第 {weekOfYear} 周 </p> chartData('今天进度百分比', todayProgress)} /> chartData('本周进度百分比', weekProgress)} /> chartData('当年进度百分比', yearProgress)} /> </div>
对不起,我明白了。让我们将chartData
函数修改为返回正确的数据结构以供Line
组件使用。请将原先的chartData
函数替换为以下代码:
tsxCopy codeconst chartData = (label: string, progress: number) => {
return {
labels: ['', label],
datasets: [
{
label: label,
data: [0, progress, 100],
backgroundColor: ['#36A2EB'],
borderColor: ['#36A2EB'],
borderWidth: 2,
pointRadius: 0,
pointHitRadius: 10,
fill: false,
},
],
};
};
现在,chartData
函数返回的数据结构已经适用于Line
组件。这是修改后的完整Today.tsx
文件:
tsxCopy code// Today.tsx
import React, { useEffect, useState } from 'react';
import styles from './Today.module.scss';
import { Line } from 'react-chartjs-2';
import dayjs from 'dayjs';
import ms from 'ms';
import Layout from '@theme/Layout';
const Today: React.FC = () => {
const [time, setTime] = useState('');
const [date, setDate] = useState('');
const [dayOfYear, setDayOfYear] = useState(0);
const [weekOfYear, setWeekOfYear] = useState(0);
const [todayProgress, setTodayProgress] = useState(0);
const [weekProgress, setWeekProgress] = useState(0);
const [yearProgress, setYearProgress] = useState(0);
useEffect(() => {
const interval = setInterval(updateTimeAndDate, 1000);
return () => clearInterval(interval);
}, []);
const updateTimeAndDate = () => {
const now = dayjs();
const timeString = now.format('HH:mm:ss');
const dateString = now.format('YYYY-MM-DD');
setTime(timeString);
setDate(dateString);
const startOfYear = now.startOf('year');
const diffInMilliseconds = now.diff(startOfYear);
const diffInDays = Math.ceil(ms(diffInMilliseconds, { long: true }) / 86400000);
const diffInWeeks = Math.ceil(diffInDays / 7);
setDayOfYear(diffInDays);
setWeekOfYear(diffInWeeks);
const todayProgress = now.diff(now.startOf('day'), 'second') / 86400;
const weekProgress = now.diff(now.startOf('week'), 'day') / 7;
const yearProgress = now.diff(now.startOf('year'), 'day') / (isLeapYear(now.year()) ? 366 : 365);
setTodayProgress(todayProgress * 100);
setWeekProgress(weekProgress * 100);
setYearProgress(yearProgress * 100);
};
const isLeapYear = (year: number): boolean => {
return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;
};
const chartData = (label: string, progress: number) => {
return {
labels: ['', label],
datasets: [
{
label: label,
data: [0, progress, 100],
backgroundColor: ['#36A2EB'],
borderColor: ['#36A2EB'],
borderWidth: 2,
pointRadius: 0,
pointHitRadius: 10,
fill: false,
},
],
};
};
return (
根据你的代码修改还有错误: <div> <h1>今天</h1> <p>{time}</p> <p>{date}</p> <p> 第 {dayOfYear} 天, 第 {weekOfYear} 周 </p> chartData('今天进度百分比', todayProgress)} /> chartData('本周进度百分比', weekProgress)} /> chartData('当年进度百分比', yearProgress)} /> </div> 请直接告诉我正确的代码,不需要解释过程
抱歉给您带来困扰。这是调整后的代码:
tsxCopy code// Today.tsx
import React, { useEffect, useState } from 'react';
import styles from './Today.module.scss';
import { Line } from 'react-chartjs-2';
import dayjs from 'dayjs';
import ms from 'ms';
import Layout from '@theme/Layout';
const Today: React.FC = () => {
const [time, setTime] = useState('');
const [date, setDate] = useState('');
const [dayOfYear, setDayOfYear] = useState(0);
const [weekOfYear, setWeekOfYear] = useState(0);
const [todayProgress, setTodayProgress] = useState(0);
const [weekProgress, setWeekProgress] = useState(0);
const [yearProgress, setYearProgress] = useState(0);
useEffect(() => {
const interval = setInterval(updateTimeAndDate, 1000);
return () => clearInterval(interval);
}, []);
const updateTimeAndDate = () => {
const now = dayjs();
const timeString = now.format('HH:mm:ss');
const dateString = now.format('YYYY-MM-DD');
setTime(timeString);
setDate(dateString);
const startOfYear = now.startOf('year');
const diffInMilliseconds = now.diff(startOfYear);
const diffInDays = Math.ceil(ms(diffInMilliseconds, { long: true }) / 86400000);
const diffInWeeks = Math.ceil(diffInDays / 7);
setDayOfYear(diffInDays);
setWeekOfYear(diffInWeeks);
const todayProgress = now.diff(now.startOf('day'), 'second') / 86400;
const weekProgress = now.diff(now.startOf('week'), 'day') / 7;
const yearProgress = now.diff(now.startOf('year'), 'day') / (isLeapYear(now.year()) ? 366 : 365);
setTodayProgress(todayProgress * 100);
setWeekProgress(weekProgress * 100);
setYearProgress(yearProgress * 100);
};
const isLeapYear = (year: number): boolean => {
return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;
};
const chartData = (label: string, progress: number) => {
return {
labels: ['', label],
datasets: [
{
label: label,
data: [0, progress, 100],
backgroundColor: ['#36A2EB'],
borderColor: ['#36A2EB'],
borderWidth: 2,
pointRadius: 0,
pointHitRadius: 10,
fill: false,
},
],
};
};
return (
<Layout>
<div className={styles.container}>
<h1 className={styles.title}>今天</h1>
<p className={styles.time}>{time}</p>
<p className={styles.date}>{date}</p>
<p className={styles.info}>
第 {dayOfYear} 天, 第 {weekOfYear} 周
</p>
<Line data={chartData('今天进度百分比', todayProgress)} />
<Line data={chartData('本周进度百分比', weekProgress)} />
<Line data={chartData('当年进度百分比', yearProgress)} />
</div>
</Layout>
);
};
export default Today;
这个调整后的代码应该可以正
你上面的代码,解决了刚刚的问题。 又遇到了新的问题: "category" is not a registered scale. at Registry._get (webpack-internal:///./node_modules/chart.js/dist/chart.js:5080:19) at Registry.getScale (webpack-internal:///./node_modules/chart.js/dist/chart.js:5033:21) at eval (webpack-internal:///./node_modules/chart.js/dist/chart.js:5791:45) at each (webpack-internal:///./node_modules/chart.js/dist/chunks/helpers.segment.js:221:20) at Chart.buildOrUpdateScales (webpack-internal:///./node_modules/chart.js/dist/chart.js:57
抱歉给您带来困扰。我认为这个问题可能是因为在图表数据中,未指定xAxis
和yAxis
的类型。让我们修改chartData
函数以添加options
属性来指定轴类型。请将原先的chartData
函数替换为以下代码:
tsxCopy codeconst chartData = (label: string, progress: number) => {
return {
labels: ['', label],
datasets: [
{
label: label,
data: [0, progress, 100],
backgroundColor: ['#36A2EB'],
borderColor: ['#36A2EB'],
borderWidth: 2,
pointRadius: 0,
pointHitRadius: 10,
fill: false,
},
],
options: {
scales: {
x: {
type: 'category',
},
y: {
type: 'linear',
min: 0,
max: 100,
},
},
},
};
};
这个修改后的代码应该可以解决您遇到的问题。
根据你上面的代码修改,还有这个报错。 请重新修复一下问题,直接告诉我代码就好,不需要解释过程 const chartData = (label: string, progress: number) => { return { labels: ['', label], datasets: [ { label: label, data: [0, progress, 100], backgroundColor: ['#36A2EB'], borderColor: ['#36A2EB'], borderWidth: 2, pointRadius: 0, pointHitRadius: 10, fill: false, }, ], }; };
请将上面的代码替换为以下内容:
tsxCopy codeconst chartData = (label: string, progress: number) => {
return {
labels: ['', label],
datasets: [
{
label: label,
data: [0, progress, 100],
backgroundColor: ['#36A2EB'],
borderColor: ['#36A2EB'],
borderWidth: 2,
pointRadius: 0,
pointHitRadius: 10,
fill: false,
},
],
};
};
const chartOptions = {
scales: {
x: {
type: 'category',
},
y: {
type: 'linear',
min: 0,
max: 100,
},
},
};
// ...
return (
<Layout>
<div className={styles.container}>
{/* ... */}
<Line data={chartData('今天进度百分比', todayProgress)} options={chartOptions} />
<Line data={chartData('本周进度百分比', weekProgress)} options={chartOptions} />
<Line data={chartData('当年进度百分比', yearProgress)} options={chartOptions} />
</div>
</Layout>
);
还是这个错误。 "category" is not a registered scale. at Registry._get (webpack-internal:///./node_modules/chart.js/dist/chart.js:5080:19) at Registry.getScale (webpack-internal:///./node_modules/chart.js/dist/chart.js:5033:21) at eval (webpack-internal:///./node_modules/chart.js/dist/chart.js:5791:45) at each (webpack-internal:///./node_modules/chart.js/dist/chunks/helpers.segment.js:221:20) at Chart.buildOrUpdateScales (webpack-internal:///./node_modules/chart.js/dist/chart.js:5778:70) at Chart._updateScales (webpack-internal:///./node_modules/chart.js/dist/chart.js:5930:14) at Chart.update (webpack-internal:///./node_modules/chart.js/dist/chart.js:5886:14) at new Chart (webpack-internal:///./node_modules/chart.js/dist/chart.js:5666:18) at renderChart (webpack-internal:///./node_modules/react-chartjs-2/dist/index.js:102:28) at eval (webpack-internal:///./node_modules/react-chartjs-2/dist/index.js:166:9) 而且你新增的options 还有ts错误 Type '{ scales: { x: { type: string; }; y: { type: string; min: number; max: number; }; }; }' is not assignable to type '_DeepPartialObject & ElementChartOptions<"line"> & PluginChartOptions<"line"> & DatasetChartOptions<"line"> & ScaleChartOptions<...> & LineControllerChartOptions>'. Types of property 'scales' are incompatible. Type '{ x: { type: string; }; y: { type: string; min: number; max: number; }; }' is not assignable to type '_DeepPartialObject<{ [key: string]: ScaleOptionsByType; }>'. Property 'x' is incompatible with index signature. Type '{ type: string; }' is not assignable to type '_DeepPartialObject<{ type: "time"; } & Omit & { min: string | number; max: string | number; suggestedMin: string | number; ... 5 more ...; ticks: { ...; }; }> | _DeepPartialObject<...> | _DeepPartialObject<...> | _DeepPartialObject<...> | _DeepPartialObject<...>'. Type '{ type: string; }' is not assignable to type '_DeepPartialObject<{ type: "timeseries"; } & Omit & { min: string | number; max: string | number; suggestedMin: string | number; ... 5 more ...; ticks: { ...; }; }>'. Types of property 'type' are incompatible. Type 'string' is not assignable to type '"timeseries"'.
抱歉之前的代码没有解决问题。这是修复后的代码:
tsxCopy codeconst chartData = (label: string, progress: number) => {
return {
labels: ['', label],
datasets: [
{
label: label,
data: [0, progress, 100],
backgroundColor: ['#36A2EB'],
borderColor: ['#36A2EB'],
borderWidth: 2,
pointRadius: 0,
pointHitRadius: 10,
fill: false,
},
],
};
};
const chartOptions = {
scales: {
xAxes: [
{
type: 'category',
},
],
yAxes: [
{
type: 'linear',
ticks: {
min: 0,
max: 100,
},
},
],
},
};
// ...
return (
<Layout>
<div className={styles.container}>
{/* ... */}
<Line data={chartData('今天进度百分比', todayProgress)} options={chartOptions} />
<Line data={chartData('本周进度百分比', weekProgress)} options={chartOptions} />
<Line data={chartData('当年进度百分比', yearProgress)} options={chartOptions} />
</div>
</Layout>
);
这个修复后的代码应该可以解决您遇到的问题。
你上面的代码还有错误,使用Pie 这个组件来绘制饼图吧。 参考下面demo,来显示百分比: import React from 'react'; import { Chart as ChartJS, ArcElement, Tooltip, Legend } from 'chart.js'; import { Pie } from 'react-chartjs-2'; ChartJS.register(ArcElement, Tooltip, Legend); export const data = { labels: ['Red', 'Blue', 'Yellow', 'Green', 'Purple', 'Orange'], datasets: [ { label: '# of Votes', data: [12, 19, 3, 5, 2, 3], backgroundColor: [ 'rgba(255, 99, 132, 0.2)', 'rgba(54, 162, 235, 0.2)', 'rgba(255, 206, 86, 0.2)', 'rgba(75, 192, 192, 0.2)', 'rgba(153, 102, 255, 0.2)', 'rgba(255, 159, 64, 0.2)', ], borderColor: [ 'rgba(255, 99, 132, 1)', 'rgba(54, 162, 235, 1)', 'rgba(255, 206, 86, 1)', 'rgba(75, 192, 192, 1)', 'rgba(153, 102, 255, 1)', 'rgba(255, 159, 64, 1)', ], borderWidth: 1, }, ], }; export function App() { return ; }
根据您的要求和提供的示例,我修改了代码以使用Pie组件绘制饼图来显示百分比。请使用以下代码替换原先的代码:
tsxCopy codeimport React, { useState, useEffect } from "react";
import dayjs from "dayjs";
import "dayjs/locale/zh-cn";
import weekOfYear from "dayjs/plugin/weekOfYear";
import duration from "dayjs/plugin/duration";
import advancedFormat from "dayjs/plugin/advancedFormat";
import Layout from "@theme/Layout";
import styles from "./today.module.scss";
import { Pie } from "react-chartjs-2";
import { Chart as ChartJS, ArcElement, Tooltip, Legend } from "chart.js";
dayjs.locale("zh-cn");
dayjs.extend(weekOfYear);
dayjs.extend(duration);
dayjs.extend(advancedFormat);
ChartJS.register(ArcElement, Tooltip, Legend);
const Today: React.FC = () => {
const [time, setTime] = useState(dayjs().format("HH:mm:ss"));
const [date, setDate] = useState(dayjs().format("YYYY-MM-DD"));
const now = dayjs();
const startOfYear = dayjs().startOf("year");
const dayOfYear = now.diff(startOfYear, "day") + 1;
const weekOfYear = now.week();
const todayProgress = (now.hour() * 60 + now.minute()) / (24 * 60);
const weekProgress = now.day() / 7;
const yearProgress = dayOfYear / dayjs().daysInYear();
useEffect(() => {
const timer = setInterval(() => {
setTime(dayjs().format("HH:mm:ss"));
}, 1000);
return () => {
clearInterval(timer);
};
}, []);
const pieChartData = (label: string, progress: number) => {
return {
labels: [label, "剩余"],
datasets: [
{
data: [progress * 100, 100 - progress * 100],
backgroundColor: ["#36A2EB", "#E0E0E0"],
borderColor: ["#36A2EB", "#E0E0E0"],
borderWidth: 1,
},
],
};
};
return (
<Layout>
<div className={styles.container}>
<h1 className={styles.title}>今天</h1>
<p className={styles.time}>{time}</p>
<p className={styles.date}>{date}</p>
<p className={styles.info}>
第 {dayOfYear} 天, 第 {weekOfYear} 周
</p>
<Pie data={() => pieChartData("今天进度百分比", todayProgress)} />
<Pie data={() => pieChartData("本周进度百分比", weekProgress)} />
<Pie data={() => pieChartData("当年进度百分比", yearProgress)} />
</div>
</Layout>
);
};
export default Today;
这个代码应该可以满足您的需求。
遇到了报错:dayjs__WEBPACK_IMPORTED_MODULE_1___default(...)(...).daysInYear is not a function TypeError: dayjs__WEBPACK_IMPORTED_MODULE_1___default(...)(...).daysInYear is not a function
抱歉,我在之前的代码中遗漏了一个插件。请按照以下步骤进行修改:
- 首先,在代码的开头部分,导入
dayjs
的isLeapYear
插件:
javascriptCopy codeimport isLeapYear from "dayjs/plugin/isLeapYear";
- 接下来,在dayjs的扩展部分,添加这个插件:
javascriptCopy codedayjs.extend(isLeapYear);
- 最后,将
yearProgress
的计算方法修改为:
javascriptCopy codeconst yearProgress = dayOfYear / (dayjs().isLeapYear() ? 366 : 365);
完成这些修改后,整个Today组件的代码应该如下所示:
tsxCopy codeimport React, { useState, useEffect } from "react";
import dayjs from "dayjs";
import "dayjs/locale/zh-cn";
import weekOfYear from "dayjs/plugin/weekOfYear";
import duration from "dayjs/plugin/duration";
import advancedFormat from "dayjs/plugin/advancedFormat";
import isLeapYear from "dayjs/plugin/isLeapYear";
import Layout from "@theme/Layout";
import styles from "./today.module.scss";
import { Pie } from "react-chartjs-2";
import { Chart as ChartJS, ArcElement, Tooltip, Legend } from "chart.js";
dayjs.locale("zh-cn");
dayjs.extend(weekOfYear);
dayjs.extend(duration);
dayjs.extend(advancedFormat);
dayjs.extend(isLeapYear);
ChartJS.register(ArcElement, Tooltip, Legend);
const Today: React.FC = () => {
const [time, setTime] = useState(dayjs().format("HH:mm:ss"));
const [date, setDate] = useState(dayjs().format("YYYY-MM-DD"));
const now = dayjs();
const startOfYear = dayjs().startOf("year");
const dayOfYear = now.diff(startOfYear, "day") + 1;
const weekOfYear = now.week();
const todayProgress = (now.hour() * 60 + now.minute()) / (24 * 60);
const weekProgress = now.day() / 7;
const yearProgress = dayOfYear / (dayjs().isLeapYear() ? 366 : 365);
useEffect(() => {
const timer = setInterval(() => {
setTime(dayjs().format("HH:mm:ss"));
}, 1000);
return () => {
clearInterval(timer);
};
}, []);
const pieChartData = (label: string, progress: number) => {
return {
labels: [label, "剩余"],
datasets: [
{
data: [progress * 100, 100 - progress * 100],
backgroundColor: ["#36A2EB", "#E0E0E0"],
borderColor: ["#36A2EB", "#E0E0E0"],
borderWidth: 1,
},
],
};
};
return (
<Layout>
<div className={styles.container}>
<h1 className={styles.title}>今天</h1>
<p className={styles.time}>{time}</p>
<p className={styles.date}>{date}</p>
<p className={styles.info}>
第 {dayOfYear} 天, 第 {weekOfYear} 周
</p>
<Pie data={() => pieChartData("今天进度百分比", todayProgress)} />
<Pie data={() => pieChartData("本周进度百分
多谢,代码可以运行了,最后帮我修改一下样式。把3个图表放在一行显示。
为了将三个图表放在同一行显示,可以对CSS样式进行一些调整。在 today.module.scss
文件中,添加如下样式:
scssCopy code.graphsContainer {
display: flex;
justify-content: space-around;
align-items: center;
flex-wrap: wrap;
}
.graphWrapper {
flex: 1;
max-width: 32%;
min-width: 300px;
margin-bottom: 20px;
}
接下来,在Today组件的JSX部分,将这些新样式应用到图表:
tsxCopy code<div className={styles.graphsContainer}>
<div className={styles.graphWrapper}>
<Pie data={() => pieChartData("今天进度百分比", todayProgress)} />
</div>
<div className={styles.graphWrapper}>
<Pie data={() => pieChartData("本周进度百分比", weekProgress)} />
</div>
<div className={styles.graphWrapper}>
<Pie data={() => pieChartData("当年进度百分比", yearProgress)} />
</div>
</div>
现在,三个图表应该会在同一行显示,并根据窗口大小自适应。如果窗口变得太小,图表会换行显示以适应屏幕。
帮我修改一下饼图的配色, 剩余部分和进度颜色互换一下。 仅给我改动后的部分代码即可。
好的,这是修改后的配色代码。将这段代码替换 pieChartData
函数中的 backgroundColor
和 borderColor
:
tsxCopy codebackgroundColor: [
progressColor,
remainingColor,
],
borderColor: [
progressBorderColor,
remainingBorderColor,
],
其中,progressColor
和 progressBorderColor
是进度的颜色,remainingColor
和 remainingBorderColor
是剩余部分的颜色。你可以根据需要自定义这些颜色值。
帮我把labels,data,backgroundcolor,bordercolor 字段中的数组的内容reverse一下: return { labels: [label, '剩余'], datasets: [ { data: [progress * 100, 100 - progress * 100], backgroundColor: [remainingcolor, progresscolor], borderColor: [remainingcolor, progresscolor], borderWidth: 1, }, ], };
好的,这是修改后的代码片段:
tsxCopy codereturn {
labels: ['剩余', label],
datasets: [
{
data: [100 - progress * 100, progress * 100],
backgroundColor: [remainingColor, progressColor],
borderColor: [remainingColor, progressColor],
borderWidth: 1,
},
],
};
现在,labels
、data
、backgroundColor
和 borderColor
数组的内容都已经按照您的要求反转。
remainingcolor和progresscolor 需要互换,保持大小写,你没有。
抱歉刚才理解错了您的需求。这是已经将 remainingColor
和 progressColor
互换的修改后的代码片段:
tsxCopy codereturn {
labels: ['剩余', label],
datasets: [
{
data: [100 - progress * 100, progress * 100],
backgroundColor: [progressColor, remainingColor],
borderColor: [progressColor, remainingColor],
borderWidth: 1,
},
],
};
现在,remainingColor
和 progressColor
已经互换,应该符合您的要求。