Files
skt-vuetify-templates/src/components/SKAnalysis.vue
T

112 lines
3.1 KiB
Vue

<template>
<v-sheet class="bg-surface" v-bind="$attrs">
<!-- Top Stats Cards -->
<v-row class="mb-4">
<v-col v-for="(stat, index) in props.stats" :key="index" cols="12" md="3" sm="6">
<AnalysisStatsCard
:color="stat.color"
:icon="stat.icon"
:label="stat.label"
:title="stat.title"
:total="stat.total"
:value="stat.value"
/>
</v-col>
</v-row>
<!-- Main Trend Chart (Sparkline Area) -->
<v-row class="mb-4">
<v-col cols="12">
<AnalysisTrendChart
:active-filter="activeFilter"
:data="props.trendData"
:filters="props.trendFilters"
:title="props.trendTitle"
@filter-change="activeFilter = $event"
/>
</v-col>
</v-row>
<!-- Bottom Charts Grid -->
<v-row>
<!-- Chart 1: Bar Chart (Proxy for Radar/Distribution) -->
<v-col cols="12" md="4">
<AnalysisBarChart :data="props.barData" :title="props.chart1Title" />
</v-col>
<!-- Chart 2: Donut Chart (Source) -->
<v-col cols="12" md="4">
<AnalysisPieChart :data="props.pie1Data" :title="props.chart2Title" />
</v-col>
<!-- Chart 3: Donut Chart (Distribution) -->
<v-col cols="12" md="4">
<AnalysisDonutChart :data="props.pie2Data" :title="props.chart3Title" />
</v-col>
</v-row>
</v-sheet>
</template>
<script setup lang="ts">
import { mdiSchool } from '@mdi/js'
import { ref } from 'vue'
import AnalysisBarChart from './base/analysis/AnalysisBarChart.vue'
import AnalysisDonutChart from './base/analysis/AnalysisDonutChart.vue'
import AnalysisPieChart from './base/analysis/AnalysisPieChart.vue'
import AnalysisStatsCard from './base/analysis/AnalysisStatsCard.vue'
import AnalysisTrendChart from './base/analysis/AnalysisTrendChart.vue'
interface StatsItem {
title: string
value: string | number
label: string
total: string | number
icon: string
color: string
}
interface BarDataItem {
label: string
value: number
color: string
}
interface PieData {
value: number
label: string
color: string
}
interface DonutData extends PieData {
icon: string
}
const props = defineProps({
// Stats Cards Data
stats: { type: Array as () => StatsItem[], default: () => [] },
// Trend Chart
trendTitle: { type: String, default: '流量趨勢' },
trendData: { type: Array as () => number[], default: () => [] },
trendFilters: { type: Array as () => string[], default: () => ['流量', '訪問量'] },
// Chart Titles
chart1Title: { type: String, default: '核心素養' },
chart2Title: { type: String, default: '訪問來源' },
chart3Title: { type: String, default: '成績分佈' },
// Data for Charts
barData: { type: Array as () => BarDataItem[], default: () => [] },
pie1Data: {
type: Object as () => PieData,
default: () => ({ value: 75, label: '直接訪問', color: 'primary' }),
},
pie2Data: {
type: Object as () => DonutData,
default: () => ({ value: 65, label: '及格率', color: 'success', icon: mdiSchool }),
},
})
const activeFilter = ref(props.trendFilters[0] || '')
</script>