前后端交互之动态列
一. 情景
- 在做项目时,有时候后会遇到后端使用了聚合函数,导致生成的对象的属性数量或数量不固定,因此无法建立一个与之对应的对象来向前端传递数据,
- 这时可以采用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>
相关文章:

前后端交互之动态列
一. 情景 在做项目时,有时候后会遇到后端使用了聚合函数,导致生成的对象的属性数量或数量不固定,因此无法建立一个与之对应的对象来向前端传递数据,这时可以采用NameDataListVO向前端传递数据。 Data Builder AllArgsConstructo…...

递归(3)----力扣40组合数2,力扣473火柴拼正方形
给定一个候选人编号的集合 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。 candidates 中的每个数字在每个组合中只能使用 一次 。 注意:解集不能包含重复的组合。 示例 1: 输入: candidates [10,1,2,7,6,1…...
十一:HTTP 状态码详解:解读每一个响应背后的意义
HTTP(超文本传输协议)是网络通信的基石之一,主要用于客户端(例如浏览器)和服务器之间的通信。为了让服务器能准确地向客户端反馈请求的处理状态,HTTP设计了一套标准的状态码。每一个状态码代表了特定的含义,指示了请求的状态、潜在的问题或成功的信息。 1. 信息响应 (1…...

《译文》2024年11月数维杯国际大学生数学建模挑战赛题目
# 赛题正式发布 2024年第十届数维杯国际大学生数学建模挑战赛顺利开赛,竞赛开始时间为北京时间2024年11月15日09:00至北京时间2024年11月19日09:00,共计4天,竞赛题目正式发布,快来一起围观,你认为今年的哪个题目更具有…...
shell命令统计文件行数之和
你可以使用以下 shell 命令来统计每个 .txt 文件的行数,并将其加和在一起: find . -name "*.txt" -not -name "*.json" -exec wc -l {} + | awk {sum += $1} END {print sum} 解释: find . -name "*.txt" -not -name "*.json": f…...

第02章 CentOS基本操作
2.文件基本操作【文件操作(一)】 目标 理解Linux下路径的表示方法能够使用命令(mkdir和touch)在指定位置创建目录和文件能够使用命令(rm)删除指定的目录和文件能够使用命令(ls)列出目录里的文件能够使用命令(cat,head,tail,less,more)查看文件内容理解标…...
241113.学习日志——[CSDIY] [ByteDance] 后端训练营 [02]
CSDIY:这是一个非科班学生的努力之路,从今天开始这个系列会长期更新,(最好做到日更),我会慢慢把自己目前对CS的努力逐一上传,帮助那些和我一样有着梦想的玩家取得胜利!!&…...

【HOT100第三天】和为K的子数组,最大子数组和,合并区间,轮转数组
今天练的是子串和子数组专题 ~ (前缀和那里差点学死了) 560.和为K的子数组 给你一个整数数组 nums 和一个整数 k ,请你统计并返回 该数组中和为 k 的子数组的个数 。 子数组是数组中元素的连续非空序列。 先写个暴力法,用昨天刚学…...

设计模式-Adapter(适配器模式)GO语言版本
前言 个人感觉Adapter模式核心就在于接口之间的转换。将已有的一些接口转换成其他接口形式。并且一般用于对象上,而不是系统上 问题 就用一个简单的问题,懂数据结构的同学可能知道双端队列。那么就用双端队列实现一个栈(stack)或…...

SAM_Med2D 训练完成后boxes_prompt没有生成mask的问题
之前对着这这篇文章去微调SAM_Med2D(windows环境),发现boxes_prompt空空如也。查找了好长时间问题SAM-Med2D 大模型学习笔记(续):训练自己数据集_sam训练自己数据集-CSDN博客 今天在看label2image_test.json文件的时候发现了一些端倪: 官方…...

游戏引擎学习第18天
clang-format 相关的配置可以参考下面 .clang-format 是用来配置代码格式化规则的文件,主要用于 Clang-Format 工具。以下是 .clang-format 文件中的一些常用设置: 1. 基础设置 Language: Cpp # 指定语言 (C, C, Java, JavaScript, etc…...
Kotlin return与return@forEachIndexed
Kotlin return与returnforEachIndexed fun main() {val data arrayOf(0, 1, 2, 3, 4)println("a")data.forEachIndexed { index, v ->if (v 2) {//类似while循环中的continue//跳过,继续下一个forEachIndexed迭代returnforEachIndexed}println("…...
基于Canny边缘检测和轮廓检测
这段代码实现了基于Canny边缘检测和轮廓检测,从图像中筛选出面积较大的矩形,并使用OpenCV和Matplotlib显示结果。主要流程如下: 步骤详解: 读取图像: img cv2.imread(U:/1.png)使用cv2.imread()加载图像。 转换为灰…...
力扣题目解析--合并k个升序链表
题目 给你一个链表数组,每个链表都已经按升序排列。 请你将所有链表合并到一个升序链表中,返回合并后的链表。 示例 1: 输入:lists [[1,4,5],[1,3,4],[2,6]] 输出:[1,1,2,3,4,4,5,6] 解释:链表数组如下…...

Linux:调试器-gdb/cgdb
文章目录 一、编译成debug1、-g 选项 二、gdb调试命令1、在CentOS系统下检查安装gdb2、进入gdb模式3、quit 退出gdb4、list (简写 l)显示文件内容5、b 打断点6、 r / run运行程序7、c 让程序直接运行完 三、cgdb1、info b查看打的所有断点2、d 删除断点3…...

『VUE』30. 生命周期的介绍(详细图文注释)
目录 生命周期生命周期的8阶段生命周期小例子总结 欢迎关注 『VUE』 专栏,持续更新中 欢迎关注 『VUE』 专栏,持续更新中 生命周期 每个 Vue 组件实例在创建时都需要经历一系列的初始化步骤,比如设置好数据侦听,编译模板…...
Python 人脸检测:使用 Dlib 和 OpenCV
简介 本文用Python、Dlib 和 OpenCV 库来检测图像中的人脸,并在人脸上绘制矩形框进行窗口显示。 环境准备 在开始之前,请确保您的计算机上已安装 Python。此外,您还需要安装以下库: dlib:一个包含多种机器学习算法…...

【大数据学习 | flume】flume的概述与组件的介绍
1. flume概述 Flume是cloudera(CDH版本的hadoop) 开发的一个分布式、可靠、高可用的海量日志收集系统。它将各个服务器中的数据收集起来并送到指定的地方去,比如说送到HDFS、Hbase,简单来说flume就是收集日志的。 Flume两个版本区别: 1&…...
torch.is_storage()
torch.is_storage() 判断给定的对象是否是一个 PyTorch 存储对象 PyTorch 存储对象:PyTorch 中,存储对象(Storage)是一个低级别的对象,它表示一个存储数据的连续内存块。存储对象不包含任何关于数据如何解释的信息&a…...
2411rust,编译时自动检查配置
原文 Cargo和编译器团队很高兴地宣布,从Rust1.80(或nightly-2024-05-05)开始,会自动检查每个可访问的#[cfg],看看是否与期望的配置名和值匹配. 这帮助验证crate,是否正确处理不同目标平台或函数的条件编译.它确保在期望和使用设置的配置间保持一致,帮助在开发过程的早期抓住潜…...

使用VSCode开发Django指南
使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架,专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用,其中包含三个使用通用基本模板的页面。在此…...
Linux链表操作全解析
Linux C语言链表深度解析与实战技巧 一、链表基础概念与内核链表优势1.1 为什么使用链表?1.2 Linux 内核链表与用户态链表的区别 二、内核链表结构与宏解析常用宏/函数 三、内核链表的优点四、用户态链表示例五、双向循环链表在内核中的实现优势5.1 插入效率5.2 安全…...
多场景 OkHttpClient 管理器 - Android 网络通信解决方案
下面是一个完整的 Android 实现,展示如何创建和管理多个 OkHttpClient 实例,分别用于长连接、普通 HTTP 请求和文件下载场景。 <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas…...
FastAPI 教程:从入门到实践
FastAPI 是一个现代、快速(高性能)的 Web 框架,用于构建 API,支持 Python 3.6。它基于标准 Python 类型提示,易于学习且功能强大。以下是一个完整的 FastAPI 入门教程,涵盖从环境搭建到创建并运行一个简单的…...
Neo4j 集群管理:原理、技术与最佳实践深度解析
Neo4j 的集群技术是其企业级高可用性、可扩展性和容错能力的核心。通过深入分析官方文档,本文将系统阐述其集群管理的核心原理、关键技术、实用技巧和行业最佳实践。 Neo4j 的 Causal Clustering 架构提供了一个强大而灵活的基石,用于构建高可用、可扩展且一致的图数据库服务…...

Python基于历史模拟方法实现投资组合风险管理的VaR与ES模型项目实战
说明:这是一个机器学习实战项目(附带数据代码文档),如需数据代码文档可以直接到文章最后关注获取。 1.项目背景 在金融市场日益复杂和波动加剧的背景下,风险管理成为金融机构和个人投资者关注的核心议题之一。VaR&…...

人机融合智能 | “人智交互”跨学科新领域
本文系统地提出基于“以人为中心AI(HCAI)”理念的人-人工智能交互(人智交互)这一跨学科新领域及框架,定义人智交互领域的理念、基本理论和关键问题、方法、开发流程和参与团队等,阐述提出人智交互新领域的意义。然后,提出人智交互研究的三种新范式取向以及它们的意义。最后,总结…...
Go 并发编程基础:通道(Channel)的使用
在 Go 中,Channel 是 Goroutine 之间通信的核心机制。它提供了一个线程安全的通信方式,用于在多个 Goroutine 之间传递数据,从而实现高效的并发编程。 本章将介绍 Channel 的基本概念、用法、缓冲、关闭机制以及 select 的使用。 一、Channel…...

【JVM】Java虚拟机(二)——垃圾回收
目录 一、如何判断对象可以回收 (一)引用计数法 (二)可达性分析算法 二、垃圾回收算法 (一)标记清除 (二)标记整理 (三)复制 (四ÿ…...

Linux nano命令的基本使用
参考资料 GNU nanoを使いこなすnano基础 目录 一. 简介二. 文件打开2.1 普通方式打开文件2.2 只读方式打开文件 三. 文件查看3.1 打开文件时,显示行号3.2 翻页查看 四. 文件编辑4.1 Ctrl K 复制 和 Ctrl U 粘贴4.2 Alt/Esc U 撤回 五. 文件保存与退出5.1 Ctrl …...