当前位置: 首页 > ops >正文

Vue接口平台十三——测试记录

效果图及说明

在这里插入图片描述
上面用散点图显示,x轴可以筛选时间,环境,任务名称。选中后,聚合方式会发生变化。y轴显示通过率。相同任务点的颜色会相同。
下方显示执行的所有任务简介。点击查看报告,跳转报告详情页面。

内容实现

前置准备

  1. 新建文件RecordView.vue
    在这里插入图片描述
  2. 路由配置
    在这里插入图片描述
  3. 左侧菜单栏配置
    在这里插入图片描述

页面代码

页面展示

<template><div class="main"><!-- 渲染图标的元素 --><div><div style="margin-bottom: 10px;"><label>X轴选择: </label><select @change="changeXAxis" v-model="selectedXAxis"><option value="create_time">时间</option><option value="task">任务名称</option><option value="env">测试环境</option></select></div><div id="chat_pro_record" class="box1"></div></div><!-- 渲染表格的组件 --><el-table :data="recordList" border style="width: 100%" size="small"><el-table-column label="执行时间" prop="create_time" min-width="180"/><el-table-column prop="env" label="执行环境"/><el-table-column prop="task" label="测试计划"/><el-table-column prop="all" label="总用例"/><el-table-column prop="success" label="通过数"/><el-table-column prop="pass_rate" label="通过率"/><el-table-column label="测试报告" width="180"><template #default="scope"><el-button @click="showReport(scope.row)" icon="View" type="primary" plainsize="small">查看报告</el-button></template></el-table-column></el-table></div>
</template><style scoped lang="scss">
.box1 {height: 260px;background: #282828;margin-bottom: 10px;
}.main {padding: 10px;
}
</style>

js

<script setup>
import { ProjectStore } from '@/stores/module/ProStore'
import mychat from '@/utils/chart.js'
import http from '@/api/index'
import { ref, onMounted,onUnmounted } from 'vue'
import { useRouter } from 'vue-router'const router = useRouter()
// 存储项目的执行记录
let recordList = ref([])
let chartInstance = null;const selectedXAxis = ref('create_time');const proStore = ProjectStore()// 获取项目的所有测试执行记录
const getRecords = async function () {const response = await http.task.getRecordsApi({project: proStore.pro.id})recordList.value = response.datashowChat()
}
// 组件加载完获取所有数据
onMounted(() => {getRecords()
})const showChat = function () {console.log("recordList.value", recordList.value)const dom = document.getElementById('chat_pro_record')// 销毁之前的图表实例if (chartInstance) {chartInstance.dispose();}// 创建新的图表实例chartInstance = mychat.chart4(dom, recordList.value)
}// X轴切换处理
function changeXAxis() {if (chartInstance && chartInstance.changeXAxis) {chartInstance.changeXAxis(selectedXAxis.value);}
}function showReport(record) {router.push({name: "report",params: {id: record.id}})
}// 组件卸载时清理资源
onUnmounted(() => {if (chartInstance) {chartInstance.dispose();}
})
</script>

这块内容比较简单,简单梳理一下逻辑

组件加载完获取所有records数据,获取完数据后,保存到变量recordList中,并且展示图表数据。

然后x轴选择可以触发函数,切换聚合目标。销毁原先的图数据,再展示新的图数据。

表格中的操作-查看报告绑定了函数,点击跳转报告详情。

图的绘制

