数据可视化前端图表库【免费下载链接】G6♾ A Graph Visualization Framework in JavaScript.项目地址https://gitcode.com/gh_mirrors/g6/G6点击查看免费下载导读G6 是一个以数据驱动的 JavaScript 图可视化框架图数据的组织方式直接决定了图的渲染结果与交互行为。本文基于 packages/site/docs/manual/data.en.md 展开系统讲解 G6 的GraphData数据结构节点、边、Combo 三要素、各字段的语义与类型约束、数据组织的推荐实践并结合仓库源码剖析getData、addData、updateData、removeData等数据 API 的底层实现与调用链。读完本文你将掌握如何用标准 JSON 描述一张图、如何正确存放业务数据以避免与 G6 内部字段冲突以及如何通过数据 API 对图执行增删改查并理解其内部合并与变更机制。数据驱动的图为什么数据是 G6 的核心G6 是典型的数据驱动data-driven图可视化库数据是图的“唯一事实来源”。在 G6 中展示和交互都基于数据节点的位置、大小、颜色边的样式Combo 的折叠状态等全部由数据经样式映射推导而来用户拖拽、框选等行为产生的变更最终也会写回数据模型。因此理解 G6 的数据结构是使用 G6 的第一步也是后续自定义扩展、性能优化的基础。常见的图数据交换格式包括 CSV、DOT、GDF、GML、GraphML、GEXF 等而 G6 选用JSON来描述图结构。JSON 相比上述格式的优势在于结构直观节点与边的信息以键值对形式平铺表达可读性强扩展灵活可以随时为节点或边追加任意自定义属性兼容性好JSON 是计算机世界广泛支持的数据交换格式无需担心格式兼容问题。一个最简的 G6 图数据如下{ nodes: [{ id: node1 }, { id: node2 }], edges: [{ source: node1, target: node2 }] }GraphData 数据结构节点、边与 Combo在 G6 中一张图的数据由三部分组成nodes节点数据、edges边数据与combosCombo 数据三者分别对应图中的不同元素其类型与取值共同决定图的呈现方式。源码中的类型定义见 packages/g6/src/spec/data.ts如下interface GraphData { nodes?: NodeData[]; // 节点数据 edges?: EdgeData[]; // 边数据可选 combos?: ComboData[]; // Combo 数据可选 }注意实际源码中nodes、edges、combos均为可选字段以?标记只有nodes在语义上是图的主体边与 Combo 可以按需提供。NodeData节点数据节点是图的基本构成单元代表图中的实体如人、系统、事件。每个节点拥有唯一的id用于标识同时可以携带数据data、样式style与状态states。属性类型说明id必填string节点唯一标识用于区分不同节点typestring节点类型可以是内置节点类型或自定义节点类型dataObject节点的自定义业务数据如 name、description 等可在样式映射中通过回调函数访问styleObject节点样式包括位置、尺寸、颜色等视觉属性statesstring[]节点的初始状态如 selected、active、hover 等combostring|null节点所属 Combo 的 ID用于组织层级关系无归属时为 nullchildrenstring[]子节点 ID 集合仅用于树图结构示例{ id: node-1, type: circle, data: { name: alice, role: Admin }, style: { x: 100, y: 200, size: 32, fill: violet }, states: [selected], combo: null }对照源码 packages/g6/src/spec/data.tsNodeData还包含depth?: number节点深度仅用于树图以及[key: string]: unknown索引签名。索引签名的存在意味着 G6 允许你在节点上直接挂载任意自定义字段——但从官方最佳实践看业务数据仍应放进data字段以保证与样式映射、数据比较等内部机制的兼容。EdgeData边数据边连接两个节点代表节点之间的关系。每条边关联两个节点source与target边本身同样可以携带数据、样式与状态。边的数据常用来表达逻辑关系例如社交网络中的用户关联、流程图中的步骤流转。属性类型说明source必填string源节点 IDtarget必填string目标节点 IDidstring边的唯一标识若不指定将自动生成${source}-${target}格式的 IDtypestring边类型可以是内置边类型或自定义边类型dataObject边的自定义业务数据可在样式映射中通过回调函数访问styleObject边样式包括描边颜色、线宽、箭头等statesstring[]边的初始状态示例{ source: alice, target: bob, type: line, data: { relationship: friend, strength: 5 }, style: { stroke: green, lineWidth: 2 }, states: [hover] }从源码看EdgeData中id、source、target之外的字段均为可选见 packages/g6/src/spec/data.ts但source与target为必填。边 ID 的自动生成规则${source}-${target}在文档中明确给出这意味着同一对节点间只允许存在一条不带显式id的边若需要表达多条并行边应显式指定不同的id可参考测试数据集 packages/g6/tests/dataset/parallel-edges.json 与 element-edges.json 中的真实用法。ComboDataCombo 数据Combo 用于将多个节点组织为一个逻辑单元实现分层、分组或其他结构化目的。一个 Combo 可以包含子节点也可以包含其他 Combo从而形成嵌套结构。属性类型说明id必填stringCombo 的唯一标识typestringCombo 类型可以是内置 Combo 类型或自定义 Combo 类型dataObjectCombo 的自定义业务数据可在样式映射中通过回调函数访问styleObjectCombo 样式statesstring[]Combo 的初始状态combostring|null父 Combo 的 ID无父 Combo 时为 null示例{ id: combo1, type: circle, data: { groupName: Group A }, style: { fill: lightblue, stroke: blue, collapsed: true }, states: [], combo: null }Combo 在源码中同样以图节点Node的形式存储于图模型通过内部的comboIds集合与 Combo 树结构COMBO_KEY加以区分见 packages/g6/src/runtime/data.ts 中DataController的实现。从类型看packages/g6/src/types/data.tsComboData与NodeData被统一抽象为NodeLikeData这正是两者可共享父/子层级 API 的原因。此外 G6 中“树形层级”与“Combo 层级”是两套相互独立的结构树形层级由节点的children字段驱动Combo 层级由combo字段驱动相关 API如getParentData、getAncestorsData需要通过hierarchy: tree | combo显式指定层级类型见 packages/g6/src/types/data.ts。数据组织与最佳实践为保证图渲染与交互的正确性建议严格按 G6 的标准数据结构组织数据。文档明确给出两条核心建议避免使用与 G6 内部字段冲突的标识符不要将业务字段命名为id、type、style等 G6 保留字段防止命名冲突将业务数据统一存放在data字段如用户信息、社交关系等存放在data中可保证数据的灵活性与可扩展性同时不干扰 G6 的元素属性解析。推荐示例{ nodes: [ { id: node1, data: { name: Alice, role: Admin } }, { id: node2, data: { name: Bob, role: User } } ], edges: [ { source: node1, target: node2, data: { relationship: friend } } ] }这一建议与源码实现高度吻合mergeElementsData见 packages/g6/src/utils/data.ts在合并元素数据时会将data与style作为独立的二级对象进行浅合并{ ...originalData, ...modifiedData }而顶层属性直接覆盖。也就是说data字段天然被设计为可增量合并的业务数据容器将业务数据放在此处可以享受更新合并带来的便利而放在顶层则可能被整体覆盖。通过数据 API 操作图数据G6 提供了一系列数据 API 覆盖图数据从查询、修改到更新的完整生命周期文档完整列表见 packages/site/docs/manual/data.en.md 的 API 小节详细签名与示例见 packages/site/docs/api/data.en.md查询getData、getNodeData、getEdgeData、getComboData新增addData、addNodeData、addEdgeData、addComboData更新updateData、updateNodeData、updateEdgeData、updateComboData删除removeData、removeNodeData、removeEdgeData、removeComboData这些 API 以graph.xxx()的形式暴露内部委托给运行时数据控制器DataController见 packages/g6/src/runtime/data.ts执行并触发后续的变更事件与重绘。查询数据graph.getData()返回包含全部节点、边、Combo 的完整图数据对应实现见 packages/g6/src/runtime/graph.ts其内部调用DataController.getData见 packages/g6/src/runtime/data.tsconst graphData graph.getData(); console.log(Node data:, graphData.nodes); console.log(Edge data:, graphData.edges); console.log(Combo data:, graphData.combos);getNodeData/getEdgeData/getComboData均支持三种调用方式无参取全部、传入单个 ID、传入 ID 数组。例如// 获取所有节点 const nodes graph.getNodeData(); // 获取单个节点 const node graph.getNodeData(node1); console.log(Node position:, node.style.x, node.style.y); // 获取多个节点 const [node1, node2] graph.getNodeData([node1, node2]);新增数据addData用于一次性添加多种元素addNodeData/addEdgeData/addComboData则分别针对单一元素类型。所有方法都支持传入数组或返回数组的函数式写法graph.addData({ nodes: [{ id: node-1 }, { id: node-2 }], edges: [{ source: node-1, target: node-2 }], }); // 添加带样式与业务数据的节点 graph.addNodeData([ { id: node1, style: { x: 100, y: 100 }, data: { label: Node 1 } }, ]); // 函数式新增 graph.addNodeData((prev) [...prev, { id: node4, style: { x: 400, y: 400 } }]);从源码实现看packages/g6/src/runtime/data.tsaddData内部会先添加 Combo、再添加节点、最后添加边这是因为 Combo 需要先建立层级结构而边依赖节点存在。此外新增元素后会自动计算zIndexcomputeZIndex保证组合内层级、边与节点之间的绘制顺序正确。仓库演示用例 animation-element-style-position.ts 展示了新增、删除、更新节点的组合用法graph.addNodeData([ { id: node-4, style: { x: 50, y: 200, fill: orange } }, { id: node-5, style: { x: 75, y: 150, fill: purple } }, { id: node-6, style: { x: 200, y: 100, fill: cyan } }, ]); graph.removeNodeData([node-1]); graph.updateNodeData([{ id: node-2, style: { x: 200, y: 200, stroke: green } }]); graph.draw();更新数据更新类 API 遵循“只需传入需要更新的数据无需传入完整数据”的原则文档中以 ⚠️ 特别标注graph.updateData({ nodes: [{ id: node-1, style: { x: 100, y: 100 } }], edges: [{ id: edge-1, style: { lineWidth: 2 } }], }); // 更新单个节点 graph.updateNodeData([{ id: node-1, style: { x: 100, y: 100 } }]); // 更新边的样式 graph.updateEdgeData([{ id: edge-1, style: { lineWidth: 2 } }]);这一“局部更新”语义的实现关键在于mergeElementsData更新时原始数据与传入的修改数据会做浅合并——顶层属性如type、states直接覆盖data与style内部的二级字段按 key 增量合并见 packages/g6/src/utils/data.ts。同时updateNodeData在合并前会通过isElementDataEqual做相等性判断见 packages/g6/src/utils/data.ts数据未变化时直接跳过避免无意义的变更事件与重绘。更新边的source/target时数据层会调用model.updateEdgeSource/model.updateEdgeTarget同步图模型中的拓扑关系见 packages/g6/src/runtime/data.ts。从类型层面看PartialNodeLikeDataT要求更新节点/Combo 时必须携带idPartialEdgeDataT则要求携带sourcetarget或id二选一见 packages/g6/src/types/data.ts。删除数据删除 API 传入需要删除元素的 ID或返回 ID 的函数graph.removeData({ nodes: [node-1, node-2], edges: [edge-1] }); graph.removeNodeData([node-1, node-2]); graph.removeEdgeData([edge-1]); graph.removeComboData([combo-1]);值得注意的是removeData内部采用“先删边、再删节点、最后删 Combo”的顺序见 packages/g6/src/runtime/data.ts且删除节点时会顺带移除与之关联的边removeEdgeData(this.getRelatedEdgesData(id).map(idOf))见 packages/g6/src/runtime/data.ts。删除 Combo 后其子节点会被提升到父 Combo 或根层级removeNodeLikeHierarchy见 packages/g6/src/runtime/data.ts避免出现“孤儿节点”。更多查询类 API除上述增删改查外G6 还提供面向关系与层级查询的数据 API签名与示例详见 packages/site/docs/api/data.en.mdgetElementData(id)不关心元素类型直接按 ID 获取元素数据getElementDataByState(elementType, state)获取处于指定状态如selected、active、highlight、inactive、disabled的元素数据getNeighborNodesData(id)获取节点/Combo 的邻居节点数据getRelatedEdgesData(id, direction?)获取与节点/Combo 关联的边数据direction支持in | out | bothgetParentData(id, hierarchy)/getChildrenData(id)/getAncestorsData(id, hierarchy)/getDescendantsData(id)按tree | combo层级获取父子与祖先/后代数据。这些方法的底层实现均可在 packages/g6/src/runtime/data.ts 中找到例如getChildrenData会根据元素类型自动选择TREE_KEY或COMBO_KEY对应的树结构packages/g6/src/runtime/data.ts。使用远程数据G6 本身不提供数据获取与解析能力数据需要由业务侧准备好再交给图实例。对于本地 JSON 数据可以直接导入使用import data from ./path/to/data.json assert { type: json };对于远程数据使用fetch或其他网络库获取后传入fetch(https://path/to/data.json) .then((res) res.json()) .then((data) { // 使用 data });获取数据后既可以在实例化Graph时通过data配置项传入仓库演示 common-graph.ts 即为标准写法也可以在渲染前或运行中调用graph.setData(data)进行设置。setData同样支持函数式写法便于基于当前数据做增量调整graph.setData({ nodes: [ { id: node1, style: { x: 100, y: 100 } }, { id: node2, style: { x: 200, y: 200 } }, ], edges: [{ id: edge1, source: node1, target: node2 }], }); // 函数式更新基于当前数据追加节点 graph.setData((prev) ({ ...prev, nodes: [...prev.nodes, { id: node3, style: { x: 300, y: 300 } }], }));从源码看setData的实现见 packages/g6/src/runtime/data.ts会对新旧数据按 ID 做差量计算arrayDiff分别得到需要新增enter、更新update与删除exit的元素再在同一个批处理batch内依次执行从而避免多余的重绘开销。状态states在数据中的角色节点的states字段声明元素的初始状态G6 内置了selected、active、highlight、inactive、disabled等状态见 packages/site/docs/api/data.en.md 的 Built-in States 一节状态对应的视觉表现由主题theme与元素样式定义决定。仓库测试数据集 element-nodes.json 中可以看到真实的状态声明用法{ id: active, states: [active] }, { id: selected, states: [selected] }, { id: highlight, states: [highlight] }, { id: inactive, states: [inactive] }, { id: disabled, states: [disabled] }运行时可通过updateNodeData/updateEdgeData等 API 修改元素的states来驱动状态切换例如仓库中的树图用例会通过graph.updateNodeData([{ id: targetId, states: [selected] }])高亮选中节点见 case-indented-tree.ts。小结G6 的数据体系可以概括为三条主线结构GraphData由nodes、edges、combos组成三者分别对应节点、边与 Combo节点与边分别以id和source/target为必填标识业务数据统一存放在data字段中API查询get*、新增add*、更新update*、删除remove*四类数据 API 覆盖了图数据的完整生命周期支持数组与函数式两种传参方式更新操作采用局部合并语义实现数据层由DataController统一管理内部基于图模型GraphLib存储节点/边与树形结构数据变更会生成变更记录并驱动重绘setData采用差量 diff 以最小化重绘开销。在此基础上你可以进一步阅读 数据 API 完整参考 获取每个方法的签名、参数与返回值细节或结合仓库中的 测试数据集 与 演示用例 查看真实场景下的数据组织方式。赞分享数据可视化前端图表库【免费下载链接】G6♾ A Graph Visualization Framework in JavaScript.项目地址https://gitcode.com/gh_mirrors/g6/G6点击查看免费下载相关推荐开发者指南基于Inkling-Small-mlx-4bit构建自定义多模态应用的完整流程开发者指南基于Inkling Small mlx 4bit构建自定义多模态应用的完整流程 Inkling Small mlx 4bit是一款专为Apple S数据结构选择harmony-utils中数据结构的最佳实践数据结构选择harmony utils中数据结构的最佳实践 痛点鸿蒙开发中的数据管理困境 你还在为鸿蒙应用开发中的数据管理而烦恼吗面对复杂的业务场景如何OpenHarmonyCrowbar高级应用掌握GoldSource和Source引擎模型处理的5个专业工作流Crowbar高级应用掌握GoldSource和Source引擎模型处理的5个专业工作流 Crowbar是一款专为GoldSource和Source引擎设计的游戏开发开发工具上一篇告别混乱代码Vue.js项目的CursorRules配置实战指南下一篇Catch2测试优化性能提升策略创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
企业数字化 ERP 产品动态
相关推荐
手写实现布里渊区算法避坑:解决代码报错与性能瓶颈 手写实现布里渊区算法避坑:解决代码报错与性能瓶颈 复制来的布里渊区计算代码,一跑就报错,或者结果和教科书上的图对不上,调试半天找不到原因?这种“复制粘贴即翻车”的经历,在固体物理计算中太常见了。很多开发者直接套用GitHub上开源的示例,却… · 2026/9/23 17:37:43
科技职场生存指南:高绩效老将的危机与应对 1. 职场生存现状:高绩效老将的突然陨落在科技行业打拼13年的资深员工,54岁时遭遇职业生涯滑铁卢——这个真实案例揭示了当代职场中一个残酷的现实:即使曾获得CEO亲自表彰、手握价值1200万美元的未兑现股票,也可能在一夜之间被贴上… · 2026/9/23 17:37:43
Vision Transformer图像去雾:物理模型驱动的全局建模方法 简介:本资源是一套基于Vision Transformer(ViT)的图像去雾算法完整实现方案,面向计算机视觉方向的研究者、深度学习开发者及高校高年级本科生,解决雾霾天气下图像对比度低、细节模糊等实际成像问题。压缩包共340个文件… · 2026/9/23 18:13:32
树莓派人脸识别全攻略:环境搭建、LBPH训练与项目部署 简介:这份资源面向人工智能、通信工程、自动化、电子信息、物联网等专业的在校学生和教师,也适合用于毕业设计、课程设计、项目初期演示或小白进阶学习。内容以树莓派为硬件平台,围绕人脸识别从数据采集、人脸检测、特征提取到实时识别展开&a… · 2026/9/23 18:13:32
搞懂daemontools:避开版本坑与高频面试题的实战指南 搞懂daemontools:避开版本坑与高频面试题的实战指南 版本升级后 API 全变了?这是很多刚接触 daemontools 的新人最容易踩的雷。别慌,这不仅仅是配置问题,更是理解 Unix… · 2026/9/23 18:13:32
投稿怎么投才不石沉大海:3个源码解析技巧教你避开退稿雷区 投稿怎么投才不石沉大海:3个源码解析技巧教你避开退稿雷区 官方文档翻了三遍,脑子还是嗡嗡的?别慌,这不是你的问题。很多技术博主和开发者都卡在同一个坎上:文档太长、太碎,抓不住重点,导致写出来的东西像流水账,或者干脆不敢动手写。这时候,… · 2026/9/23 18:13:32
三菱系统Y03报警与0101急停维修:光纤通信故障排查实战 这是一篇基于你提供的标题真实维修案例梳理的实战笔记。干这行的都知道,三菱系统报警看着吓人,代码一串一串,其实只要理清供电、通信、参数这三条线,大部分都能稳稳拿下。今天就把这次加工中心上电报警的完整处理过程掰开揉碎讲清… · 2026/9/23 18:13:25
3招搞定手机怎么下载微信面试难题实战项目解析 3招搞定手机怎么下载微信面试难题实战项目解析 面试被问“手机怎么下载微信”背后的原理,90%的人答不上来。别笑,这看似弱智的问题,实则是考察你对移动应用分发机制、安全校验及网络协议理解的试金石。我带过不少校招新人,他们背了八股文,却连一个A… · 2026/9/23 0:00:03
你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型 你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型 面试被问“高并发下如何保证消息不丢失”,你张口就是“用Redis”,结果面试官追问“如果Redis宕机了怎么办”,你瞬间卡壳。这种场景太常见了,很多新手在背八股文时,只记住了技术名词… · 2026/9/23 0:00:29