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

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.lryc.cn/news/618799.html

相关文章:

  • springboot整合sharding-jdbc 5.5.2 做单库分表
  • 燕山大学计算机网络实验(2025最新)
  • Java调用Vue前端页面生成PDF文件
  • 深入剖析 React 合成事件:透过 onClick 看本质
  • Java 工厂方法模式
  • Flask + Vue.js 物联网数字大屏实现方案
  • 数据分析基本内容(第二十节课内容总结)
  • Rsync自动化备份平台建设实战
  • 【数据分析与挖掘实战】金融风控之贷款违约预测
  • 阿里云 Windows 服务器 搭建 Gitea 私有 Git 服务器完整教程
  • 开疆智能Ethernet转ModbusTCP网关连接PAC3200电能表配置案例
  • VirtualBox 虚拟机磁盘扩容完整手册
  • MaxKB+合合信息TextIn:通过API实现PDF扫描件的文档审核
  • [git] 重配ssh key | 解决冲突
  • python日志中的logging.basicConfig和logging.getLogger
  • [Robotics_py] 机器人运动模型 | `update`函数 | 微积分矩阵
  • 数据类型 list
  • 浏览器CEFSharp+X86+win7 之 全球外贸电商平台订单管理(十)
  • 每日五个pyecharts可视化图表-line:从入门到精通 (4)
  • 数据结构:链表栈的操作实现( Implementation os Stack using List)
  • Java 中 List 接口详解:知识点与注意事项
  • Java数据结构之LinkedList
  • 【开发环境下浏览器前后端Cookie跨域问题】
  • 视频安全预警系统的应用价值
  • vue3用quill富文本赋值后回退键删除报错
  • 可以免费使用的数字人API
  • 亚马逊POST退场后的增长突围:关联与交叉销售的全链路策略重构
  • 一维数组的创建、初始化与使用指南
  • 详解k6中的核心概念——场景(Scenarios)
  • Spring面试宝典