AIManage/src/views/simulationEvaluation/reportDesc.vue

529 lines
19 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<div class="app-container simulation-report-desc" v-loading="loading">
<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>
<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" />
<el-table-column label="Precision(精确度)" align="left" prop="precision" />
<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>
<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">
<charts :id="'reportChart2-' + idx" width="100%" :height="calcChartHeight(it)"
: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" />
<el-table-column label="TM(跟踪轨迹)" align="left" prop="mt" />
<el-table-column label="ML(丢失轨迹)" align="left" prop="ml" />
<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>
</div>
</div>
<template v-if="info.robustness && info.robustness.length > 0">
<div class="sub-title">鲁棒性评估报告</div>
<el-table :data="info.robustness" 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-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>
</template>
</div>
<el-card class="card-footer">
<el-button type="primary" @click="doPrint"></el-button>
<el-button type="primary" @click="doExport"></el-button>
<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'
import html2canvas from 'html2canvas';
import { useDateFormat } from "@vueuse/core";
const route = useRoute()
const router = useRouter();
const info = reactive({
report: {},
taskList: [],
thresholds: null,
extra_evaluation_type: '',
tasks: [],
reportType: '',
robustness: [],
robustnessMapDecrease: '',
horizontal_comparison:[],
isPrint: false,
elPrint: 0,
})
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');
}
return tmp;
}
const doExport = async () => {
try {
let dom = document.querySelector("#print_simulation_report_desc");
const canvas = await html2canvas(dom, {
allowTaint: true,
useCORS: true,
});
const img = canvas.toDataURL('image/png');
const link = document.createElement('a');
link.href = img;
link.setAttribute('download', info.report.report_name + useDateFormat(new Date(), "YYYYMMDDHHmmss").value + '.png');
link.click();
} catch (e) {
ElMessage.error("导出图片失败!");
console.error("导出图片失败!", e);
}
}
function goBack() {
router.push({ path: "/simulationEvaluation/reportList" });
}
function doPrint() {
document.querySelector("html").classList.add("report-print");
info.isPrint = true;
info.elPrint++;
loading.value = true;
setTimeout(() => {
loading.value = false;
setTimeout(() => {
window.print();
document.querySelector("html").classList.remove("report-print");
info.isPrint = false;
info.elPrint++;
}, 100);
}, 2000);
}
const doDelete = () => {
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("删除失败!");
}
});
});
}
//硬件横向对比评估图
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;
}
function renderChart1(data, type) {
let chartInfo = data.chartsInfo
let gridTop = info.isPrint ? 20 * (data.classes.length / 5) : 20 * (data.classes.length / 10);
let opt = {
legend: {
left: '10%', right: '20%',
data: chartInfo.names
},
grid: { top: gridTop, },
xAxis: [{
type: 'category', // 还有其他的type可以去官网喵两眼哦
data: chartInfo.labels, // x轴数据
}],
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,
label: {
show: true,
position: 'top'
}
}
})
}
return opt;
}
function initTaskChart(it) {
let rocs = [];
let rps = [];
let names = [];
let labels = [];
let classes = it.classes || [];
labels = classes.length > 0 ? classes[0].pr.map(it => it[0]) : [];
classes.forEach(d => {
rocs.push({
name: d.class_name, data: d.roc, type: 'line'
});
rps.push({
name: d.class_name, data: d.pr.map(it => it[1]), type: 'line'
});
names.push(d.class_name)
});
return {
rocs, rps, names, labels
}
}
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 || '';
info.tasks = (info.report.report_data?.tasks || info.report.report_data?.report_data?.tasks || []).map(it => {
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);
if (it.targets && it.targets.length > 0) {
info.reportType = "tracking";
} else {
info.reportType = "other"
}
return it;
});
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
});
}
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;
}
}
.print-page {
page-break-after: always;
}
.card-footer {
position: fixed;
width: calc(100% - 215px);
bottom: 0px;
.el-card__body {
padding: 10px;
.el-pagination {
justify-content: end;
}
}
}
}
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 {
.el-scrollbar__view {
vertical-align: unset !important;
}
.el-table {
table {
width: unset !important;
}
}
}
}
}
}
}
}
}
}
.el-header {
display: none;
}
.el-aside {
display: none;
}
.card-footer {
display: none;
}
}
}
@page {
margin: 20px;
}
</style>