自定义复杂AntV/G6案例
一、效果图
二、源码
/**
*
* Author: me
* CreatDate: 2024-08-22
*
* Description: 复杂G6案例
*
*/
<template><div class="moreG6-wapper"><div id="graphContainer" ref="graphRef" class="graph-content"></div></div>
</template><script>
import G6 from "@antv/g6";
export default {name: "moreG6",components: {},props: {},data() {return {graph: null, // G6 实例graphData: {nodes: [],edges: [],},dataList: [{name: "第一阶段",aimData: [{title: "张三",aim: "战胜李四",type: 1,},{title: "李四",aim: "战胜张三",type: 2,},],eventData: [{time: "1948年11月6日",isLeft: true, // 在左边还是在右边dataList: {title: "发现王五正在收缩",type: 1,domain: "综合",describe: "发现王五正在收缩,当即转入追击",children: [{title: "张三攻占a区,没发现李四",type: 1,domain: "战斗",describe: "",},{title: "李四调动李白",type: 1,domain: "战斗",describe: "",},],},},{time: "1948年11月7日",isLeft: false,dataList: {title: "张三团守a州,同时向b州东进",type: 2,domain: "综合",describe: "张三团守a州,令小红、小兰两人回b州东进",children: [{title: "李四在b官邸",type: 2,domain: "战斗",describe: "",},],},},],},{name: "第二阶段",aimData: [{title: "小红",aim: "战胜王五",type: 1,},{title: "小兰",aim: "战胜王五",type: 1,},{title: "王五",aim: "战胜张三",type: 2,},],eventData: [{time: "1948年11月6日",isLeft: true,dataList: {title: "发现王五正在收缩",type: 1,domain: "综合",describe: "发现王五正在收缩,当即转入追击",children: [{title: "张三攻占a区,没发现李四",type: 1,domain: "战斗",describe: "",},{title: "李四调动李白",type: 1,domain: "战斗",describe: "",},{title: "李四造谣张三",type: 1,domain: "舆论",describe: "",},],},},{time: "1948年11月7日",isLeft: false,dataList: {title: "张三团守a州",type: 2,domain: "综合",describe: "张三团守a州,令小红、小兰两人回徐州东进",children: [{title: "李四在b官邸",type: 2,domain: "前进",describe: "",},{title: "小兰垄断李四的口粮",type: 2,domain: "商战",describe: "",},],},},],},{name: "第三阶段",},{name: "第四阶段",},],bgColor: "#0B1E4C",stageSize: [110, 40],aimSize: [150, 30],eventSize: [176, 46],eventContentSize: [182, 90],eventDataSize: [120, 40],stageSpace: 100,openSpace: 40,aimSpace: 150,eventSpace: 220,domainW: 28,};},mounted() {this.$nextTick(() => {this.initData();this.initGraph();this.drawGraph();});},methods: {/*** 根据数据生成节点和边数据*/initData() {const that = this;const dom = this.$refs.graphRef;const centerX = dom.offsetWidth / 2;this.dataList.forEach((stage, index) => {const pl = ((stage.partieList?.length || 0) / 2) * that.aimSize[1];let eventLen = 0;if (index === 0) {stage.y = 40 + pl;} else {eventLen = this.dataList[index - 1].eventData?.length || 0;stage.y =this.dataList[index - 1].y +eventLen * that.eventSpace +that.stageSpace * 2 +pl;}// 1.阶段总线const stageNde = {id: `stageNode${index}`, // 元素的 idlabel: stage.name, // 标签文字x: centerX,y: stage.y,type: "rect", // 元素的图形size: that.stageSize, // 元素的大小// 标签配置属性labelCfg: {positions: "center", // 标签在元素中的位置// 包裹标签样式属性的字段 style 与标签其他属性在数据结构上并行style: {fill: "#fff", // 填充色,这里是文字颜色fontSize: 16,// fontWeight: "bold",fontFamily: "黑体",},},// 包裹样式属性的字段 style 与其他属性在数据结构上并行style: {lineWidth: 2,fill: "#0F3664", // 元素的填充色stroke: "#fff", // 元素的描边色radius: 20, // 圆角},// 锚点anchorPoints: [[1, 0.5], // 右中[0.5, 1], // 下中],};this.graphData.nodes.push(stageNde);if (index !== 0) {const stageLine = {id: `stageLine${index}`,source: `stageNode${index - 1}`, // 和上面的保持一致target: `stageNode${index}`,type: "line", // 边形状style: {lineWidth: 2,color: "#fff",opacity: 0.7, // 边透明度},};this.graphData.edges.push(stageLine);}// 2.阶段-目标数据if (stage.aimData && stage.aimData.length) {const adl = stage.aimData.length;// 目标数据stage.aimData.forEach((aim, aimIndex) => {// aimNodeY 先大概吧,后面再重新计算优化一下const aimNodeY =stage.y + (that.aimSize[1] + 10) * aimIndex - pl - adl * 12;// 目标标题const aimNode = {id: `aimNode${index}${aimIndex}`,label: aim.title + "目标",x: centerX + that.stageSize[0] + that.openSpace * 2.5,y: aimNodeY,type: "rect",size: that.aimSize,labelCfg: {style: {textAlign: "center",fill: "#fff",fontSize: 14,fontFamily: "黑体",},},style: {lineWidth: 0,fill: aim.type === 1 ? "#E16E76" : "#1685F3",radius: [0, 15, 15, 0],},anchorPoints: [[0, 0.5],[1, 0.5],],};this.graphData.nodes.push(aimNode);// 目标内容const aimContentNode = {id: `aimContentNode${index}${aimIndex}`,label: aim.aim,x: centerX + that.stageSize[0] + that.openSpace * 6.5,y: aimNodeY,type: "rect",size: [0, 40],labelCfg: {positions: "left",style: {textAlign: "left",fill: "#fff",fontSize: 14,opacity: 0.7,fontFamily: "黑体",},},style: {lineWidth: 0,fill: that.bgColor,},anchorPoints: [[0, 0.5]],};this.graphData.nodes.push(aimContentNode);// 连线const aimLine = {id: `aimLine${index}${aimIndex}`,source: `stageNode${index}`,target: `aimNode${index}${aimIndex}`,type: "cubic-horizontal", // 边形状style: {lineWidth: 1,fill: "transparent", // 设置透明背景色opacity: 0.7,},};const aimContentLine = {id: `aimContentLine${index}${aimIndex}`,source: `aimNode${index}${aimIndex}`,target: `aimContentNode${index}${aimIndex}`,type: "line", // 边形状style: {lineWidth: 1,fill: "#ffffff",opacity: 0.7,},};this.graphData.edges.push(aimLine);this.graphData.edges.push(aimContentLine);});}// 3.时间事件数据if (stage.eventData && stage.eventData.length) {stage.eventData.forEach((event, eventIndex) => {event.x = event.isLeft? -centerX + that.stageSize[0] + that.openSpace * 4: centerX + that.stageSize[0] + that.openSpace * 4;event.y =stage.y +eventIndex * that.eventSpace +that.aimSize[1] +that.openSpace * 2.5; // 先大概吧,后面再重新计算优化一下// 时间const timeNode = {id: `timeNode${index}${eventIndex}`,label: event.time,x: event.isLeft ? centerX - 10 : centerX + 10,y: event.y - 16,type: "rect",size: [0, 40],labelCfg: {positions: event.isLeft ? "right" : "left",style: {textAlign: event.isLeft ? "right" : "left",fill: "#fff",fontSize: 14,opacity: 0.8,fontFamily: "黑体",},},style: {lineWidth: 0,fill: that.bgColor,},};this.graphData.nodes.push(timeNode);// 事件标题const eventNode = {id: `eventNode${index}${eventIndex}`,label: that.fittingString(event.dataList.title, 9),labelInit: event.dataList.title,x: event.isLeft? -event.x - that.domainW + 12: event.x + that.domainW - 12,y: event.y,type: "rect",size: that.eventSize,labelCfg: {positions: event.isLeft ? "right" : "left",style: {textAlign: "center",fill: "#fff",fontSize: 14,fontFamily: "黑体",},},style: {lineWidth: 0,fill: event.dataList.type === 1 ? "#E16E76" : "#1685F3",radius: event.isLeft ? [24, 0, 0, 24] : [0, 24, 24, 0],},anchorPoints: [[0, 0.5],[1, 0.5],],};this.graphData.nodes.push(eventNode);// 领域const realmNode = {id: `realmNode${index}${eventIndex}`,label: [...event.dataList.domain].join("\n"),x: event.isLeft? -event.x + that.openSpace * 2 + 6: event.x - that.openSpace * 2 - 6,y: event.y,type: "rect",size: [that.domainW, that.eventSize[1]],labelCfg: {positions: "center",style: {textAlign: "center",fill: "#fff",fontSize: 14,fontFamily: "黑体",},},style: {lineWidth: 1,fill: event.dataList.type === 1 ? "#E16E76" : "#1685F3",stroke: event.dataList.type === 1 ? "#EDA9AE" : "#76B7F8", // 元素的描边色},};this.graphData.nodes.push(realmNode);// 内容const eventContentNode = {id: `eventContentNode${index}${eventIndex}`,label: event.dataList.describe? that.divideString(event.dataList.describe, 11, 4): "暂无描述",labelInit: event.dataList.describe,x: event.isLeft ? -event.x + 9 : event.x - 9,y: event.y + that.eventSize[1] + 22,type: "rect",size: that.eventContentSize,labelCfg: {positions: "center",style: {textAlign: "center",fill: "#fff",fontSize: 14,fontFamily: "黑体",},},style: {lineWidth: 1,fill: "#3C4B70",stroke: "#5C6988", // 元素的描边色opacity: 0.9,},};this.graphData.nodes.push(eventContentNode);// 连线const eventLine = {id: `eventLine${index}${eventIndex}`,source: `stageNode${index}`,target: `eventNode${index}${eventIndex}`,type: "polyline", // 边形状style: {lineWidth: 1,fill: "transparent",opacity: 0.7,},};this.graphData.edges.push(eventLine);// 4.时间事件后面的列表if (event.dataList.children && event.dataList.children.length) {event.dataList.children.forEach((eventData, eventDataIndex) => {const x =event.x +that.eventSize[0] +that.openSpace * 3 +eventDataIndex *(that.eventDataSize[0] + that.openSpace * 1.4);const y = event.y + that.openSpace;// 标题const eventDataNode = {id: `eventDataNode${index}${eventIndex}${eventDataIndex}`,label: that.fittingString(eventData.title, 6),labelInit: eventData.title,x: event.isLeft? -x - that.domainW + 14: x + that.domainW - 14,y: y,type: "rect",size: that.eventDataSize,labelCfg: {positions: event.isLeft ? "right" : "left",style: {textAlign: "center",fill: "#fff",fontSize: 14,fontFamily: "黑体",},},style: {lineWidth: 0,fill: event.dataList.type === 1 ? "#E16E76" : "#1685F3",},anchorPoints: [[0.5, 0]],};this.graphData.nodes.push(eventDataNode);// 领域const realmNode02 = {id: `realmNode${index}${eventIndex}${eventDataIndex}02`,label: [...eventData.domain].join("\n"),x: event.isLeft ? -x + 60 : x - 60,y: y,type: "rect",size: [that.domainW, that.eventDataSize[1]],labelCfg: {positions: "center",style: {textAlign: "center",fill: "#fff",fontSize: 14,fontFamily: "黑体",},},style: {lineWidth: 1,fill: event.dataList.type === 1 ? "#E16E76" : "#1685F3",stroke: event.dataList.type === 1 ? "#EDA9AE" : "#76B7F8", // 元素的描边色},};this.graphData.nodes.push(realmNode02);// 内容const eventContentNode02 = {id: `eventContentNode${index}${eventIndex}${eventDataIndex}02`,label: eventData.describe? that.divideString(eventData.describe, 9, 3): "暂无描述",labelInit: eventData.describe,x: event.isLeft ? -x : x,y: y + that.eventDataSize[1] + 18,type: "rect",size: [that.eventDataSize[0] + that.domainW,that.eventContentSize[1] * 0.85,],labelCfg: {positions: "center",style: {textAlign: "center",fill: "#fff",fontSize: 14,fontFamily: "黑体",},},style: {lineWidth: 1,fill: "#3C4B70",stroke: "#5C6988",opacity: 0.9,},};this.graphData.nodes.push(eventContentNode02);// 连线const eventLine = {id: `eventLine${index}${eventIndex}${eventDataIndex}`,source: `eventNode${index}${eventIndex}`,target: `eventDataNode${index}${eventIndex}${eventDataIndex}`,type: "polyline", // 边形状style: {lineWidth: 1,fill: "transparent", // 透明色opacity: 0.7,},};this.graphData.edges.push(eventLine);});}});}});},/*** 初始化graph实例*/initGraph() {// 缩略图const minimap = new G6.Minimap({size: [window.innerWidth / 6, window.innerHeight / 4],});// 提示框const tooltip = new G6.Tooltip({offsetX: 10,offsetY: 10,size: [100, 100],itemTypes: ["node"], // 允许出现 tooltip 的 item 类型// 自定义 tooltip 内容getContent: (e) => {const outDiv = document.createElement("div");outDiv.style.width = "fit-content";outDiv.innerHTML = `<div style="max-width:200px;">${e.item.getModel().labelInit || e.item.getModel().label}</div>`;return outDiv;},// 哪些要设置提示框shouldBegin: (e) => {const id = e.item.getModel().id;const a = id.includes("eventNode");const b = id.includes("eventContentNode");const c = id.includes("eventDataNode");const is = a || b || c;return is;},});// 容器节点const dom = this.$refs.graphRef;// 配置参数const options = {container: "graphContainer", // 画布的容器idwith: dom.offsetWidth, // 画布宽度height: dom.offsetHeight, // 画布高度minZoom: 0.2,maxZoom: 5,// 图交互模式modes: {default: ["drag-canvas", "zoom-canvas"], // 允许拖拽画布、缩放画布},plugins: [tooltip, minimap], // 插件};// 实例化this.graph = new G6.Graph(options);// 自适应this.resizeView();// 监听窗口大小变化window.addEventListener("resize", this.resizeView);},/*** 画图*/drawGraph() {// 清除画布元素this.graph.clear();// 数据源this.graph.data(this.graphData);// 渲染this.graph.render();},/*** 自适应*/resizeView() {const dom = this.$refs.graphRef;if (dom && this.graph) {this.graph.changeSize(dom.offsetWidth, dom.offsetHeight); // 修改画布大小// this.graph.fitCenter(); // 移至中心}},/*** 字符串等长划分-入口事件* @param str 字符串* @param len 一行的长度* @param row 行数*/divideString(str, len, row = 3) {str = this.fittingString(str, len * row - 2);const result = this.divideHandle(str, len);return result.join("\n");},/*** 字符串等长划分* @param str 字符串* @param len 划分的长度*/divideHandle(str, len) {if (str.length <= len) {return [str];}const chunk = str.substring(0, len);const arr = [chunk, ...this.divideHandle(str.substring(len), len)];return arr;},/*** 截取字符串,超出多少len省略* @param str 字符串* @param len 长度*/fittingString(str, len) {if (str.length <= len) {return str;}const result = str.substring(0, len) + "…";return result;},},beforeDestroy() {this.graph && this.graph.destroy();},watch: {},
};
</script><style lang='scss' scoped>
.moreG6-wapper {height: 100%;background: #0b1e4c;.graph-content {width: 100%;height: 96%;::v-deep .g6-tooltip {border: 1px solid #e2e2e2;border-radius: 4px;font-size: 12px;color: #545454;background-color: rgba(255, 255, 255, 0.9);padding: 10px 8px;box-shadow: rgb(174, 174, 174) 0px 0px 10px;}::v-deep .g6-minimap {position: absolute;right: 0;top: 61px;background-color: #0b1e4c;}}
}
</style>
三、记录说明
-
当前使用版本:
"@antv/g6": "^4.8.21"
-
官方文档节点形状为shape,但是在不记得哪个版本后,
shape
改为type
,当时整了好久,形状就是不生效,原来是字段改变了,这个坑要注意 -
初步接触就有这么个界面需求,官方文档有点乱,且不全面,新手小白上路属实有点头皮发麻,后来也琢磨出来一些:
- 官方案例实现不了的,自己画
- 无非就是两个要点:节点、边
- 像这案例一样的不能使用居中api的,得自己计算节点的位置
- 实现不了的不影响使用的小功能,就干掉它,不要了…
-
期间遇到还没解决的问题:
- 使用
image
内置节点,自己的图片显示有问题 polyline
样式的连线拐点问题,本来定在边角的锚点,但是拐点太多了不齐整,后来就直接锚点在中间了…- 本来有个节点收缩/展开的功能,后来没做了,这个后面再研究研究…
- 使用
相关文章:

自定义复杂AntV/G6案例
一、效果图 二、源码 /** * * Author: me * CreatDate: 2024-08-22 * * Description: 复杂G6案例 * */ <template><div class"moreG6-wapper"><div id"graphContainer" ref"graphRef" class"graph-content"></d…...

Golang | Leetcode Golang题解之第419题棋盘上的战舰
题目: 题解: func countBattleships(board [][]byte) (ans int) {for i, row : range board {for j, ch : range row {if ch X && !(i > 0 && board[i-1][j] X || j > 0 && board[i][j-1] X) {ans}}}return }...
CCF刷题计划——LDAP(交集、并集 how to go)
LDAP 计算机软件能力认证考试系统 不知道为什么,直接给我报一个运行错误,得了0分。但是我在Dev里,VS里面都跑的好好的,奇奇怪怪。如果有大佬路过,请帮小弟看看QWQ。本题学到的:交集set_intersection、并集…...

谷歌论文提前揭示o1模型原理:AI大模型竞争或转向硬件
Open AI最强模型o1的护城河已经没有了?仅在OpenAI发布最新推理模型o1几日之后,海外社交平台 Reddit 上有网友发帖称谷歌Deepmind在 8 月发表的一篇论文内容与o1模型原理几乎一致,OpenAI的护城河不复存在。 谷歌DeepMind团队于今年8月6日发布…...

【ShuQiHere】 探索数据挖掘的世界:从概念到应用
🌐 【ShuQiHere】 数据挖掘(Data Mining, DM) 是一种从大型数据集中提取有用信息的技术,无论是在商业分析、金融预测,还是医学研究中,数据挖掘都扮演着至关重要的角色。本文将带您深入了解数据挖掘的核心概…...

LabVIEW提高开发效率技巧----使用事件结构优化用户界面响应
事件结构(Event Structure) 是 LabVIEW 中用于处理用户界面事件的强大工具。通过事件驱动的编程方式,程序可以在用户操作时动态执行特定代码,而不是通过轮询(Polling)的方式不断检查界面控件状态。这种方式…...
【前端】ES6:Set与Map
文章目录 1 Set结构1.1 初识Set1.2 实例的属性和方法1.3 遍历1.4 复杂数据结构去重 2 Map结构2.1 初识Map2.2 实例的属性和方法2.3 遍历 1 Set结构 它类似于数组,但成员的值都是唯一的,没有重复的值。 1.1 初识Set let s1 new Set([1, 2, 3, 2, 3]) …...
Java 之网络编程小案例
1. 多发多收 描述: 编写一个简单的聊天程序,客户端可以向服务器发送多条消息,服务器可以接收所有消息并回复。 代码示例: 服务器端 (Server.java): import java.io.*; import java.net.*; import java.util.concurrent.Execut…...
Spring Boot:现代化Java应用开发的艺术
目录 什么是Spring Boot? 为什么选择Spring Boot? Spring Boot的核心概念 详细步骤:创建一个Spring Boot应用 步骤1:使用Spring Initializr创建项目 步骤2:解压并导入项目 步骤3:构建和配置项目 po…...
Redis五种基本数据结构的使用
Redis具有五种基本数据类型:String(字符串)、Hash(哈希)、List(列表)、Set(集合)、SortedSet(有序集合),下面示意它们的使用。 String类数据类型的使用 增:添加数据(set)、添加多个数据(mset)、添加数据时指定过期时间(setex) 删…...

【QT】系统-下
欢迎来到Cefler的博客😁 🕌博客主页:折纸花满衣 🏠个人专栏:QT 目录 👉🏻QTheadrun() 👉🏻QMutex👉🏻QWaitCondition👉🏻Q…...
java和kotlin 可以同时运行吗
Java 和 Kotlin 可以同时运行在同一个项目中,这主要得益于 Kotlin 对 Java 的互操作性。Kotlin 被设计为与 Java 100% 兼容,这意味着 Kotlin 代码可以很容易地调用 Java 代码,反之亦然。这种设计使得 Kotlin 能够无缝集成到现有的 Java 项目中…...

2024最新版 Tuxera NTFS for Mac 2023绿色版图文安装教程
在数字化时代,数据的存储和传输变得至关重要。Mac用户经常需要在Windows NTFS格式的移动硬盘上进行读写操作,然而,由于MacOS系统默认不支持NTFS的写操作,这就需要我们寻找一款高效的读写软件。Tuxera NTFS for Mac 2023便是其中…...
npm发布插件超级简单版
在开源的世界里,每个人都有机会成为贡献者,甚至是创新的引领者。您是否有过这样的想法:开发一个解决特定问题的小工具,让他成为其他开发者手中的利器?今天,我们就来一场实战训练,学习如何将你的…...

C# 访问Access存取图片
图片存入ole字段,看有的代码是获取图片的字节数组转换为base64字符串,存入数据库;显示图片是把base64字符串转换为字节数组再显示;直接存字节数组可能还好一点; 插入的时候用带参数的sql写法比较好;用拼接…...
正则表达式中常见字符的用法介绍
正则表达式(Regular Expression,简称Regex)是一种文本模式描述的方法,包括普通字符(如a到z之间的字母)和特殊字符(称为“元字符”)。正则表达式使用单个字符串来描述、匹配一系列符合…...

Vue3.0组合式API:依赖注入provide和inject实现跨层组件的通信
Vue3.0组合式API系列文章: 《Vue3.0组合式API:setup()函数》 《Vue3.0组合式API:使用reactive()、ref()创建响应式代理对象》 《Vue3.0组合式API:computed计算属性、watch监听器、watchEffect高级监听器》 《Vue3.0组合式API&…...
VSCode中配置C/C++环境
在Visual Studio Code(VSCode)中配置C/C环境是一个相对直接且功能强大的过程,它能让开发者利用VSCode的诸多便利功能来编写、编译和调试C/C代码。以下是一个详细的步骤指南,涵盖了从安装必要的软件到配置编译器、调试器以及VSCode…...

vue实现鼠标滚轮控制页面横向滑动
先看效果 20240919_095531 1.首先创建一个xScroll.vue组件 <template><div class"main" v-size-ob"mainSize"><div class"v-scroll"><div class"content"><slot></slot></div></div>…...

【Git使用】删除Github仓库中的指定文件/文件夹
前言: 上篇文章带大家上传了第一个项目至github,那要是想删除仓库中的指定文件夹怎么办?在Github中 仓库是无法通过鼠标操作直接删除文件和文件夹的,那只能通过 git 命令来执行删除操作。接下来就带大家进行操作。 详细步骤: 一…...

Debian系统简介
目录 Debian系统介绍 Debian版本介绍 Debian软件源介绍 软件包管理工具dpkg dpkg核心指令详解 安装软件包 卸载软件包 查询软件包状态 验证软件包完整性 手动处理依赖关系 dpkg vs apt Debian系统介绍 Debian 和 Ubuntu 都是基于 Debian内核 的 Linux 发行版ÿ…...
C++ 基础特性深度解析
目录 引言 一、命名空间(namespace) C 中的命名空间 与 C 语言的对比 二、缺省参数 C 中的缺省参数 与 C 语言的对比 三、引用(reference) C 中的引用 与 C 语言的对比 四、inline(内联函数…...

UR 协作机器人「三剑客」:精密轻量担当(UR7e)、全能协作主力(UR12e)、重型任务专家(UR15)
UR协作机器人正以其卓越性能在现代制造业自动化中扮演重要角色。UR7e、UR12e和UR15通过创新技术和精准设计满足了不同行业的多样化需求。其中,UR15以其速度、精度及人工智能准备能力成为自动化领域的重要突破。UR7e和UR12e则在负载规格和市场定位上不断优化…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...

AI书签管理工具开发全记录(十九):嵌入资源处理
1.前言 📝 在上一篇文章中,我们完成了书签的导入导出功能。本篇文章我们研究如何处理嵌入资源,方便后续将资源打包到一个可执行文件中。 2.embed介绍 🎯 Go 1.16 引入了革命性的 embed 包,彻底改变了静态资源管理的…...

学校时钟系统,标准考场时钟系统,AI亮相2025高考,赛思时钟系统为教育公平筑起“精准防线”
2025年#高考 将在近日拉开帷幕,#AI 监考一度冲上热搜。当AI深度融入高考,#时间同步 不再是辅助功能,而是决定AI监考系统成败的“生命线”。 AI亮相2025高考,40种异常行为0.5秒精准识别 2025年高考即将拉开帷幕,江西、…...
React---day11
14.4 react-redux第三方库 提供connect、thunk之类的函数 以获取一个banner数据为例子 store: 我们在使用异步的时候理应是要使用中间件的,但是configureStore 已经自动集成了 redux-thunk,注意action里面要返回函数 import { configureS…...

安宝特案例丨Vuzix AR智能眼镜集成专业软件,助力卢森堡医院药房转型,赢得辉瑞创新奖
在Vuzix M400 AR智能眼镜的助力下,卢森堡罗伯特舒曼医院(the Robert Schuman Hospitals, HRS)凭借在无菌制剂生产流程中引入增强现实技术(AR)创新项目,荣获了2024年6月7日由卢森堡医院药剂师协会࿰…...

LINUX 69 FTP 客服管理系统 man 5 /etc/vsftpd/vsftpd.conf
FTP 客服管理系统 实现kefu123登录,不允许匿名访问,kefu只能访问/data/kefu目录,不能查看其他目录 创建账号密码 useradd kefu echo 123|passwd -stdin kefu [rootcode caozx26420]# echo 123|passwd --stdin kefu 更改用户 kefu 的密码…...
Python 训练营打卡 Day 47
注意力热力图可视化 在day 46代码的基础上,对比不同卷积层热力图可视化的结果 import torch import torch.nn as nn import torch.optim as optim from torchvision import datasets, transforms from torch.utils.data import DataLoader import matplotlib.pypl…...