前后端交互之动态列

一. 情景

  • 在做项目时,有时候后会遇到后端使用了聚合函数,导致生成的对象的属性数量或数量不固定,因此无法建立一个与之对应的对象来向前端传递数据,
  • 这时可以采用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.mzph.cn/pingmian/61127.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[笔记]L6599的极限工作条件考量

0.名词 OTP over tempature protect.OCP over current protectOVP over voltage protectBrownout Protection Undervoltage Protection可能需要考虑hysteresis response.因为要考虑一些高频干扰 1.基本的过流保护逻辑 参考&#xff1a;ST L6599 器件手册 LLC开关电源&#…

shell编程规范和脚本变量

什么是shell 人和计算机内核之间的中介&#xff1a; 计算机的语言是二进制&#xff0c;把人类的语言翻译成计算机能够识别的语言&#xff0c;然后让内核来处理 内核完成之后要把结果反馈给用户&#xff0c;要把计算机的翻译成人类能够识别的语言 命令解释器&#xff0c;pyc…

二分查找类型算法

今天开始刷题啦&#xff0c;坚持住哟&#xff01; 使用二分法的前提是数组有序且无重复元素。 704.二分查找 第一遍代码如下&#xff1a; class Solution {public int search(int[] nums, int target) {int left0;int rightnums.length-1;while(left<right){int mid (r…

【Pikachu】XML外部实体注入实战

若天下不定&#xff0c;吾往&#xff1b;若世道不平&#xff0c;不回&#xff01; 1.XXE漏洞实战 首先写入一个合法的xml文档 <?xml version "1.0"?> <!DOCTYPE gfzq [<!ENTITY gfzq "gfzq"> ]> <name>&gfzq;</name&…

多模块集成swagger(knife4j-spring-boot-starter)

前言 单体项目、多模块单体项目、微服务项目&#xff0c;集成的方案大同小异&#xff0c;微服务会在网关做个聚合&#xff0c;后面再补充。 依赖版本 目前demo的版本如下&#xff1a; spring boot 2.7.3spring cloud 2021.0.4spring cloud alibaba 2021.0.4.0knife4j-sprin…

uni-app快速入门(七)--组件路由跳转和API路由跳转及参数传递

uni-app有两种页面路由跳转模式&#xff0c;即使用navigator组件跳转和调用API跳转&#xff0c;API调转不要理解为调用后台接口的API&#xff0c;而是指脚本函数中使用跳转函数。 一、组件路由跳转 1.1 打开新页面 打开新页面使用组件的open-type"navigate",见下面…

DataStream编程模型之数据源、数据转换、数据输出

Flink之DataStream数据源、数据转换、数据输出&#xff08;scala&#xff09; 0.前言–数据源 在进行数据转换之前&#xff0c;需要进行数据读取。 数据读取分为4大部分&#xff1a; &#xff08;1&#xff09;内置数据源&#xff1b; 又分为文件数据源&#xff1b; socket…

CSS盒子的定位>(上篇)#定位属性#相对定位-附练习

一、定位属性 1.定位方式 position属性可以选择4种不同类型的定位方式。 语法格式&#xff1a;position&#xff1a;relation | absolute | fixed参数&#xff1a;①relative生成相对定位的元素&#xff0c;相对于其正常位置进行定位。 ②absolute生成绝对定位的…

django从入门到精通(六)——auth认证及自定义用户

Django 提供了一个强大的用户认证系统&#xff0c;允许开发者轻松管理用户的注册、登录、权限和组等功能。以下是对 Django 用户认证系统的详细介绍&#xff0c;包括默认的用户认证、自定义用户认证和权限设置。 1. 默认用户认证 1.1 用户模型 Django 默认提供了一个用户模型…

Redis/Codis性能瓶颈揭秘:网卡软中断的影响与优化

目录 现象回顾 问题剖析 现场分析 解决方案 总结与反思 1.调整中断亲和性&#xff08;IRQ Affinity&#xff09;&#xff1a; 2.RPS&#xff08;Receive Packet Steering&#xff09;和 RFS&#xff08;Receive Flow Steering&#xff09;&#xff1a; 近期&#xff0c;…

