前后端交互之动态列

ops/2024/11/20 11:07:07/

一. 情景

  • 在做项目时,有时候后会遇到后端使用了聚合函数,导致生成的对象的属性数量或数量不固定,因此无法建立一个与之对应的对象来向前端传递数据,
  • 这时可以采用NameDataListVO向前端传递数据。
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class NameDataListVO {private String name;                 //名称(可以是聚合函数的分组名)private List<BigDecimal> data1;      //数据private List<BigDecimal> data2;private List<String> desp;            //与数据List的长度相等,用于描述每个数据的含义 
}

二. 前端处理

1. 数据显示

要想显示如下的数据
在这里插入图片描述

(1) 前端接收的List< NameDataVOList>对象(其中每个对象的desp字段保持一致

this.rawData=[{"name": "2023","data1": [85.5, 92.3, 88.1, 91.4, 87.6, 89.8, 93.2, 90.0, 86.7, 88.9, 92.5, 91.1],"data2": null,"desp": ["张三", "李四", "王五", "赵六", "钱七", "周八", "吴九", "郑十", "王十一", "李十二", "赵十三", "孙十四"]},{"name": "2022","data1": [82.4, 90.5, 85.3, 89.7, 84.2, 86.9, 88.4, 83.6, 87.8, 91.2, 90.1, 84.5],"data2": null,"desp": ["张三", "李四", "王五", "赵六", "钱七", "周八", "吴九", "郑十", "王十一", "李十二", "赵十三", "孙十四"]},]

要想在前端正确显示,必须将data由数组转为prop:value(注意:为了使得this.columnList中的列名(label)与属性(prop)一一对应,可以以data_${index}来命名属性)

this.columnList=["张三", "李四", "王五", "赵六", "钱七", "周八", "吴九", "郑十", "王十一", "李十二", "赵十三", "孙十四"]
this.processedData=[{"name": "2023","data_0":85.5,"data_1":92.3"data_2":88.1"data_3":91.4},{"name": "2022","data_0":85.5,"data_1":92.3"data_2":88.1"data_3":91.4},]
  • 前端数据处理代码:
    if (this.rawData.length > 0) {this.columnList = this.rawData[0].dep;this.processedData=processData(this.rawData)}
   processData(rawData) {return rawData.map(item => {const processedItem = {name: item.name,};item.data1.forEach((data, index) => {processedItem[`data_${index}`] = data;});return processedItem;});},

(2) 前端页面显示

<el-table :data="processedData" height="800" v-loading="loading" @selection-change="handleSelectionChange"><el-table-column type="selection" width="55" /><el-table-column prop="name" label="聚类名称" sortable width="60" align="center" /><el-table-column v-for="(column, index) in columnList" :key="index" :label="column" :prop="`data_${index}`"align="center" v-if="columns[index].visible"><template slot-scope="scope"><span>{{ scope.row[`data_${index}`] }}</span></template></el-table-column>
</el-table>
2. 显隐列

新建列配置列表this.columns,通过使用 v-if=“columns[index].visible” 来控制是该列是否显示

//构建columns配置列表buildColumns(rawData) {// 初始化一个空数组用于存储列配置this.columns = [];// 将列名称添加到列配置中,动态生成keythis.columnList.forEach((c, index) => {let key = this.columns.length; // 使用 this.columns 数组的当前长度作为 keythis.columns.push({key: key,label: c,visible: true});});},
3. Echarts图表显示
  • chartOptions 是一个计算属性,它返回一个对象,这个对象包含了图表的配置项。每当组件的数据发生变化时,chartOptions 会重新计算,并且图表会根据新的配置进行更新。
<template><div class="app-container"><!-- ... 其他代码 ... --><!-- 生成图表按钮 --><el-button type="warning" plain icon="el-icon-s-data" size="mini" @click="handleGraph">生成图表</el-button><!-- ... 其他代码 ... --><!-- 图表对话框 --><el-dialog title="图表展示" :visible.sync="chartDialogVisible" width="80%"><div ref="chart" style="width: 100%; height: 500px;"></div></el-dialog><!-- ... 其他代码 ... --></div>
</template><script>
// 引入echarts
import * as echarts from 'echarts';export default {// ... 其他选项 ...data() {return {// ... 其他数据 ...chartDialogVisible: false, // 控制图表对话框的显示// 假设yearList是存储年份的数组yearList: [],};},computed: {// ... 其他计算属性 ...chartOptions() {const xAxisData = this.columnList;const seriesData = this.processedData.map(item => ({name: item.name,type: 'bar',data: Object.keys(item).filter(key => key.startsWith('data_')) // 过滤出以 'data_' 开头的键.map(key => item[key]) // 获取每个 'data_X' 属性的值}));return {legend: {data: this.nameList},tooltip: {},xAxis: {type: 'category',data: xAxisData,},yAxis: {// // 设置 y 轴的最大值为数据中的最大值加上 20%// max: (value) => {//   return value.max + value.max * 0.2;// }},dataZoom: [{type: 'slider',show: true,xAxisIndex: [0],start: 1,end: 35},{type: 'inside',xAxisIndex: [0],start: 1,end: 35}],toolbox: {show: true,feature: {mark: { show: true },saveAsImage: { show: true },}},series: seriesData};}},methods: {// ... 其他方法 ...// 处理图表显示handleGraph() {this.chartDialogVisible = true;this.$nextTick(() => {this.initChart();});},// 初始化图表initChart() {const chart = echarts.init(this.$refs.chart);const options = this.chartOptions;chart.setOption(options);},// ... 其他方法 ...}
};
</script>

http://www.ppmy.cn/ops/135216.html

相关文章

【蓝桥杯C/C++】I/O优化技巧:cin.tie(nullptr)的详解与应用

文章目录 &#x1f4af;前言&#x1f4af;I/O流的基本概念&#x1f4af;cin.tie(nullptr)使用场景底层机制与ios::sync_with_stdio(false) 的搭配使用手动刷新输出流 &#x1f4af;使用示例和性能对比示例代码 &#x1f4af;常见误区和注意事项进一步优化&#xff1a;快速输入输…

【视觉SLAM】4b-特征点法估计相机运动之PnP 3D-2D

文章目录 0. 前言1. PnP求解1.1 直接线性变换DLT1.2 P3P1.3 光束平差法BA2. 实现0. 前言 透视n点(Perspective-n-Point,PnP)问题是计算机视觉领域的经典问题,用于求解3D-2D的点运动。换句话说,当知道 N N N个世界坐标系中3D空间点的坐标以及它们在图像上的投影点像素坐标…

Centos 7 修改YUM镜像源地址为阿里云镜像地址

安装 wget 1 yum install -y wget 进入目录 1 cd /etc/yum.repos.d/ 创建目录 1 mkdir backup 默认源配备份 1 mv C* backup/ 下载阿里云yum源 1 wget -O /etc/yum.repos.d/CenOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo 清除旧缓存 1 yum c…

homework系列

(4)输出整数各位数字:输人一个整数number&#xff0c;从高位开始逐位分割并输出它的各位 数字。试编写相应程序。 输人输出示例 Enter a number:123456 输出 1 2 3 4 5 6 #include <iostream>int main() {int m 0, i 1, j 1, k 1;int count 0;printf("Enter …

在Ubuntu上部署Open WebUI和Ollama,打造你的私人GPT

在Ubuntu上部署Open WebUI和Ollama&#xff0c;打造你的私人GPT 如果你对自然语言处理或者构建自己的对话AI感兴趣&#xff0c;那么这篇文章就是为你准备的。我将带你一步步搭建Open WebUI和Ollama&#xff0c;让你在自己的服务器上就能体验到强大的语言模型。 简介 Ollama是…

C++类和对象(下)

文章目录 1. 初始化列表1.1 什么是初始化列表1.2 为什么要引入初始化列表1.3 初始化列表如何写1.3.1 显式写初始化列表1.3.2 隐式写初始化列表1.3.2.1 不声明缺省值1.3.2.2 声明缺省值 1.3.3 初始化列表总结 2.类型转换2.1 内置类型与自定义类型转换2.2 自定义类型间的转换2.3 …

Python 正则表达式进阶用法:边界匹配

Python 正则表达式进阶用法&#xff1a;边界匹配 正则表达式是一种强大的工具&#xff0c;用于处理文本中的模式匹配。它广泛应用于文本查找、替换、数据清洗等任务。在学习了正则表达式的基础知识后&#xff0c;掌握更高级的用法将使得正则表达式的应用更加灵活。边界匹配&am…

2.5D视觉——Aruco码定位检测

目录 1.什么是Aruco标记2.Aruco码解码说明2.1 Original ArUco2.2 预设的二维码字典2.3 大小Aruco二维码叠加 3.函数说明3.1 cv::aruco::detectMarkers3.2 cv::solvePnP 4.代码注解4.1 Landmark图说明4.2 算法源码注解 1.什么是Aruco标记 ArUco标记最初由S.Garrido-Jurado等人在…