Files
it/frontend/src/components/PerformanceCharts.vue
2025-11-03 17:03:57 +08:00

240 lines
5.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.

<template>
<div class="performance-charts">
<!-- 性能历史趋势图 -->
<div class="bg-white rounded-lg shadow-md p-6 mb-6">
<h2 class="text-lg font-semibold mb-4">性能历史趋势</h2>
<div v-if="!performanceHistory || performanceHistory.length === 0" class="h-64 flex items-center justify-center bg-gray-50 rounded-lg">
<p class="text-gray-500">暂无历史数据</p>
</div>
<div v-else class="h-80">
<v-chart
class="h-full w-full"
:option="historyChartOption"
:loading="loading"
autoresize
/>
</div>
</div>
<!-- 性能指标雷达图 -->
<div class="bg-white rounded-lg shadow-md p-6">
<h2 class="text-lg font-semibold mb-4">性能指标雷达图</h2>
<div v-if="!product || !product.performanceScores || product.performanceScores.length === 0" class="h-64 flex items-center justify-center bg-gray-50 rounded-lg">
<p class="text-gray-500">暂无性能数据</p>
</div>
<div v-else class="h-80">
<v-chart
class="h-full w-full"
:option="radarChartOption"
:loading="loading"
autoresize
/>
</div>
</div>
</div>
</template>
<script>
import { ref, computed, watch } from 'vue'
import { use } from 'echarts/core'
import { CanvasRenderer } from 'echarts/renderers'
import { LineChart, RadarChart } from 'echarts/charts'
import {
TitleComponent,
TooltipComponent,
LegendComponent,
GridComponent,
RadarComponent
} from 'echarts/components'
import VChart from 'vue-echarts'
// 注册必要的组件
use([
CanvasRenderer,
LineChart,
RadarChart,
TitleComponent,
TooltipComponent,
LegendComponent,
GridComponent,
RadarComponent
])
export default {
name: 'PerformanceCharts',
components: {
VChart
},
props: {
product: {
type: Object,
required: true
},
performanceHistory: {
type: Array,
default: () => []
},
loading: {
type: Boolean,
default: false
}
},
setup(props) {
// 性能历史趋势图配置
const historyChartOption = computed(() => {
if (!props.performanceHistory || props.performanceHistory.length === 0) {
return {}
}
// 准备数据
const dates = []
const scores = []
props.performanceHistory.forEach(item => {
dates.push(new Date(item.recordDate).toLocaleDateString())
scores.push(item.score)
})
return {
title: {
text: `${props.product.name} 性能趋势`,
left: 'center'
},
tooltip: {
trigger: 'axis',
formatter: function(params) {
return `${params[0].axisValue}<br/>性能分数: ${params[0].value}`
}
},
xAxis: {
type: 'category',
data: dates,
axisLabel: {
rotate: 45
}
},
yAxis: {
type: 'value',
name: '性能分数'
},
series: [
{
name: '性能分数',
type: 'line',
data: scores,
smooth: true,
symbolSize: 8,
lineStyle: {
width: 3,
color: '#409EFF'
},
itemStyle: {
color: '#409EFF'
},
areaStyle: {
color: {
type: 'linear',
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{ offset: 0, color: 'rgba(64, 158, 255, 0.5)' },
{ offset: 1, color: 'rgba(64, 158, 255, 0.1)' }
]
}
}
}
],
grid: {
left: '3%',
right: '4%',
bottom: '15%',
containLabel: true
}
}
})
// 性能指标雷达图配置
const radarChartOption = computed(() => {
if (!props.product || !props.product.performanceScores || props.product.performanceScores.length === 0) {
return {}
}
// 准备雷达图数据
const indicators = []
const values = []
// 定义常见的基准测试及其最大值
const benchmarkMaxValues = {
'Geekbench Single-Core': 3000,
'Geekbench Multi-Core': 20000,
'3DMark Time Spy': 20000,
'3DMark Fire Strike': 30000,
'AnTuTu': 1000000,
'PCMark': 8000,
'Cinebench R23': 30000,
'Cinebench R20': 8000
}
props.product.performanceScores.forEach(score => {
const benchmarkName = score.benchmarkName
const maxValue = benchmarkMaxValues[benchmarkName] || 100
indicators.push({
name: benchmarkName,
max: maxValue
})
// 将分数转换为百分比0-100
const percentage = Math.min(100, (score.score / maxValue) * 100)
values.push(percentage)
})
return {
title: {
text: `${props.product.name} 性能指标`,
left: 'center'
},
tooltip: {
trigger: 'item'
},
radar: {
indicator: indicators,
center: ['50%', '55%'],
radius: '70%'
},
series: [
{
name: '性能指标',
type: 'radar',
data: [
{
value: values,
name: props.product.name,
itemStyle: {
color: '#409EFF'
},
areaStyle: {
color: 'rgba(64, 158, 255, 0.3)'
}
}
]
}
]
}
})
return {
historyChartOption,
radarChartOption
}
}
}
</script>
<style scoped>
.performance-charts {
width: 100%;
}
</style>