xlx_teacher_app/src/components/class-analysis/QuestionScoreChart.vue

130 lines
2.8 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<script lang="ts" setup>
import type * as API from '@/service/types'
import UniEcharts from 'uni-echarts'
import { computed } from 'vue'
const props = defineProps<{
data: API.StudentScoreStat[]
loading?: boolean
}>()
const emit = defineEmits<{
viewStudents: [score: number]
}>()
// 图表配置(横向柱状图)
const chartOption = computed(() => {
if (!props.data || props.data.length === 0) {
return {}
}
// 按分数排序
const sortedData = [...props.data].sort((a, b) => (a.score || 0) - (b.score || 0))
const categories = sortedData.map(item => `${item.score || 0}`)
const counts = sortedData.map(item => item.student_count || 0)
return {
tooltip: {
trigger: 'axis',
confine: true,
axisPointer: {
type: 'shadow',
},
formatter: (params: any) => {
if (!Array.isArray(params))
return ''
const param = params[0]
// 使用 \n 换行而不是 <br/>
return `${param.axisValue}\n${param.marker} 人数: ${param.value}`
},
},
grid: {
left: 50,
right: 30,
bottom: 30,
top: 20,
containLabel: false,
},
// 横向柱状图xAxis 为数值轴yAxis 为类目轴
xAxis: {
type: 'value',
name: '人数',
nameTextStyle: {
fontSize: 11,
},
axisLabel: {
fontSize: 10,
},
splitLine: {
lineStyle: {
type: 'dashed',
color: '#eeeeee',
},
},
},
yAxis: {
type: 'category',
data: categories,
axisLabel: {
fontSize: 10,
},
axisLine: {
lineStyle: {
color: '#cccccc',
},
},
// 反转 Y 轴,让分数从上到下递增
inverse: true,
},
series: [
{
name: '人数',
type: 'bar',
data: counts,
itemStyle: {
color: '#3b82f6',
},
barMaxWidth: 30,
label: {
show: true,
position: 'right',
fontSize: 10,
formatter: '{c}人',
},
},
],
}
})
const showChart = computed(() => {
return !props.loading && props.data && props.data.length > 0
})
</script>
<template>
<view class="score-chart">
<!-- 图表 -->
<view v-if="showChart" class="chart-container">
<uni-echarts :option="chartOption" custom-class="chart" />
</view>
<!-- 加载状态 -->
<view v-if="loading" class="h-60 flex items-center justify-center">
<wd-loading size="24" />
</view>
<!-- 暂无数据 -->
<view v-if="!loading && (!data || data.length === 0)" class="py-8 text-center">
<text class="text-sm text-gray-500">暂无数据</text>
</view>
</view>
</template>
<style scoped>
.chart {
width: 100%;
height: 250px;
}
</style>