202 lines
8.5 KiB
TypeScript
202 lines
8.5 KiB
TypeScript
import { computed, defineComponent, onBeforeUnmount, onMounted, reactive, ref } from "vue";
|
||
// 引入 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>
|
||
<span class={"font-bold text-[#333] text-[30px]"}>{(store.todayHour - store.yestodayHour) >= 0 ? "+" : ''}{(store.todayHour - store.yestodayHour) * 100}%</span>
|
||
</div>
|
||
</div>
|
||
<div class={"flex flex-col items-center"}>
|
||
<span class={"text-[#333] text-[16px]"}>今日专注时长</span>
|
||
<span class={"text-[#5a6eff] font-extrabold text-[36px]"}> {(store.todayHour * 0.15).toFixed(2)}
|
||
<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>
|
||
<span class={"font-bold text-[#333] text-[30px]"}>{(store.todayFinishTarget - store.yesFinishTarget) >= 0 ? "+" : ''}{(store.todayFinishTarget - store.yesFinishTarget) * 100}%</span>
|
||
</div>
|
||
</div>
|
||
<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>
|
||
</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>
|
||
)
|
||
}) |