修改Test图展示
This commit is contained in:
parent
3c47855f3f
commit
737d091b75
|
|
@ -4,13 +4,6 @@
|
||||||
<div class="list-box">
|
<div class="list-box">
|
||||||
<div class="filter-wrap">
|
<div class="filter-wrap">
|
||||||
<el-form :inline="true" :model="queryParams" class="demo-form-inline">
|
<el-form :inline="true" :model="queryParams" class="demo-form-inline">
|
||||||
<!--<el-form-item label="Activity reference time">
|
|
||||||
<el-date-picker v-model="queryParams.acquisition_start_begin" type="datetime" placeholder="选择日期时间" class="dark-date-picker" popper-class="dark-date-picker"></el-date-picker>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="Concentration reference time">
|
|
||||||
<el-date-picker v-model="queryParams.acquisition_start_end" type="datetime" placeholder="选择日期时间" class="dark-date-picker" popper-class="dark-date-picker"></el-date-picker>
|
|
||||||
</el-form-item>-->
|
|
||||||
|
|
||||||
<el-form-item label="Dataset">
|
<el-form-item label="Dataset">
|
||||||
<el-select v-model="datasetId" placeholder="请选择" class="dark-select" popper-class="dark-select-popper"
|
<el-select v-model="datasetId" placeholder="请选择" class="dark-select" popper-class="dark-select-popper"
|
||||||
style="width: 120px" @change="getCaseData">
|
style="width: 120px" @change="getCaseData">
|
||||||
|
|
@ -75,26 +68,11 @@ export default {
|
||||||
file: '',
|
file: '',
|
||||||
},
|
},
|
||||||
selectOptions: [
|
selectOptions: [
|
||||||
{
|
{ value: 'CNN', label: 'CNN' },
|
||||||
value: 'CNN',
|
{ value: 'BDT', label: 'BDT' },
|
||||||
label: 'CNN',
|
{ value: 'SVM', label: 'SVM' },
|
||||||
},
|
{ value: 'MLP', label: 'MLP' },
|
||||||
{
|
{ value: 'RF', label: 'RF' },
|
||||||
value: 'BDT',
|
|
||||||
label: 'BDT',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: 'SVM',
|
|
||||||
label: 'SVM',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: 'MLP',
|
|
||||||
label: 'MLP',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: 'RF',
|
|
||||||
label: 'RF',
|
|
||||||
},
|
|
||||||
],
|
],
|
||||||
caseOptions: [],
|
caseOptions: [],
|
||||||
fileList: [],
|
fileList: [],
|
||||||
|
|
@ -105,51 +83,78 @@ export default {
|
||||||
datasetSource: []
|
datasetSource: []
|
||||||
},
|
},
|
||||||
outPath: '',
|
outPath: '',
|
||||||
output_path: ''
|
output_path: '',
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
// color: ['#0A4072', '#683F14', '#0F605A', '#0F5A7A', '#5C5F25']
|
|
||||||
// this.onSearch()
|
|
||||||
this.getDataset()
|
this.getDataset()
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.chart()
|
// 初始化图表(空数据)
|
||||||
|
this.initChart()
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
// 监听数据源变化,自动更新图表
|
||||||
|
'chartData.datasetSource': {
|
||||||
|
handler(newVal) {
|
||||||
|
if (newVal.length && this.myChart) {
|
||||||
|
this.updateChart(newVal)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
deep: true
|
||||||
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
onSearch() {
|
onSearch() {
|
||||||
|
if (!this.currentFile && !this.queryParams.case_no) {
|
||||||
|
this.$message.warning('请选择文件或案例!');
|
||||||
|
return;
|
||||||
|
}
|
||||||
this.loading = true
|
this.loading = true
|
||||||
const formData = new FormData()
|
const formData = new FormData()
|
||||||
formData.append("file", this.currentFile)
|
if (this.currentFile) formData.append("file", this.currentFile)
|
||||||
formData.append("case_no", this.queryParams.case_no)
|
formData.append("case_no", this.queryParams.case_no)
|
||||||
formData.append("model_types", this.queryParams.model_types)
|
formData.append("model_types", this.queryParams.model_types)
|
||||||
// this.$axios.post(window.CONFIG.baseUrl + '/train-oneday/predict', formData, { headers: { "Content-Type": "multipart/form-data" } }).then((res) => {
|
|
||||||
this.$axios.post(window.CONFIG.baseUrl + '/train-oneday/predict_with_label', formData, { timeout: 1800000, headers: { "Content-Type": "multipart/form-data" } }).then((res) => {
|
this.$axios.post(
|
||||||
|
window.CONFIG.baseUrl + '/train-oneday/predict_with_label',
|
||||||
|
formData,
|
||||||
|
{ timeout: 1800000, headers: { "Content-Type": "multipart/form-data" } }
|
||||||
|
).then((res) => {
|
||||||
console.log('Predict_output_path', res.output_path)
|
console.log('Predict_output_path', res.output_path)
|
||||||
this.output_path = res?.output_path
|
this.output_path = res?.output_path
|
||||||
this.chartData.dataset = res.echart_data
|
// 1. 缓存接口返回的数据源
|
||||||
this.myChart.setOption({
|
this.chartData.datasetSource = res.echart_data || []
|
||||||
dataset: {
|
}).catch((err) => {
|
||||||
source: res.echart_data
|
this.$message.error('请求失败:' + err.message)
|
||||||
},
|
console.error('接口错误:', err)
|
||||||
})
|
|
||||||
}).finally(() => {
|
}).finally(() => {
|
||||||
this.loading = false
|
this.loading = false
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
getDataset() {
|
getDataset() {
|
||||||
this.$axios.get(window.CONFIG.baseUrl + '/train-oneday/query_train_datasets', { params: { page: 1, size: 100 } }).then((res) => {
|
this.$axios.get(window.CONFIG.baseUrl + '/train-oneday/query_train_datasets', { params: { page: 1, size: 100 } })
|
||||||
this.datasetIdOptions = res.data.items
|
.then((res) => {
|
||||||
|
this.datasetIdOptions = res.data.items || []
|
||||||
|
}).catch(err => {
|
||||||
|
this.$message.error('获取数据集失败:' + err.message)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
async getCaseData(datasetId) {
|
async getCaseData(datasetId) {
|
||||||
const res = await this.$axios.get(window.CONFIG.baseUrl + '/train-oneday/query_train_cases', { params: { dataset_id: datasetId, model_type: '', case_no: '', page: 1, size: 100 } })
|
try {
|
||||||
this.caseOptions = this.removeDuplicatesByMap(res.data.items)
|
const res = await this.$axios.get(
|
||||||
|
window.CONFIG.baseUrl + '/train-oneday/query_train_cases',
|
||||||
|
{ params: { dataset_id: datasetId, model_type: '', case_no: '', page: 1, size: 100 } }
|
||||||
|
)
|
||||||
|
this.caseOptions = this.removeDuplicatesByMap(res.data.items || [])
|
||||||
|
} catch (err) {
|
||||||
|
this.$message.error('获取案例失败:' + err.message)
|
||||||
|
}
|
||||||
},
|
},
|
||||||
removeDuplicatesByMap(arr) {
|
removeDuplicatesByMap(arr) {
|
||||||
const map = new Map()
|
const map = new Map()
|
||||||
arr.forEach(item => {
|
arr.forEach(item => {
|
||||||
if (!map.has(item.case_no)) {
|
if (item?.case_no && !map.has(item.case_no)) {
|
||||||
map.set(item.case_no, item)
|
map.set(item.case_no, item)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
@ -161,7 +166,6 @@ export default {
|
||||||
this.outPath = arr[0].out_path
|
this.outPath = arr[0].out_path
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// 文件选择变化
|
|
||||||
handleChange(file, fileList) {
|
handleChange(file, fileList) {
|
||||||
if (file) {
|
if (file) {
|
||||||
this.currentFile = file.raw || file
|
this.currentFile = file.raw || file
|
||||||
|
|
@ -173,29 +177,42 @@ export default {
|
||||||
this.queryParams.model_types = data.join(',')
|
this.queryParams.model_types = data.join(',')
|
||||||
},
|
},
|
||||||
onDownload() {
|
onDownload() {
|
||||||
// const arr = this.queryParams.model_types.split(',')
|
if (this.loading || !this.output_path) {
|
||||||
// arr.forEach(item => {
|
this.$message.warning('暂无下载文件!');
|
||||||
// // const url = this.outPath + '\\' + this.queryParams.case_no + '_' + item + '_ROC.json'
|
return false
|
||||||
// // const path = url.replace(/\\/g, '/')
|
}
|
||||||
// // this.$axios.get(window.CONFIG.baseUrl + '/download', { params: { path: path }})
|
this.$axios.get(
|
||||||
// // this.downloadFile(path, this.queryParams.case_no + '_' + item + '_ROC.json')
|
window.CONFIG.baseUrl + '/download',
|
||||||
// })
|
{ params: { path: this.output_path }, responseType: 'blob' }
|
||||||
if(this.loading) return false
|
).then(res => {
|
||||||
this.$axios.get(window.CONFIG.baseUrl + '/download', { params: { path: this.output_path }, responseType: 'blob', }).then(res => {
|
|
||||||
const downLoadName = 'test.xlsx'
|
const downLoadName = 'test.xlsx'
|
||||||
// 通过a标签打开新页面下载文件
|
|
||||||
const a = document.createElement('a')
|
const a = document.createElement('a')
|
||||||
a.href = URL.createObjectURL(res)
|
a.href = URL.createObjectURL(res) // 修复:res.data才是blob数据
|
||||||
// a标签里有download属性可以自定义文件名
|
|
||||||
a.setAttribute('download', downLoadName)
|
a.setAttribute('download', downLoadName)
|
||||||
document.body.appendChild(a)
|
document.body.appendChild(a)
|
||||||
a.click()
|
a.click()
|
||||||
document.body.removeChild(a)
|
document.body.removeChild(a)
|
||||||
|
URL.revokeObjectURL(a.href) // 释放URL对象
|
||||||
|
}).catch(err => {
|
||||||
|
this.$message.error('下载失败:' + err.message)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
chart() {
|
// 初始化图表(空数据)
|
||||||
|
initChart() {
|
||||||
|
if (!this.$refs.chartDom) return
|
||||||
|
// 销毁旧图表,避免重复实例
|
||||||
|
if (this.myChart) {
|
||||||
|
this.myChart.dispose()
|
||||||
|
}
|
||||||
this.myChart = this.$echarts.init(this.$refs.chartDom)
|
this.myChart = this.$echarts.init(this.$refs.chartDom)
|
||||||
const option = {
|
const emptyOption = this.getChartOption([])
|
||||||
|
this.myChart.setOption(emptyOption)
|
||||||
|
// 监听窗口大小变化,自适应图表
|
||||||
|
window.addEventListener('resize', this.resizeChart)
|
||||||
|
},
|
||||||
|
// 生成图表配置项
|
||||||
|
getChartOption(source) {
|
||||||
|
return {
|
||||||
grid: {
|
grid: {
|
||||||
left: 40,
|
left: 40,
|
||||||
right: 20,
|
right: 20,
|
||||||
|
|
@ -205,79 +222,120 @@ export default {
|
||||||
},
|
},
|
||||||
xAxis: {
|
xAxis: {
|
||||||
type: 'category',
|
type: 'category',
|
||||||
axisLine: {
|
axisLine: { lineStyle: { color: '#273F4B', width: 1 } },
|
||||||
lineStyle: {
|
axisTick: { lineStyle: { color: '#152029', width: 1 } },
|
||||||
color: '#273F4B',
|
axisLabel: { color: '#a2b4c9' },
|
||||||
width: 1,
|
splitLine: { lineStyle: { color: '#152029', type: 'dashed' } },
|
||||||
},
|
|
||||||
},
|
|
||||||
axisTick: {
|
|
||||||
lineStyle: {
|
|
||||||
color: '#152029',
|
|
||||||
width: 1,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
axisLabel: {
|
|
||||||
color: '#a2b4c9',
|
|
||||||
// rotate: 0
|
|
||||||
},
|
|
||||||
splitLine: {
|
|
||||||
lineStyle: {
|
|
||||||
color: '#152029',
|
|
||||||
type: 'dashed',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
yAxis: {
|
yAxis: {
|
||||||
type: 'value',
|
type: 'value',
|
||||||
axisLine: {
|
axisLine: { show: true, lineStyle: { color: '#273F4B' } },
|
||||||
|
axisLabel: { color: '#a2b4c9' },
|
||||||
|
splitLine: { lineStyle: { color: '#152029', type: 'dashed' } },
|
||||||
|
markLine: {
|
||||||
show: true,
|
show: true,
|
||||||
lineStyle: {
|
silent: true,
|
||||||
color: '#273F4B',
|
lineStyle: { width: 2, type: 'solid' },
|
||||||
},
|
label: { show: true, position: 'end', color: '#fff', fontSize: 12 },
|
||||||
},
|
data: [
|
||||||
axisLabel: {
|
{ yAxis: 70, label: { formatter: '阈值70', color: '#FFA500' }, lineStyle: { color: '#FFA500' } },
|
||||||
color: '#a2b4c9',
|
{ yAxis: 80, label: { formatter: '阈值80', color: '#FF4D4F' }, lineStyle: { color: '#FF4D4F' } }
|
||||||
},
|
]
|
||||||
splitLine: {
|
|
||||||
lineStyle: {
|
|
||||||
color: '#152029',
|
|
||||||
type: 'dashed',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
// axisTick: {
|
|
||||||
// show: true,
|
|
||||||
// lineStyle: {
|
|
||||||
// color: '#f00'
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
},
|
|
||||||
tooltip: {
|
|
||||||
trigger: 'axis',
|
|
||||||
axisPointer: {
|
|
||||||
type: 'shadow'
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
tooltip: { trigger: 'axis', axisPointer: { type: 'shadow' } },
|
||||||
color: ['#0A4072', '#683F14', '#0F605A', '#0F5A7A', '#5C5F25'],
|
color: ['#0A4072', '#683F14', '#0F605A', '#0F5A7A', '#5C5F25'],
|
||||||
dataset: {
|
dataset: { source: source },
|
||||||
source: this.chartData.datasetSource
|
series: [
|
||||||
},
|
// 系列1:第一个柱子
|
||||||
series: [{ type: 'bar' }, { type: 'bar' }, { type: 'bar' }]
|
{
|
||||||
|
type: 'bar',
|
||||||
|
label: {
|
||||||
|
show: true, position: 'top', color: '#a2b4c9', fontSize: 12, formatter: (params) => {
|
||||||
|
return params.value[1]
|
||||||
}
|
}
|
||||||
this.myChart.setOption(option)
|
|
||||||
},
|
},
|
||||||
|
},
|
||||||
|
// 系列2:中间柱子(原始值标签)
|
||||||
|
{
|
||||||
|
type: 'bar',
|
||||||
|
stack: 'sameStack', // 叠加标识
|
||||||
|
label: {
|
||||||
|
show: true,
|
||||||
|
position: 'top',
|
||||||
|
color: '#a2b4c9',
|
||||||
|
fontSize: 12,
|
||||||
|
formatter: (params) => {
|
||||||
|
return params.value[2]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 系列3:透明柱子(自定义值标签)
|
||||||
|
{
|
||||||
|
type: 'bar',
|
||||||
|
stack: 'sameStack', // 同栈叠加
|
||||||
|
encode: { y: 1 }, // 绑定第二列数据(核心修复:替代datasetIndex)
|
||||||
|
itemStyle: { color: 'rgba(0,0,0,0)' }, // 完全透明
|
||||||
|
label: {
|
||||||
|
show: true,
|
||||||
|
position: 'inside',
|
||||||
|
color: '#FFD700',
|
||||||
|
fontSize: 12,
|
||||||
|
fontWeight: 'bold',
|
||||||
|
formatter: (params) => {
|
||||||
|
const val = params.value[1] + params.value[2] + params.value[3]
|
||||||
|
const result = `${(val / 3).toFixed(2)}%`
|
||||||
|
// const val = this.getRealValue(params.value)
|
||||||
|
// const accuracy = this.accuracyMap[params.name] || `${(val * 0.9).toFixed(2)}%`
|
||||||
|
return `总准确率:\n ${result}`
|
||||||
|
}
|
||||||
|
},
|
||||||
|
tooltip: { show: false } // 隐藏tooltip干扰
|
||||||
|
},
|
||||||
|
// 系列4:最后一个柱子
|
||||||
|
{
|
||||||
|
type: 'bar',
|
||||||
|
label: {
|
||||||
|
show: true, position: 'top', color: '#a2b4c9', fontSize: 12, formatter: (params) => {
|
||||||
|
return params.value[3]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 更新图表数据
|
||||||
|
updateChart(source) {
|
||||||
|
if (!this.myChart) return
|
||||||
|
const option = this.getChartOption(source)
|
||||||
|
this.myChart.setOption(option, true) // true:重置配置,避免缓存
|
||||||
|
this.myChart.resize() // 强制刷新
|
||||||
|
},
|
||||||
|
// 图表自适应
|
||||||
|
resizeChart() {
|
||||||
|
if (this.myChart) {
|
||||||
|
this.myChart.resize()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 下载文件通用方法
|
||||||
downloadFile(url, filename) {
|
downloadFile(url, filename) {
|
||||||
const link = document.createElement('a')
|
const link = document.createElement('a')
|
||||||
link.href = url
|
link.href = url
|
||||||
link.download = filename
|
link.download = filename
|
||||||
link.style.display = 'none'
|
link.style.display = 'none'
|
||||||
|
|
||||||
document.body.appendChild(link)
|
document.body.appendChild(link)
|
||||||
link.click()
|
link.click()
|
||||||
|
|
||||||
document.body.removeChild(link)
|
document.body.removeChild(link)
|
||||||
},
|
},
|
||||||
},
|
// 销毁钩子(避免内存泄漏)
|
||||||
|
beforeDestroy() {
|
||||||
|
window.removeEventListener('resize', this.resizeChart)
|
||||||
|
if (this.myChart) {
|
||||||
|
this.myChart.dispose()
|
||||||
|
this.myChart = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user