2024-11-05 15:40:58 +08:00
|
|
|
|
import { computed, defineComponent, onBeforeUnmount, onMounted, reactive, ref } from "vue";
|
2024-11-04 19:30:31 +08:00
|
|
|
|
// 引入 echarts 核心模块,核心模块提供了 echarts 使用必须要的接口。
|
|
|
|
|
import * as echarts from 'echarts/core';
|
|
|
|
|
import { LineChart, PieChart, } from 'echarts/charts';
|
|
|
|
|
// 引入柱状图图表,图表后缀都为 Chart
|
|
|
|
|
import { BarChart } from 'echarts/charts';
|
|
|
|
|
// 引入标题,提示框,直角坐标系,数据集,内置数据转换器组件,组件后缀都为 Component
|
|
|
|
|
import {
|
|
|
|
|
TitleComponent,
|
|
|
|
|
TooltipComponent,
|
|
|
|
|
GridComponent,
|
|
|
|
|
DatasetComponent,
|
|
|
|
|
TransformComponent
|
|
|
|
|
} from 'echarts/components';
|
|
|
|
|
// 标签自动布局、全局过渡动画等特性
|
|
|
|
|
import { LabelLayout, UniversalTransition } from 'echarts/features';
|
|
|
|
|
// 引入 Canvas 渲染器,注意引入 CanvasRenderer 或者 SVGRenderer 是必须的一步
|
|
|
|
|
import { CanvasRenderer } from 'echarts/renderers';
|
|
|
|
|
import useTomatoStore from "../useTomatoStore";
|
|
|
|
|
import dayjs from "dayjs";
|
|
|
|
|
import gsap from 'gsap'
|
|
|
|
|
import { Progress } from "ant-design-vue";
|
|
|
|
|
|
|
|
|
|
// 注册必须的组件
|
|
|
|
|
echarts.use([
|
|
|
|
|
PieChart,
|
|
|
|
|
TitleComponent,
|
|
|
|
|
LineChart,
|
|
|
|
|
TooltipComponent,
|
|
|
|
|
GridComponent,
|
|
|
|
|
DatasetComponent,
|
|
|
|
|
TransformComponent,
|
|
|
|
|
BarChart,
|
|
|
|
|
LabelLayout,
|
|
|
|
|
UniversalTransition,
|
|
|
|
|
CanvasRenderer
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
// 接下来的使用就跟之前一样,初始化图表,设置配置项
|
|
|
|
|
|
|
|
|
|
export default defineComponent(() => {
|
|
|
|
|
const chart = ref(null);
|
|
|
|
|
const leftChat = ref(null)
|
|
|
|
|
const store = useTomatoStore()
|
|
|
|
|
const precent1 = reactive({
|
|
|
|
|
number: 0
|
|
|
|
|
})
|
|
|
|
|
const precent2 = reactive({
|
|
|
|
|
number: 0
|
|
|
|
|
})
|
|
|
|
|
let myChart: echarts.ECharts | null = null;
|
|
|
|
|
|
|
|
|
|
const initChart = () => {
|
|
|
|
|
myChart = echarts.init(chart.value);
|
|
|
|
|
const option = {
|
|
|
|
|
|
|
|
|
|
tooltip: {
|
|
|
|
|
trigger: 'axis',
|
|
|
|
|
formatter: (params: any) => {
|
|
|
|
|
const dataPoint = params[0];
|
|
|
|
|
const timeInMinutes = dataPoint.value;
|
|
|
|
|
// 使用 HTML 标签格式化 tooltip 内容
|
|
|
|
|
return `${dataPoint.name} <br/> <strong class="text-blue-500">${timeInMinutes} </strong>分钟`;
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
xAxis: {
|
|
|
|
|
type: 'category',
|
|
|
|
|
data: Array.from({ length: 7 }).map((_, idx) => (dayjs().subtract(idx, 'day').format('MM月DD日'))).reverse(),
|
|
|
|
|
},
|
|
|
|
|
yAxis: {
|
|
|
|
|
type: 'value',
|
|
|
|
|
},
|
|
|
|
|
series: [
|
|
|
|
|
{
|
|
|
|
|
type: 'line',
|
|
|
|
|
data: Array.from({ length: 7 }).map((_, idx) => (dayjs().subtract(idx, 'day').format('MM月DD日')))
|
|
|
|
|
.reverse()
|
|
|
|
|
.map(item => store.state.timeList.reduce((pre, cur) => {
|
|
|
|
|
if (dayjs(cur).isSame(dayjs(item, "MM月DD日"), 'day')) {
|
|
|
|
|
return pre + 1
|
|
|
|
|
}
|
|
|
|
|
return 0
|
|
|
|
|
}, 0) * 15),
|
|
|
|
|
lineStyle: {
|
|
|
|
|
color: '#C876FB', // 线条的颜色
|
|
|
|
|
width: 2, // 线条宽度
|
|
|
|
|
},
|
|
|
|
|
itemStyle: {
|
|
|
|
|
color: '#FF8688', // 数据点的颜色
|
|
|
|
|
},
|
|
|
|
|
showSymbol: false, // 默认不显示数据点
|
|
|
|
|
// hover 时显示数据点
|
|
|
|
|
emphasis: {
|
|
|
|
|
itemStyle: {
|
|
|
|
|
color: '#FF8688', // 悬停时数据点的颜色
|
|
|
|
|
|
|
|
|
|
},
|
|
|
|
|
showSymbol: true, // 悬停时显示数据点
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
myChart.setOption(option);
|
|
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
onMounted(() => {
|
|
|
|
|
initChart();
|
|
|
|
|
window.addEventListener('resize', myChart?.resize as any);
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
|
|
|
|
|
}, 1000)
|
|
|
|
|
gsap.to(precent1, { duration: 1, number: Number(100) || 0 })
|
|
|
|
|
gsap.to(precent2, { duration: 1, number: Number(100) || 0 })
|
|
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
onBeforeUnmount(() => {
|
|
|
|
|
window.removeEventListener('resize', myChart?.resize as any);
|
|
|
|
|
myChart?.dispose();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return () => (
|
|
|
|
|
<div class={"w-full h-full flex flex-col px-4 pb-3 gap-y-1"}>
|
|
|
|
|
<div class={"h-[144px] mt-[44px] flex justify-between"}>
|
|
|
|
|
<div class={"w-[360px] h-full flex justify-end items-center pr-10 relative"} style={{
|
|
|
|
|
background: 'linear-gradient(180deg,#F4FAFF 0%,#FFFFFF 100%)',
|
|
|
|
|
boxShadow: '0 2px 12px #0000001a',
|
|
|
|
|
borderRadius: '46px 8px 8px'
|
|
|
|
|
}}>
|
|
|
|
|
<div class={" left-5 -top-10 absolute bg-white rounded-full"} style={{
|
|
|
|
|
width: '174px',
|
|
|
|
|
height: '174px'
|
|
|
|
|
}}>
|
|
|
|
|
|
|
|
|
|
<Progress type="circle"
|
|
|
|
|
percent={precent1.number}
|
|
|
|
|
showInfo={false}
|
|
|
|
|
size={174}
|
|
|
|
|
strokeWidth={10}
|
|
|
|
|
strokeColor={{
|
|
|
|
|
'25%': '#76E05F',
|
|
|
|
|
'75%': '#F8E14F',
|
|
|
|
|
}}></Progress>
|
|
|
|
|
<div class={"w-[65%] bg-[#F6F6F6] shadow rounded-full h-[65%] items-center justify-center absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 flex flex-col"}>
|
|
|
|
|
<span class={"text-[#666]"}>相比昨天</span>
|
2024-11-05 15:40:58 +08:00
|
|
|
|
<span class={"font-bold text-[#333] text-[30px]"}>{(store.todayHour - store.yestodayHour) >= 0 ? "+" : ''}{(store.todayHour - store.yestodayHour) * 100}%</span>
|
2024-11-04 19:30:31 +08:00
|
|
|
|
</div>
|
|
|
|
|
</div>
|
2024-11-05 15:40:58 +08:00
|
|
|
|
<div class={"flex flex-col items-center"}>
|
2024-11-04 19:30:31 +08:00
|
|
|
|
<span class={"text-[#333] text-[16px]"}>今日专注时长</span>
|
2024-11-05 15:40:58 +08:00
|
|
|
|
<span class={"text-[#5a6eff] font-extrabold text-[36px]"}> {(store.todayHour * 0.15).toFixed(2)}
|
2024-11-04 19:30:31 +08:00
|
|
|
|
<span class={"text-[20px]"}>h</span>
|
|
|
|
|
</span>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div class={"w-[360px] h-full relative flex items-center justify-end pr-5"} style={{
|
|
|
|
|
background: 'linear-gradient(180deg,#F4FAFF 0%,#FFFFFF 100%)',
|
|
|
|
|
boxShadow: '0 2px 12px #0000001a',
|
|
|
|
|
borderRadius: '46px 8px 8px'
|
|
|
|
|
}}>
|
|
|
|
|
<div class={" left-5 -top-10 absolute bg-white rounded-full"} style={{
|
|
|
|
|
width: '174px',
|
|
|
|
|
height: '174px'
|
|
|
|
|
}}>
|
|
|
|
|
|
|
|
|
|
<Progress type="circle"
|
|
|
|
|
percent={precent2.number}
|
|
|
|
|
showInfo={false}
|
|
|
|
|
size={174}
|
|
|
|
|
strokeWidth={10}
|
|
|
|
|
strokeColor={{
|
|
|
|
|
'25%': '#DB63FB',
|
|
|
|
|
'75%': '#977BFB',
|
|
|
|
|
}}></Progress>
|
|
|
|
|
<div class={"w-[65%] bg-[#F6F6F6] shadow rounded-full h-[65%] items-center justify-center absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 flex flex-col"}>
|
|
|
|
|
<span class={"text-[#666]"}>相比昨天</span>
|
2024-11-05 15:40:58 +08:00
|
|
|
|
<span class={"font-bold text-[#333] text-[30px]"}>{(store.todayFinishTarget - store.yesFinishTarget) >= 0 ? "+" : ''}{(store.todayFinishTarget - store.yesFinishTarget) * 100}%</span>
|
2024-11-04 19:30:31 +08:00
|
|
|
|
</div>
|
|
|
|
|
</div>
|
2024-11-05 15:40:58 +08:00
|
|
|
|
<div class={"flex flex-col items-center"}>
|
|
|
|
|
<span class={"text-[#333] text-[16px]"}>今日完成目标数</span>
|
|
|
|
|
<span class={"text-[#5a6eff] font-extrabold text-[36px]"}>{store.todayFinishTarget}
|
|
|
|
|
<span class={"text-[20px]"}>个</span>
|
2024-11-04 19:30:31 +08:00
|
|
|
|
</span>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div class={"flex-1 h-0 w-full p-1 flex flex-col rounded-lg items-start justify-between relative"} style={{
|
|
|
|
|
boxShadow: '0 2px 12px #0000001a'
|
|
|
|
|
}}>
|
|
|
|
|
<span class={" absolute top-2 left-5 text-[#666666]"}>专注时长历史趋势</span>
|
|
|
|
|
<div class={"h-[750px] relative w-full"}>
|
|
|
|
|
<div ref={chart} class={"w-full h-full"} ></div>
|
|
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
<span class={"absolute bottom-3 left-5 text-[#9d6dff]"}>您的趋势向上,为了美好的明天,继续努力吧!</span>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
)
|
|
|
|
|
})
|