MySQL 中有哪几种锁?

在 MySQL 中&#xff0c;锁&#xff08;Locks&#xff09;是为了保证数据的一致性和完整性而设计的机制。常见的锁可以从粒度和操作类型两个角度分类。以下是详细介绍&#xff1a; 按 粒度 分类 1. 全局锁 描述&#xff1a;锁定整个数据库实例。用途&#xff1a;主要用于备份…

重置docker版本的octoprint管理员账号密码

我的情况是octoprint安装在HiNAS系统的机顶盒上&#xff0c;只有一个账号&#xff0c;但是忘记了用户名和密码。有两个选择&#xff1a; 可以试试先找回用户名&#xff0c;然后尝试你的常用密码。直接重置所有账号。 1.找回用户名&#xff1a; 使用使用 docker exec -it <…

OpenCPN-插件之dashboardsk_pi

官网链接地址 DashboardSK Plugin 当前仅仅是编译和运行,后续需要研究代码! 其中编译的时候需要下载需要依赖libs,之后就可以交叉编译 corey@fcyswrd-15:~/opencpn/opencpnbuildroot/opencpn_plugins/dashboardsk_pi$ git submodule update --init Submodule opencpn-lib…

WordPress设置自动更新CSS版本号

WordPress 通常会在引用 CSS 文件时添加版本号参数&#xff08;?verx.x.x&#xff09;。如果版本号未更新&#xff0c;浏览器可能继续加载旧的文件。 解决方法&#xff1a;确保你在 functions.php 文件中正确加载了 CSS 文件&#xff0c;并动态更新版本号。例如在functions.p…

若依权限控制

springbootvue2项目中的权限控制(若依项目) 步骤: 1.登录管理员账号,为普通用户增加权限按钮 绿色部分为权限控制字符 2.在后端对应的方法上增加权限控制(这里以删除操作为例):PreAuthorize(“ss.hasPermi(‘area:store:remove’)”) 3.在前端对应的按钮上增加权限控制:v-ha…

【机器学习】如何配置anaconda环境(无脑版)

马上就要上机器学习的实验&#xff0c;这里想写一下我配置机器学习的anaconda环境的二三事 一、首先&#xff0c;下载安装包&#xff1a; Download Now | Anaconda 二、打开安装包&#xff0c;一直点NEXT进行安装 这里要记住你要下载安装的路径在哪&#xff0c;后续配置环境…

网络协议之Ethernet

一、Ethernet协议的基本概念、原理和发展历程 **Ethernet&#xff08;以太网&#xff09;**是一种局域网&#xff08;LAN&#xff09;技术&#xff0c;用于在局域网范围内传输数据。它是最常见、最广泛使用的局域网技术之一&#xff0c;允许多台设备&#xff08;如计算机、打印…

论文解析:计算能力资源的可信共享:利益驱动的异构网络服务提供机制

目录 论文解析:计算能力资源的可信共享:利益驱动的异构网络服务提供机制 KM-SMA算法 KM-SMA算法通过不断更新节点的可行顶点标记值(也称为顶标),利用匈牙利方法(Hungarian method)来获取匹配结果。在获取匹配结果后,该算法还会判断该结果是否满足Pareto最优性,即在没…

OceanBase 升级过程研究(4.2.1.6-4.2.1.8)

模拟业务 使用benchmark加载10仓数据模拟业务场景 升级方法 使用滚动升级方式来进行OB升级。该方法前提是OB集群必须满足官方规定的高可用架构(如果 Zone 个数小于 3&#xff0c;滚动升级时则无法构成多数派), 滚动升级的原理就是轮流完成每个ZONE的升级工作&#xff0c;由于…

HTTP 请求方式

深入理解 HTTP 请求方式 在 Web 开发中&#xff0c;HTTP 请求方式起着至关重要的作用。它们决定了客户端如何与服务器进行交互以及服务器如何响应这些请求。本文将深入探讨不同的 HTTP 请求方式及其应用场景。 一、GET 请求 GET 请求是最常见的 HTTP 请求方式之一。它用于从服…