Files
sweet-hut-ui/src/components/Health/HealthChart.vue

91 lines
3.2 KiB
Vue

<template>
<div class="bill-chart common-chart"
v-loading="healthStore.isLoading"
element-loading-text="正在加载中...">
<div class="chart-container card-item">
<div class="content">
<span class="title">📊体重趋势</span>
</div>
<div class="chart" ref="weightDailyChartRef"/>
</div>
<div class="chart-container card-item">
<div class="content">
<span class="title">📊运动时长统计</span>
</div>
<div class="chart" ref="healthDurationChartRef"/>
</div>
<div class="chart-container card-item">
<div class="content">
<span class="title">📊运动类别统计</span>
</div>
<div class="chart" ref="healthCategoryChartRef"/>
</div>
</div>
</template>
<script setup lang="ts">
import { onMounted, ref, watch } from 'vue'
import * as echarts from 'echarts'
import { lineChartOptions, barChartOptions, pieChartOptions } from 'vue3-common/utils/eChartsUtil'
import { useHealthStore } from '@/store/health'
import { useAppStore } from '@/store/app.ts'
const healthStore = useHealthStore()
const appStore = useAppStore()
const weightDailyChartRef = ref<HTMLElement>()
const healthDurationChartRef = ref<HTMLElement>()
const healthCategoryChartRef = ref<HTMLElement>()
let weightDailyChart: echarts.ECharts
let healthDurationChart: echarts.ECharts
let healthCategoryChart: echarts.ECharts
watch(() => healthStore.isRefresh, () => {
updateChart()
})
onMounted(() => {
weightDailyChart = echarts.init(weightDailyChartRef.value as HTMLElement, appStore.isDark ? 'dark' : null)
healthDurationChart = echarts.init(healthDurationChartRef.value as HTMLElement, appStore.isDark ? 'dark' : null)
healthCategoryChart = echarts.init(healthCategoryChartRef.value as HTMLElement, appStore.isDark ? 'dark' : null)
})
const updateChart = () => {
const MAX_CATEGORY_COUNT = 5
// 体重趋势统计图
const weightXAxis = healthStore.healthRecordList.map((item) => item.date).reverse()
const weightYAxis = healthStore.healthRecordList.map((item) => item.weight).reverse()
weightDailyChart.setOption(lineChartOptions('日期', weightXAxis, '体重(千克)', weightYAxis))
weightDailyChart.setOption({
yAxis: {
min: 60,
max: 90
}
})
// 运动量统计图
const sportRecordList = healthStore.healthRecordList.filter((item) => item.sportProject !== '')
const durationXAxis = sportRecordList.map((item) => item.date).reverse()
const durationYAxis = sportRecordList.map((item) => item.sportDuration).reverse()
healthDurationChart.setOption(barChartOptions('日期', durationXAxis, '时间(分钟)', durationYAxis))
// 类别统计图
const healthCategoryList = healthStore.healthRecordList.reduce((acc, item) => {
if (item.sportProject && item.sportDuration > 0) {
const existing = acc.find((project) => project.name === item.sportProject)
if (existing) {
existing.value += item.sportDuration
} else {
acc.push({ name: item.sportProject, value: item.sportDuration })
}
}
return acc
}, [])
healthCategoryChart.setOption(pieChartOptions('名称', '分钟', healthCategoryList.slice(0, MAX_CATEGORY_COUNT)))
}
</script>