AIManage/src/views/simulationEvaluation/reportDesc.vue

390 lines
14 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="Accuracy(准确度)" align="left" prop="accuracy" />
<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 : 12">
<charts :id="'reportChart1-' + idx" width="100%" :height="calcChartHeight(it)"
:render="opt => renderChart1(it, 'roc')"></charts>
</el-col>
<div :class=" info.isPrint && it.classes.length>20?'print-page':''"></div>
<el-col :span="info.isPrint || it.classes.length>20 ? 24 : 12">
<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-column label="IDF1" align="left" prop="idf1" />
</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 label="数据集1名称" align="left" prop="data1" />
<el-table-column label="数据集1的mAP" align="left" prop="data1_map" />
<el-table-column label="数据集2名称" align="left" prop="data2" />
<el-table-column label="数据集2的mAP" align="left" prop="data2_map" />
<el-table-column label="mAP下降率" align="left" prop="map_decrease" />
</el-table>
</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: [],
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 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: ['0.0', '0.1', '0.2', '0.3', '0.4', '0.5', '0.6', '0.7', "0.8", "0.9", "1.0"], // 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 classes = it.classes || [];
classes.forEach(d => {
rocs.push({
name: d.class_name, data: d.roc, type: 'line'
});
rps.push({
name: d.class_name, data: d.pr, type: 'line'
});
names.push(d.class_name)
});
return {
rocs, rps, names
}
}
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 || null
info.robustness = obj ? [obj] : []
});
}
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>