// utils/chart.js
chart4(ele, datas) {if (!ele || !datas || datas.length === 0) {console.warn('Invalid element or data for chart4');return;}const indices = {id: 0,env: 1,task: 2,create_time: 3,all: 4,success: 5,fail: 6,error: 7,pass_rate: 8,tester: 9,status: 10};const schema = [{name: 'id', index: 0},{name: 'env', index: 1},{name: 'task', index: 2},{name: 'create_time', index: 3},{name: 'all', index: 4},{name: 'success', index: 5},{name: 'fail', index: 6},{name: 'error', index: 7},{name: 'pass_rate', index: 8},{name: 'tester', index: 9},{name: 'status', index: 10}];const fieldIndices = schema.reduce(function (obj, item) {obj[item.name] = item.index;return obj;}, {});// 用于存储不同类别的颜色映射const categoryColors = {};let myChart = null;let data;let currentXAxis = 'create_time';let currentSymbolSize = 10; // 默认点大小// 模拟数据const originData = datas;function normalizeData(originData) {// 收集所有唯一类别以分配颜色const categories = new Set();originData.forEach(function (row) {if (row.env) categories.add(row.env);if (row.task) categories.add(row.task);});// 为每个唯一类别分配颜色let categoryArray = Array.from(categories);let hStep = Math.round(300 / (categoryArray.length - 1 || 1));categoryArray.forEach((category, i) => {categoryColors[category] = echarts.color.modifyHSL('#5A94DF', hStep * i);});// 转换数据格式let processedData = originData.map(function (row) {let processedRow = new Array(schema.length);for (let i = 0; i < schema.length; i++) {processedRow[i] = row[schema[i].name];}return processedRow;});processedData.forEach(function (row) {for (let index = 0; index < row.length; index++) {if (index !== indices.env &&index !== indices.task &&index !== indices.create_time) {if (index === indices.pass_rate) {row[index] = parseFloat(row[index]) || 0;} else if (index !== indices.id && index !== indices.tester && index !== indices.status) {row[index] = parseFloat(row[index]) || 0;}}}});return processedData;}function getOption(data, xAxisField = 'create_time') {// 为category类型x轴准备数据let uniqueXValues = [...new Set(data.map(item => item[fieldIndices[xAxisField]]))];// 如果是时间字段,按时间排序,确保最新的在右边if (xAxisField === 'create_time') {uniqueXValues.sort((a, b) => new Date(a) - new Date(b));}return {xAxis: {type: 'category',name: xAxisField,data: uniqueXValues,splitLine: {show: false}},yAxis: {type: 'value',name: '通过率(%)',splitLine: {show: false},axisLabel: {formatter: '{value}%'}},series: [{zlevel: 1,name: '测试结果',type: 'scatter',data: data.map(function (item, idx) {// 根据当前X轴字段选择颜色分类依据let category;if (xAxisField === 'env') {category = item[indices.task]; // X轴是环境时,按任务分类颜色} else {category = item[indices.task]; // 其他情况按任务分类颜色}return {value: [item[fieldIndices[xAxisField]], item[indices.pass_rate], category, idx],itemStyle: {color: categoryColors[category] || '#5A94DF'}};}),animationThreshold: 5000,progressiveThreshold: 5000,symbolSize: currentSymbolSize // 使用当前设置的点大小}],animationEasingUpdate: 'cubicInOut',animationDurationUpdate: 2000,tooltip: {trigger: 'item',formatter: function (params) {const dataIndex = params.data.value[3];const rowData = data[dataIndex];if (!rowData) return '';return `${rowData[indices.task] || ''}<br/>${xAxisField}: ${params.data.value[0]}<br/>环境: ${rowData[indices.env] || ''}<br/>通过率: ${rowData[indices.pass_rate] || 0}%`;}},legend: {show: true,data: Object.keys(categoryColors),textStyle: {color: '#fff'}}};}// X轴切换函数function changeXAxis(xAxisField) {if (data && myChart) {currentXAxis = xAxisField;const option = getOption(data, xAxisField);myChart.setOption(option, true); // true表示不合并选项,完全替换}}// 点大小调整函数function changeSymbolSize(size) {if (myChart) {currentSymbolSize = size;const option = getOption(data, currentXAxis);myChart.setOption(option, true);}}try {myChart = echarts.init(ele);// 初始化数据data = normalizeData(originData);const option = getOption(data, currentXAxis);myChart.setOption(option);window.addEventListener('resize', () => {if (myChart) {myChart.resize();}});// 返回图表实例和控制函数,供外部调用return {chart: myChart,changeXAxis: changeXAxis,changeSymbolSize: changeSymbolSize, // 返回点大小调整函数dispose: () => {if (myChart) {myChart.dispose();}}};} catch (error) {console.error('Error initializing chart:', error);return null;}}

这块代码,是直接把echarts官网的示例丢给AI,再给出自己数据格式以及想要的效果生成,然后慢慢调试出来的。我也不会写。能用就行。

实现效果

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
这里通过率相同的点会重合,后续也可以再优化下这个问题。也可以不用管,,,看自己需要吧。

http://www.xdnf.cn/news/17605.html

相关文章:

  • Git 撤回已推送到远程的最近push
  • 【数据结构入门】堆
  • NLP—词向量转换评论学习项目分析真实案例
  • 4.运算符
  • Docker命令及操作
  • imx6ull-驱动开发篇20——linux互斥体实验
  • 图解软件系统组成
  • 什么是iOS超级签名?为何它能解决企业签名的“掉签”难题?
  • 云原生高级---TOMCAT
  • [激光原理与应用-250]:理论 - 几何光学 - 透镜成像的优缺点,以及如克服缺点
  • 机器学习-集成学习(EnsembleLearning)
  • ETCD的简介和使用
  • 17、CryptoMamba论文笔记
  • 导入文件到iPhone实现
  • C++11-下
  • QT6 如何在Linux Wayland 桌面系统抓屏和分享屏幕
  • AT F-Intervals 题解
  • 深入理解数据库架构:从原理到实践的完整指南
  • DEA模型MATLAB实现(CCR、BCC、超效率)
  • 云原生应用的DevOps3(CI/CD十大安全风险、渗透场景)
  • LeetCode189~191、198~214题解
  • Day52 Java面向对象07 类与对象总结
  • 鸿蒙har包打包与引用,其它主工程entry引用本地har
  • 【19】万集科技——万集科技嵌入式,校招 一面,二面,面试问答记录
  • 【基于Redis的手语翻译序列存储设计】
  • 淘宝API列表:高效获取商品详情图主图商品视频参数item_get
  • Flutter path_provider的基本使用(读写文件)
  • 车规级霍尔开关芯片SC25891 | 为汽车安全带扣筑起高可靠性安全防线
  • 【MySQL】MySQL聚集索引与非聚集索引深度解析
  • 蚁剑--安装、使用