前言
本文主要介绍与任务相关的界面的编写,具体而言,分为展示任务列表、新建任务、个人任务等。此外,引入了echarts,以进行训练过程的可视化展示,也会在本文介绍其使用。这一部分可以认为是该系统最重要的一部分。
所有任务展示
从后端获取到数据之后,跳转到所有任务展示界面,这里其实比较常规,就是一个表格的实现和美化:
<Motion>
<el-card style="margin-bottom: 10px">
<span>任务大厅</span>
<el-button style="margin-left: 20px" type="primary" @click="refresh"
>刷新<el-icon><Refresh /></el-icon>
</el-button>
</el-card>
</Motion>
<Motion :delay="100">
<el-card>
<el-table :data="tableData" stripe style="width: 100%">
<el-table-column prop="taskId" label="任务编号" width="140" />
<el-table-column prop="taskName" label="任务名称" width="320" />
<el-table-column prop="publisher" label="发布者" width="180" />
<el-table-column prop="totalURound" label="总聚合轮数" width="170" />
<el-table-column
prop="userNum"
label="当前 / 需要参与人数"
width="190"
/>
<el-table-column prop="state" label="任务状态" />
<el-table-column label="操作">
<template #default="scope">
<el-button
size="small"
@click="viewDetails(scope.$index, scope.row)"
>查看详情
</el-button>
</template>
</el-table-column>
</el-table>
</el-card>
</Motion>
创建任务
用一个卡片包裹的表单form。
表单当中包括了常见的数据选择形式:
单选框,计数器,输入框,文件上传,按钮等等…
<Motion>
<el-row :gutter="20" style="margin: 20px">
<el-col :span="6" style="margin-bottom: 20px">
<div></div>
</el-col>
<el-col :span="12" style="margin-bottom: 20px">
<el-card>
<template #header>
<div style="text-align: center">
<span style="font-size: 20px; font-weight: 500"
>创建任务面板</span
>
</div>
</template>
<template #default>
<el-form
ref="newTaskFormRef"
:model="taskForm"
:label-position="right"
label-width="100px"
:rules="rules"
>
<el-form-item label="任务名称" prop="taskName">
<el-input
v-model="taskForm.taskName"
placeholder="请输入任务名称"
/>
</el-form-item>
<el-form-item label="任务详情" prop="taskInfo">
<el-input
v-model="taskForm.taskInfo"
type="textarea"
:rows="3"
placeholder="请输入任务的相关信息,以更好地帮助参与者了解该任务的目的与方法"
/>
</el-form-item>
<el-form-item label="最少人数">
<el-input-number
v-model="taskForm.taskMinMember"
:min="1"
:max="10"
:step="1"
/>
</el-form-item>
<el-form-item label="总聚合轮次">
<el-input-number
v-model="taskForm.totalURound"
:min="1"
:step="1"
/>
</el-form-item>
<el-form-item label="上传模型" prop="taskModel">
<el-row>
<el-col>
<el-upload
ref="modelUpload"
action="action"
drag="true"
accept=".py"
limit="1"
auto-upload="false"
:http-request="modelFileHttpRequest"
:before-upload="modelFileBeforeUpload"
:on-exceed="handleExceed"
:on-error="handleUploadError"
style="margin-right: 15px; margin-bottom: 15px"
>
<el-icon class="el-icon--upload">
<upload-filled />
</el-icon>
<div class="el-upload__text">
将文件拖拽到此处 或 <em>单击此处</em> 来上传文件
</div>
</el-upload>
</el-col>
</el-row>
<el-row>
<el-col span="12">
<el-button type="primary" @click="downloadFile()">
下载模型模板
<el-icon class="el-icon--right">
<Download />
</el-icon>
</el-button>
</el-col>
<el-col span="12">
<span class="el-upload__tip" style="margin-left: 20px">
请基于给定的模型模板进行模型的构建
</span>
</el-col>
</el-row>
</el-form-item>
<el-form-item label="模型参数" prop="paraSource">
<el-radio-group v-model="taskForm.paraSource">
<el-radio :label="0" @click="setParaSource(false)"
>随机生成
</el-radio>
<el-radio :label="1" @click="setParaSource(true)"
>自行上传
</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item
v-if="from_user"
label="上传参数"
prop="initialPara"
>
<el-upload
ref="paraUpload"
action="action"
drag="true"
accept=".model"
limit="1"
auto-upload="false"
:http-request="paraFileHttpRequest"
:before-upload="paraFileBeforeUpload"
:on-exceed="handleExceed"
:on-error="handleUploadError"
style="margin-right: 15px"
>
<el-icon class="el-icon--upload">
<upload-filled />
</el-icon>
<div class="el-upload__text">
将文件拖拽到此处 或 <em>单击此处</em> 来上传文件
</div>
</el-upload>
<span class="el-upload__tip">
请上传.model文件以初始化模型参数
</span>
</el-form-item>
</el-form>
<div style="text-align: center">
<el-button
type="primary"
size="large"
@click="submitTaskForm"
round
>创建任务
</el-button>
<el-button
type="danger"
size="large"
:icon="Delete"
round
@click="resetTaskForm()"
>清空表单
</el-button>
</div>
</template>
</el-card>
</el-col>
<el-col :span="6" style="margin-bottom: 20px">
<div></div>
</el-col>
</el-row>
</Motion>
echarts的使用
折线图主要用来展示数据项随着时间推移的趋势或变化。
ECharts是一款基于JavaScript的数据可视化图表库,提供直观,生动,可交互,可个性化定制的数据可视化图表。ECharts最初由百度团队开源,并于2018年初捐赠给Apache基金会,成为ASF孵化级项目。
echarts导入
npm install echarts --save
// 全局引入echarts组件用于绘制图表
import echarts from 'echarts'
Vue.prototype.$echarts = echarts
折线图样式的修改
折线图中折线的样式可以通过 lineStyle 设置。可以为其指定颜色、线宽、折线类型、阴影、不透明度等等,具体的可以参考配置项手册 series.lineStyle 了解。这里,我们以设置颜色(color)、线宽(width)和折线类型(type)为例说明。
数据点的样式可以通过 series.itemStyle 指定填充颜色(color)、描边颜色(borderColor)、描边宽度(borderWidth)、描边类型(borderType)、阴影(shadowColor)、不透明度(opacity)等。与折线样式的设置十分相似,这里不再展开说明。
在系列中,这数据点的标签通过 series.label 属性指定。如果将 label 下的 show 指定为true,则表示该数值默认时就显示;如果为 false,而 series.emphasis.label.show 为 true,则表示只有在鼠标移动到该数据时,才显示数值。
官网的实例:
option = {
xAxis: {
data: ['A', 'B', 'C', 'D', 'E']
},
yAxis: {},
series: [
{
data: [10, 22, 28, 23, 19],
type: 'line',
lineStyle: {
normal: {
color: 'green',
width: 4,
type: 'dashed'
}
}
}
]
};
示例二:
option = {
xAxis: {
data: ['A', 'B', 'C', 'D', 'E']
},
yAxis: {},
series: [
{
data: [10, 22, 28, 23, 19],
type: 'line',
label: {
show: true,
position: 'bottom',
textStyle: {
fontSize: 20
}
}
}
]
};
数据动态绑定
基本的思路就是初始化引入图标,然后绑定好xy轴相应的数据,之后其会根据我们数据的变化动态的刷新展示。
为了数据变化时实时刷新表格,在监听到属性值发生改变时,重新渲染一次表格。
敲重点:echarts不会自动帮你渲染数据的,需要手动再次调用setOption函数。
再次敲重点,重点,重点:看到 this.myEcharts.setOption(this.option, true)这一行代码了吗?最后这个属性’true’真是nb坏了,没它不行。
上官方代码:setOption的函数定义,option是指图表的配置项和数据,notMerge是指是否不跟之前设置的 option 进行合并。默认为 false。即表示合并。如果为 true,表示所有组件都会被删除,然后根据新option 创建所有新组件。
这里参考了:https://blog.youkuaiyun.com/qq_41937069/article/details/117631059
我们主要的代码如下:
// 根据训练情况改变图表
chartChange() {
let myChart = this.$echarts.init(document.getElementById("myChart"));
// 使用刚指定的配置项和数据显示图表。
myChart.setOption(
{
// title: { text: "精确度" },
tooltip: {},
xAxis: {
data: this.xdata,
name: "epoch",
},
yAxis: {
// scale: true,
name: "accuracy",
min:
Math.min(...this.ydata) - 0.1 >= 0
? (Math.min(...this.ydata) - 0.1).toFixed(2)
: 0,
max:
Math.max(...this.ydata) + 0.1 <= 1
? (Math.max(...this.ydata) + 0.1).toFixed(2)
: 1,
interval: 0.05,
},
series: [
{
name: "精确度",
type: "line",
data: this.ydata,
label: {
show: true,
position: "top",
textStyle: {
fontSize: 15,
},
},
},
],
},
true
);
},
实现的效果基本如下图所示: