前后端交互之动态列
一. 情景
- 在做项目时,有时候后会遇到后端使用了聚合函数,导致生成的对象的属性数量或数量不固定,因此无法建立一个与之对应的对象来向前端传递数据,
- 这时可以采用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,是否正确处理不同目标平台或函数的条件编译.它确保在期望和使用设置的配置间保持一致,帮助在开发过程的早期抓住潜…...

第19节 Node.js Express 框架
Express 是一个为Node.js设计的web开发框架,它基于nodejs平台。 Express 简介 Express是一个简洁而灵活的node.js Web应用框架, 提供了一系列强大特性帮助你创建各种Web应用,和丰富的HTTP工具。 使用Express可以快速地搭建一个完整功能的网站。 Expre…...
IGP(Interior Gateway Protocol,内部网关协议)
IGP(Interior Gateway Protocol,内部网关协议) 是一种用于在一个自治系统(AS)内部传递路由信息的路由协议,主要用于在一个组织或机构的内部网络中决定数据包的最佳路径。与用于自治系统之间通信的 EGP&…...
基于Uniapp开发HarmonyOS 5.0旅游应用技术实践
一、技术选型背景 1.跨平台优势 Uniapp采用Vue.js框架,支持"一次开发,多端部署",可同步生成HarmonyOS、iOS、Android等多平台应用。 2.鸿蒙特性融合 HarmonyOS 5.0的分布式能力与原子化服务,为旅游应用带来…...
爬虫基础学习day2
# 爬虫设计领域 工商:企查查、天眼查短视频:抖音、快手、西瓜 ---> 飞瓜电商:京东、淘宝、聚美优品、亚马逊 ---> 分析店铺经营决策标题、排名航空:抓取所有航空公司价格 ---> 去哪儿自媒体:采集自媒体数据进…...

C++使用 new 来创建动态数组
问题: 不能使用变量定义数组大小 原因: 这是因为数组在内存中是连续存储的,编译器需要在编译阶段就确定数组的大小,以便正确地分配内存空间。如果允许使用变量来定义数组的大小,那么编译器就无法在编译时确定数组的大…...

佰力博科技与您探讨热释电测量的几种方法
热释电的测量主要涉及热释电系数的测定,这是表征热释电材料性能的重要参数。热释电系数的测量方法主要包括静态法、动态法和积分电荷法。其中,积分电荷法最为常用,其原理是通过测量在电容器上积累的热释电电荷,从而确定热释电系数…...

MySQL 知识小结(一)
一、my.cnf配置详解 我们知道安装MySQL有两种方式来安装咱们的MySQL数据库,分别是二进制安装编译数据库或者使用三方yum来进行安装,第三方yum的安装相对于二进制压缩包的安装更快捷,但是文件存放起来数据比较冗余,用二进制能够更好管理咱们M…...
C#学习第29天:表达式树(Expression Trees)
目录 什么是表达式树? 核心概念 1.表达式树的构建 2. 表达式树与Lambda表达式 3.解析和访问表达式树 4.动态条件查询 表达式树的优势 1.动态构建查询 2.LINQ 提供程序支持: 3.性能优化 4.元数据处理 5.代码转换和重写 适用场景 代码复杂性…...
LangFlow技术架构分析
🔧 LangFlow 的可视化技术栈 前端节点编辑器 底层框架:基于 (一个现代化的 React 节点绘图库) 功能: 拖拽式构建 LangGraph 状态机 实时连线定义节点依赖关系 可视化调试循环和分支逻辑 与 LangGraph 的深…...
Netty自定义协议解析
目录 自定义协议设计 实现消息解码器 实现消息编码器 自定义消息对象 配置ChannelPipeline Netty提供了强大的编解码器抽象基类,这些基类能够帮助开发者快速实现自定义协议的解析。 自定义协议设计 在实现自定义协议解析之前,需要明确协议的具体格式。例如,一个简单的…...