AIManage/src/views/simulationEvaluation/reportDesc.vue

529 lines
19 KiB
Vue
Raw Normal View History

2024-09-15 16:27:31 +08:00
<template>
2024-09-18 21:13:30 +08:00
<div class="app-container simulation-report-desc" v-loading="loading">
2024-09-15 16:27:31 +08:00
<div style="background-color: #fff;padding:20px;margin-bottom: 60px;" id="print_simulation_report_desc">
<div class="report-name">{{ info.report.report_name }}</div>
<div class="report-info">
<table>
<tr>
<td style="width:100px;" align="right"> 报告创建人:</td>
<td>{{ info.report.user_name }}</td>
</tr>
<tr>
<td align="right"> 报告生成时间:</td>
<td>{{ info.report.create_time }}</td>
</tr>
<tr>
<td align="right"> 报告说明:</td>
<td>{{ info.report.report_desc }}</td>
</tr>
</table>
</div>
<div class="div-line"></div>
<div class="sub-title">推理任务列表</div>
<el-table :data="info.taskList" stripe style="margin-top:10px;">
<el-table-column label="任务名称" align="left" prop="task_name" />
<el-table-column label="模型名称" align="left" prop="model_name" />
<el-table-column label="网络类型" align="left" prop="modl_sub_type" />
<el-table-column label="互联名称" align="left" prop="connection_name" />
<el-table-column label="数据集名称" align="left" prop="dataset_name" />
<el-table-column label="图片数量" align="left" prop="image_count" />
<el-table-column label="设备名称" align="left" prop="device_name" />
<el-table-column label="设备处理器" align="left" prop="hardware_chip" />
</el-table>
<div class="task-lists" v-if="info.tasks && info.tasks.length > 0">
<div v-for="(it, idx) in info.tasks" :key="idx">
<div class="sub-title">我的任务{{ idx + 1 }}的评估报告</div>
2024-09-16 00:25:35 +08:00
<template v-if="info.reportType == 'other'">
<div v-if="info.thresholds" class="info-thresholds">
<span>置信度阈值</span>
<span>{{ info.thresholds.score_threshold }}</span>
<span style="margin-left:10px;">nms阈值:</span>
<span>{{ info.thresholds.nms_threshold }}</span>
</div>
<el-table :data="it.classes" stripe style="margin-top:10px;">
<el-table-column label="类别名称" align="left" prop="class_name" />
2024-09-28 13:35:18 +08:00
<el-table-column label="Precision(精确度)" align="left" prop="precision" />
2024-09-16 00:25:35 +08:00
<el-table-column label="Recall(召回率)" align="left" prop="recall" />
<el-table-column label="F1-score" align="left" prop="f1_score" />
<el-table-column label="AP" align="left" prop="ap" />
</el-table>
<el-table :data="it.datas" stripe style="margin-top:20px;">
<el-table-column label="mAP" align="left" prop="map" />
<el-table-column label="Micro F1" align="left" prop="micro_f1" />
<el-table-column label="Macro F1" align="left" prop="macro_f1" />
<el-table-column label="加权F1-Scroe" align="left" prop="weight_f1" />
<el-table-column label="平均推理时间" align="left" prop="inference_time" />
<el-table-column label="系统延迟时间" align="left" prop="system_delay" />
</el-table>
<div class="print-page"></div>
2024-09-28 13:35:18 +08:00
<el-row class="report-chart1" style="margin-top:20px;" :key="info.elPrint"
:style="info.isPrint ? 'width:18cm;' : ''">
<el-col :span="info.isPrint || it.classes.length > 20 ? 24 : 24">
2024-09-18 21:13:30 +08:00
<charts :id="'reportChart2-' + idx" width="100%" :height="calcChartHeight(it)"
2024-09-16 00:25:35 +08:00
:render="opt => renderChart1(it, 'rp')"></charts>
</el-col>
</el-row>
</template>
<template v-else>
<el-table :data="it.targets" stripe style="margin-top:10px;">
<el-table-column label="目标序号" align="left" prop="index" />
<el-table-column label="IDSW" align="left" prop="idsw" />
2024-09-28 13:35:18 +08:00
<el-table-column label="TM(跟踪轨迹)" align="left" prop="mt" />
<el-table-column label="ML(丢失轨迹)" align="left" prop="ml" />
2024-09-16 00:25:35 +08:00
<el-table-column label="FM(打断次数)" align="left" prop="fm" />
</el-table>
<div class="info-thresholds" style="margin-top: 10px;line-height: 24px;">
<div> <span>MOTA跟踪准确度</span>
<span>{{ it.mota }}</span>
</div>
<div> <span>平均推理时间:</span>
<span>{{ it.inference_time }}ms</span>
</div>
<div><span>系统延迟时间:</span>
<span>{{ it.system_delay }}ms</span>
</div>
</div>
</template>
2024-09-15 16:27:31 +08:00
</div>
</div>
2024-09-16 00:25:35 +08:00
<template v-if="info.robustness && info.robustness.length > 0">
<div class="sub-title">鲁棒性评估报告</div>
<el-table :data="info.robustness" stripe style="margin-top:10px;">
2024-09-28 13:35:18 +08:00
<el-table-column type="index" width="80" label="序号" />
<el-table-column label="模型名称" align="left" prop="model_name" />
<el-table-column label="数据集名称" align="left" prop="database_name" />
<el-table-column label="Micro F1" align="left" prop="micro_f1" />
<el-table-column label="Macro F1" align="left" prop="macro_f1" />
<el-table-column label="加权F1-Score" align="left" prop="weight_f1" />
<el-table-column label="mAP" align="left" prop="map" />
<el-table-column label="平均推理时间" align="left" prop="inference_time" />
<el-table-column label="mAP变化率" align="left">
<template #default="scope">
{{ scope.$index == 0 ? '----' : info.robustnessMapDecrease + '%' }}
</template>
</el-table-column>
2024-09-16 00:25:35 +08:00
</el-table>
2024-09-28 13:35:18 +08:00
<div style="margin-top:20px;">
<charts id="reportChart3-robustness" width="100%" height="400px" :render="renderChar3">
</charts>
</div>
</template>
<template v-if="info.horizontal_comparison && info.horizontal_comparison.length>0">
<div class="sub-title">硬件横向对比评估报告</div>
<el-table :data="info.horizontal_comparison" stripe style="margin-top:10px;">
<el-table-column type="index" width="80" label="序号" />
<el-table-column label="设备名称" align="left" prop="model_name" />
<el-table-column label="设备处理器" align="left" prop="database_name" />
<el-table-column label="Micro F1" align="left" prop="micro_f1" />
<el-table-column label="Macro F1" align="left" prop="macro_f1" />
<el-table-column label="加权F1-Score" align="left" prop="weight_f1" />
<el-table-column label="mAP" align="left" prop="map" />
<el-table-column label="平均推理时间" align="left" prop="inference_time" />
<el-table-column label="mAP变化率" align="left">
<template #default="scope">
{{ scope.$index == 0 ? '----' : info.robustnessMapDecrease + '%' }}
</template>
</el-table-column>
</el-table>
<div style="margin-top:20px;">
<charts id="reportChart3-comparison" width="100%" height="400px" :render="renderChar4">
</charts>
</div>
2024-09-16 00:25:35 +08:00
</template>
2024-09-15 16:27:31 +08:00
</div>
<el-card class="card-footer">
<el-button type="primary" @click="doPrint"></el-button>
2024-09-16 00:25:35 +08:00
<el-button type="primary" @click="doExport"></el-button>
2024-09-15 16:27:31 +08:00
<el-button type="primary" @click="doDelete"></el-button>
<el-button @click="goBack"></el-button>
</el-card>
</div>
</template>
<script setup>
import ReportApi from '@/api/report'
import charts from './components/charts.vue'
2024-09-16 00:25:35 +08:00
import html2canvas from 'html2canvas';
import { useDateFormat } from "@vueuse/core";
2024-09-15 16:27:31 +08:00
const route = useRoute()
const router = useRouter();
const info = reactive({
report: {},
taskList: [],
thresholds: null,
extra_evaluation_type: '',
2024-09-16 00:25:35 +08:00
tasks: [],
reportType: '',
2024-09-16 11:11:45 +08:00
robustness: [],
2024-09-28 13:35:18 +08:00
robustnessMapDecrease: '',
horizontal_comparison:[],
2024-09-16 11:11:45 +08:00
isPrint: false,
elPrint: 0,
2024-09-15 16:27:31 +08:00
})
2024-09-28 13:35:18 +08:00
const loading = ref(false)
const calcChartHeight = it => {
let tmp = it.classes.length <= 20 ? '400px' : ((it.classes.length / 10 - 2) * 40 + 400 + 'px');
if (info.isPrint) {
tmp = it.classes.length <= 20 ? '400px' : ((it.classes.length / 5 - 2) * 30 + 400 + 'px');
2024-09-18 21:13:30 +08:00
}
return tmp;
}
2024-09-16 11:11:45 +08:00
const doExport = async () => {
try {
let dom = document.querySelector("#print_simulation_report_desc");
const canvas = await html2canvas(dom, {
allowTaint: true,
useCORS: true,
});
2024-09-16 00:25:35 +08:00
const img = canvas.toDataURL('image/png');
const link = document.createElement('a');
link.href = img;
2024-09-16 11:11:45 +08:00
link.setAttribute('download', info.report.report_name + useDateFormat(new Date(), "YYYYMMDDHHmmss").value + '.png');
2024-09-16 00:25:35 +08:00
link.click();
2024-09-16 11:11:45 +08:00
} catch (e) {
2024-09-16 00:25:35 +08:00
ElMessage.error("导出图片失败!");
2024-09-16 11:11:45 +08:00
console.error("导出图片失败!", e);
2024-09-16 00:25:35 +08:00
}
2024-09-15 16:27:31 +08:00
}
2024-09-16 00:25:35 +08:00
function goBack() {
router.push({ path: "/simulationEvaluation/reportList" });
}
2024-09-28 13:35:18 +08:00
function doPrint() {
2024-09-16 00:25:35 +08:00
document.querySelector("html").classList.add("report-print");
2024-09-16 11:11:45 +08:00
info.isPrint = true;
info.elPrint++;
2024-09-28 13:35:18 +08:00
loading.value = true;
setTimeout(() => {
loading.value = false;
setTimeout(() => {
2024-09-18 21:13:30 +08:00
window.print();
document.querySelector("html").classList.remove("report-print");
info.isPrint = false;
info.elPrint++;
2024-09-28 13:35:18 +08:00
}, 100);
2024-09-18 21:13:30 +08:00
}, 2000);
2024-09-15 16:27:31 +08:00
}
2024-09-16 11:11:45 +08:00
2024-09-15 16:27:31 +08:00
const doDelete = () => {
2024-09-16 00:25:35 +08:00
let id = route.query.id;
ElMessageBox.confirm("确认删除?", "警告", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
}).then(function () {
ReportApi.deleteReport(id).then(d => {
if (d.data.code == 0) {
ElMessage.success("删除成功!");
goBack();
} else {
ElMessage.error("删除失败!");
}
});
});
2024-09-15 16:27:31 +08:00
}
2024-09-28 13:35:18 +08:00
//硬件横向对比评估图
function renderChar4(){
let datas = info.horizontal_comparison;
let maxTime = 0;
let seriesData = [];
datas.forEach(d => {
if (d.inference_time > maxTime) {
maxTime = d.inference_time;
}
seriesData.push({
name: d.database_name,
value: [d.micro_f1, d.macro_f1, d.weight_f1, d.map, d.inference_time]
})
});
let opt = {
title: {
text: '硬件横向对比评估图'
},
legend: {
x: 'center',
data: datas.map(d => d.database_name)
},
tooltip: {
trigger: 'axis'
},
calculable: true,
polar: [
{
indicator: [
{ text: 'Micro F1', max: 1 },
{ text: 'Macro F1', max: 1 },
{ text: '加权F1-Score', max: 1 },
{ text: 'mAP', max: 1 },
{ text: '平均推理时间', max: maxTime }
],
radius: 130
}
],
series: [{
type: 'radar',
itemStyle: {
normal: {
areaStyle: {
type: 'default'
}
}
},
data: seriesData
}]
}
return opt;
}
//鲁棒性评估图
function renderChar3() {
let datas = info.robustness;
let maxTime = 0;
let seriesData = [];
datas.forEach(d => {
if (d.inference_time > maxTime) {
maxTime = d.inference_time;
}
seriesData.push({
name: d.database_name,
value: [d.micro_f1, d.macro_f1, d.weight_f1, d.map, d.inference_time]
})
});
let opt = {
title: {
text: '鲁棒性评估图'
},
legend: {
x: 'center',
data: datas.map(d => d.database_name)
},
tooltip: {
trigger: 'axis'
},
calculable: true,
polar: [
{
indicator: [
{ text: 'Micro F1', max: 1 },
{ text: 'Macro F1', max: 1 },
{ text: '加权F1-Score', max: 1 },
{ text: 'mAP', max: 1 },
{ text: '平均推理时间', max: maxTime }
],
radius: 130
}
],
series: [{
type: 'radar',
itemStyle: {
normal: {
areaStyle: {
type: 'default'
}
}
},
data: seriesData
}]
}
return opt;
}
2024-09-15 16:27:31 +08:00
function renderChart1(data, type) {
let chartInfo = data.chartsInfo
2024-09-28 13:35:18 +08:00
let gridTop = info.isPrint ? 20 * (data.classes.length / 5) : 20 * (data.classes.length / 10);
2024-09-15 16:27:31 +08:00
let opt = {
2024-09-16 00:25:35 +08:00
legend: {
2024-09-18 21:13:30 +08:00
left: '10%', right: '20%',
2024-09-16 00:25:35 +08:00
data: chartInfo.names
},
2024-09-18 21:13:30 +08:00
grid: { top: gridTop, },
2024-09-15 16:27:31 +08:00
xAxis: [{
type: 'category', // 还有其他的type可以去官网喵两眼哦
2024-09-28 13:35:18 +08:00
data: chartInfo.labels, // x轴数据
2024-09-15 16:27:31 +08:00
}],
yAxis: [{
type: 'value',
name: type == 'roc' ? "ROC曲线" : "RP曲线"
}],
tooltip: {
trigger: 'axis'
},
series: (type == "roc" ? chartInfo.rocs : chartInfo.rps).map(it => {
return {
name: it.name,
type: it.type,
data: it.data,
2024-09-16 00:25:35 +08:00
label: {
show: true,
position: 'top'
}
2024-09-15 16:27:31 +08:00
}
})
}
return opt;
}
function initTaskChart(it) {
let rocs = [];
let rps = [];
let names = [];
2024-09-28 13:35:18 +08:00
let labels = [];
2024-09-15 16:27:31 +08:00
let classes = it.classes || [];
2024-09-28 13:35:18 +08:00
labels = classes.length > 0 ? classes[0].pr.map(it => it[0]) : [];
classes.forEach(d => {
2024-09-15 16:27:31 +08:00
rocs.push({
name: d.class_name, data: d.roc, type: 'line'
});
rps.push({
2024-09-28 13:35:18 +08:00
name: d.class_name, data: d.pr.map(it => it[1]), type: 'line'
2024-09-15 16:27:31 +08:00
});
names.push(d.class_name)
});
return {
2024-09-28 13:35:18 +08:00
rocs, rps, names, labels
2024-09-15 16:27:31 +08:00
}
}
function loadData() {
let id = route.query.id;
ReportApi.getReport(id).then(d => {
info.report = d.data.data || {};
info.taskList = info.report.task_list || []
info.thresholds = info.report.report_parameters?.report_parameters?.thresholds || null
info.extra_evaluation_type = info.report.report_parameters?.report_parameters?.extra_evaluation_type || '';
2024-09-16 00:25:35 +08:00
info.tasks = (info.report.report_data?.tasks || info.report.report_data?.report_data?.tasks || []).map(it => {
2024-09-15 16:27:31 +08:00
it.datas = [{
inference_time: it.inference_time, macro_f1: it.macro_f1, map: it.map, micro_f1: it.micro_f1,
system_delay: it.system_delay, task_id: it.task_id, weight_f1: it.weight_f1
}];
it.chartsInfo = initTaskChart(it);
2024-09-16 00:25:35 +08:00
if (it.targets && it.targets.length > 0) {
info.reportType = "tracking";
} else {
info.reportType = "other"
}
2024-09-15 16:27:31 +08:00
return it;
});
2024-09-28 13:35:18 +08:00
let obj = info.report?.report_data?.robustness?.tasks || null
info.robustness = (obj ? obj : []);
info.robustnessMapDecrease = info.report?.report_data?.robustness?.map_decrease;
info.horizontal_comparison=info.report?.report_data?.horizontal_comparison
2024-09-15 16:27:31 +08:00
});
}
onMounted(loadData);
</script>
<style lang='scss'>
.simulation-report-desc {
font-size: 12px;
.report-name {
font-size: 20px;
text-align: center;
font-weight: bold;
}
.sub-title {
font-size: 14px;
font-weight: bold;
text-align: center;
}
.div-line {
margin: 10px 0px;
height: 2px;
background-color: #aaa;
}
.task-lists {
margin-top: 20px;
.info-thresholds {
font-weight: bold;
}
}
2024-09-16 00:25:35 +08:00
.print-page {
page-break-after: always;
}
.card-footer {
2024-09-15 16:27:31 +08:00
position: fixed;
width: calc(100% - 215px);
bottom: 0px;
.el-card__body {
padding: 10px;
.el-pagination {
justify-content: end;
}
2024-09-16 00:25:35 +08:00
}
}
}
html.report-print {
height: auto;
body {
#app {
height: auto;
min-height: unset;
.main-container {
min-height: unset;
.center-container {
display: block;
.el-main {
.app-main {
min-height: unset;
.el-scrollbar {
height: unset;
.el-scrollbar__wrap {
height: unset !important;
.simulation-report-desc {
2024-09-16 11:11:45 +08:00
.el-scrollbar__view {
2024-09-16 10:36:17 +08:00
vertical-align: unset !important;
}
2024-09-16 11:11:45 +08:00
2024-09-16 00:25:35 +08:00
.el-table {
table {
2024-09-16 10:36:17 +08:00
width: unset !important;
2024-09-16 00:25:35 +08:00
}
}
}
}
}
}
}
}
}
}
.el-header {
display: none;
}
.el-aside {
display: none;
}
.card-footer {
display: none;
}
2024-09-15 16:27:31 +08:00
}
}
2024-09-16 00:25:35 +08:00
@page {
margin: 20px;
}
2024-09-15 16:27:31 +08:00
</style>