datahub 中血缘图的实现分析,在react中使用airbnb的visx可视化库来画有向无环图
背景
做大数据的项目,必不可少的是要接触到数据血缘图,它在大数据项目中有着很重要的作用。
之前在公司也做过一些案例,也看过很多友商的产品,阿里的DataWork,领英的Datahub,
datawork的血缘图使用的是 G6
,自家的产品
Datahub使用的是 爱彼邻的 可视化库 visx
本篇文章就来谈谈datahub中的血缘图。
查看源码
点击此处链接你将看到 datahub中的血缘图,
由于是demo环境,数据有可能会被删掉,读者可以自行寻找。
该血缘图的特性如下
- 上下游
- 自定义节点
- 节点可点击,操作
- 线的样式有多种
- 鼠标放置线上有辅助信息
- 可以展开上下游
- 最基本的放大,缩小视图
F12 节点的源码,发现使用的是SVG 实现的
标签的类前缀都是vx
,但直接搜没有搜到,于是去项目的package.json
中寻找使用的库。
查看package.json
在项目中 找到了答案
https://github.com/datahub-project/datahub/blob/master/datahub-web-react/package.json
使用的是
https://airbnb.io/visx
github 地址 https://github.com/airbnb/visx
visx
是一个为 React 应用程序提供可视化功能的库。它提供了一系列低级可视化元素或组件,被称为 expressive, low-level visualization primitives,这些元素或组件可以用于创建各种可视化效果,例如饼图等。使用 VISX 可以方便地将设计元素添加到 React 应用程序中。它是由 Airbnb 构建的。
提前关键词,该库具有的特征
- 为react
- 低级元素
- 可视化
低级元素是说它不直接提供一个个完整的图表,而且要使用多个元素组装实现,这也意味着 要使用它,还是有一点门槛的,但人家的审美确实在线。visx的gallery 都很美观。让人看了就像用,但一用就头大,提供的api太底层了。
大家看几个官网的示例
查看组件源码
上面介绍了一下 visx库,我们回到datahub这个项目
血缘图 都放在https://github.com/datahub-project/datahub/blob/master/datahub-web-react/src/app/lineage这个目录
节点组件
https://github.com/datahub-project/datahub/blob/master/datahub-web-react/src/app/lineage/LineageEntityNode.tsx
visx库文档
因为这个库并不是一个专业的Graph库,所有在图的布局算法,自定义接的,自定义线,或者图的交互 都不如g6做的丰富。
选型还需慎重,依赖大量svg的api,标签。
案例
最后提供一个 使用visx 画的一个 Graph案例
import React, { useState } from 'react';
import { Group } from '@visx/group';
import { hierarchy, Tree } from '@visx/hierarchy';
import { LinearGradient } from '@visx/gradient';
import { pointRadial } from 'd3-shape';
import useForceUpdate from './useForceUpdate';
import LinkControls from './LinkControls';
import getLinkComponent from './getLinkComponent';interface TreeNode {name: string;isExpanded?: boolean;children?: TreeNode[];
}const data: TreeNode = {name: 'T',children: [{name: 'A',children: [{ name: 'A1' },{ name: 'A2' },{ name: 'A3' },{name: 'C',children: [{name: 'C1',},{name: 'D',children: [{name: 'D1',},{name: 'D2',},{name: 'D3',},],},],},],},{ name: 'Z' },{name: 'B',children: [{ name: 'B1' }, { name: 'B2' }, { name: 'B3' }],},],
};const defaultMargin = { top: 30, left: 30, right: 30, bottom: 70 };export type LinkTypesProps = {width: number;height: number;margin?: { top: number; right: number; bottom: number; left: number };
};export default function Example({width: totalWidth,height: totalHeight,margin = defaultMargin,
}: LinkTypesProps) {const [layout, setLayout] = useState<string>('cartesian');const [orientation, setOrientation] = useState<string>('horizontal');const [linkType, setLinkType] = useState<string>('diagonal');const [stepPercent, setStepPercent] = useState<number>(0.5);const forceUpdate = useForceUpdate();const innerWidth = totalWidth - margin.left - margin.right;const innerHeight = totalHeight - margin.top - margin.bottom;let origin: { x: number; y: number };let sizeWidth: number;let sizeHeight: number;if (layout === 'polar') {origin = {x: innerWidth / 2,y: innerHeight / 2,};sizeWidth = 2 * Math.PI;sizeHeight = Math.min(innerWidth, innerHeight) / 2;} else {origin = { x: 0, y: 0 };if (orientation === 'vertical') {sizeWidth = innerWidth;sizeHeight = innerHeight;} else {sizeWidth = innerHeight;sizeHeight = innerWidth;}}const LinkComponent = getLinkComponent({ layout, linkType, orientation });return totalWidth < 10 ? null : (<div><LinkControlslayout={layout}orientation={orientation}linkType={linkType}stepPercent={stepPercent}setLayout={setLayout}setOrientation={setOrientation}setLinkType={setLinkType}setStepPercent={setStepPercent}/><svg width={totalWidth} height={totalHeight}><LinearGradient id="links-gradient" from="#fd9b93" to="#fe6e9e" /><rect width={totalWidth} height={totalHeight} rx={14} fill="#272b4d" /><Group top={margin.top} left={margin.left}><Treeroot={hierarchy(data, (d) => (d.isExpanded ? null : d.children))}size={[sizeWidth, sizeHeight]}separation={(a, b) => (a.parent === b.parent ? 1 : 0.5) / a.depth}>{(tree) => (<Group top={origin.y} left={origin.x}>{tree.links().map((link, i) => (<LinkComponentkey={i}data={link}percent={stepPercent}stroke="rgb(254,110,158,0.6)"strokeWidth="1"fill="none"/>))}{tree.descendants().map((node, key) => {const width = 40;const height = 20;let top: number;let left: number;if (layout === 'polar') {const [radialX, radialY] = pointRadial(node.x, node.y);top = radialY;left = radialX;} else if (orientation === 'vertical') {top = node.y;left = node.x;} else {top = node.x;left = node.y;}return (<Group top={top} left={left} key={key}>{node.depth === 0 && (<circler={12}fill="url('#links-gradient')"onClick={() => {node.data.isExpanded = !node.data.isExpanded;console.log(node);forceUpdate();}}/>)}{node.depth !== 0 && (<rectheight={height}width={width}y={-height / 2}x={-width / 2}fill="#272b4d"stroke={node.data.children ? '#03c0dc' : '#26deb0'}strokeWidth={1}strokeDasharray={node.data.children ? '0' : '2,2'}strokeOpacity={node.data.children ? 1 : 0.6}rx={node.data.children ? 0 : 10}onClick={() => {node.data.isExpanded = !node.data.isExpanded;console.log(node);forceUpdate();}}/>)}<textdy=".33em"fontSize={9}fontFamily="Arial"textAnchor="middle"style={{ pointerEvents: 'none' }}fill={node.depth === 0 ? '#71248e' : node.children ? 'white' : '#26deb0'}>{node.data.name}</text></Group>);})}</Group>)}</Tree></Group></svg></div>);
}
题外话
开源项目 openmatedata
血缘图使用的react-flow,节点,线都是使用div画的。大数据量时,可能堪忧
相关文章:

datahub 中血缘图的实现分析,在react中使用airbnb的visx可视化库来画有向无环图
背景 做大数据的项目,必不可少的是要接触到数据血缘图,它在大数据项目中有着很重要的作用。 之前在公司也做过一些案例,也看过很多友商的产品,阿里的DataWork,领英的Datahub, datawork的血缘图使用的是 G6…...

二、判断语句
文章目录 1.if语句1)if判断语句基本格式2) 网吧上网3)if语句使用逻辑运算 2.if-else语句1)if-else的使用格式2)网吧上网 3.多重判断elif语句1) 多重判断elif2)例子3)注意点 4.if嵌套…...

龙智汽车行业客户案例:Jira数据中心版助客户解锁高效项目管理
龙智技术支持部负责人、Atlassian认证专家叶燕秀分享了她帮助某汽车企业落地Jira的故事,并详解了该公司选择Jira数据中心版的理由以及工具链的集成情况,为有同样需求的公司提供实践参考。 本文由叶燕秀口述内容整理而成 需求管理:从Excel表格…...

03 vi编辑器
vi编辑器的三种模式: 不同的模式下机键动作解释的意义是不一样的 编辑模式 插入模式 末行模式 文件的打开和关闭保存 移动光标...

Web界面自动化操作工具 - Selenium常见用法
Selenium是一个用于自动化浏览器操作的工具,常用于Web应用程序的测试和爬虫开发。 下面是一些Python Selenium的常见用法和代码示例: 1. 导入Selenium库和WebDriver: from selenium import webdriver2. 创建WebDriver实例: # …...

Openssl数据安全传输平台009:加密理论基础:哈希/非对称加密RSA/对称加密AES
文章目录 0. 代码仓库代码编译时候可能出现的错误 1. 哈希1.1 哈希算法的种类:1.2 使用的头文件1.3 哈希算法API1.3.1 详解md5 API1.3.2 sha1/sha224/sha256/sha384/sha512常用API 1.5 sha1代码测试1.4 在VS中添加预处理器定义1.5 哈希算法C代码封装的思路 2. 非对称加密RSA2.1…...

iPhone开发--Xcode15下载iOS 17.0.1 Simulator Runtime失败解决方案
爆句粗口,升级后公司网络下载iOS 17.0.1 Simulator Runtime一直出错,每次出错后都得重新开始下载,oh,f**k。上一次在在家里的网络升级成功。 解决办法一: 进入网址:https://developer.apple.com/download…...

Galaxy生信云平台|Maftools高效地汇总、分析、注释和可视化肿瘤基因突变MAF文件...
2023-10-25,Galaxy中国镜像站 UseGalaxy.cn 平台新增 5 个工具。 MAF Tools Maftools-突变景观图: 绘制肿瘤基因突变景观图Maftools-突变汇总: 汇总MAF文件中的突变信息Maftools-共突变与互斥突变: 计算共突变和互斥突变Maftools-队列比较:比较两个队列之…...

JS三种常见的存储机制
1.localStorage localStorage是HTML5引入的一种持久化存储机制,用于在浏览器中长期保存数据。localStorage中存储的数据没有过期时间,除非被显式清除或代码删除。存储在localStorage中的数据对于同一个域名下的所有页面都是共享的。localStorage可以存储…...

【Python机器学习】零基础掌握BaggingClassifier集成学习
何提高分类模型的稳定性和准确性? 在金融风控、医疗诊断或者社交媒体推荐等场景中,分类问题是常见的难题。但是,单一的分类模型(如SVM)在处理复杂或不均衡的数据集时可能会表现不佳。那么,有没有一种方法能够提高模型的稳定性和准确性呢? 假设一家银行想要通过机器学习…...

[晕事]今天做了件晕事26;gcc对strcmp/strncmp的优化
今天做了一件晕事,写了一个测试小程序,开头的程序例如下面片段。在后续又写了一些代码,进行编译,使用gdb查看可执行文件,怎么都得不到想要的结果,非常的纳闷,非常的奇怪。 int main() {char a[3]="ab";int b = strncmp(0, a, 1<...

【深度学习】使用Pytorch实现的用于时间序列预测的各种深度学习模型类
深度学习模型类 简介按滑动时间窗口切割数据集模型类CNNGRULSTMMLPRNNTCNTransformer 简介 本文所定义模型类的输入数据的形状shape统一为 [batch_size, time_step,n_features],batch_size为批次大小,time_step为时间步长,n_feat…...

ts | js | 爬虫小公举分享
Curl转Code 快速将curl转为各种语言的代码; 便于提取请求头之类, 或者微改直接使用 https://curlconverter.com/node-axios/ (有点慢, 但是很全)https://www.lddgo.net/convert/curl-to-code (没有axios, 我喜欢用axios) 使用… 抓取地址, 使用浏览器或者其他抓包工具都可, 这…...

实现el-table打印功能,样式对齐,去除滚动条
实现el-table打印功能,样式对齐,去除滚动条 // 整个页面打印 function printTable(id) {// let domId #js_index// if (id) {// domId #${ id };// }// let wpt document.querySelector(domId);// let newContent wpt.innerHTML;// let oldContent document.…...

2022年09月 Python(一级)真题解析#中国电子学会#全国青少年软件编程等级考试
Python等级考试(1~6级)全部真题・点这里 一、单选题(共25题,每题2分,共50分) 第1题 表达式len(“学史明理增信 ,读史终生受益”) > len(" reading history will benefit you ")的…...

【面试经典150 | 链表】两数相加
文章目录 写在前面Tag题目来源题目解读解题思路方法一:模拟 其他语言python3 写在最后 写在前面 本专栏专注于分析与讲解【面试经典150】算法,两到三天更新一篇文章,欢迎催更…… 专栏内容以分析题目为主,并附带一些对于本题涉及到…...

vue路径中“@/“代表什么
举例: <img src"/../static/imgNew/adv/tupian.jpg"/>其中,/是webpack设置的路径别名,代表什么路径,要看webpack的build文件夹下webpack.base.conf.js里面对于是如何配置: 上图中代表src,上述代码就…...

java springboot2.7 写一个本地 pdf 预览的接口
依赖方面 创建的是 接口web项目就好了 然后包管理工具打开需要这些 import org.springframework.core.io.FileSystemResource; import org.springframework.core.io.Resource; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; imp…...

RustDay06------Exercise[81-90]
81.宏函数里面的不同的匹配规则需要使用分号隔开 // macros4.rs // // Execute rustlings hint macros4 or use the hint watch subcommand for a // hint.// I AM NOT DONE#[rustfmt::skip] macro_rules! my_macro {() > {println!("Check out my macro!");};($…...

【Docker从入门到入土 6】Consul详解+Docker https安全认证(附证书申请方式)
Part 6 一、服务注册与发现的概念1.1 cmp问题1.2 服务注册与发现 二、Consul ----- 服务自动发现和注册2.1 简介2.2 为什么要用consul?2.3 consul的架构2.3 Consul-template 三、consul架构部署3.1 Consul服务器Step1 建立 Consul 服务Step2 查看集群信息Step3 通过…...

PCIe架构的处理器系统介绍
不同的处理器系统中,PCIe体系结构的实现方式不尽相同。PCIe体系结构以Intel的x86处理器为蓝本实现,已被深深地烙下x86处理器的印记。在PCIe总线规范中,有许多内容是x86处理器独有的,也仅在x86处理器的Chipset中存在。在PCIe总线规…...

国产内存强势崛起,光威龙武挑战D5内存24×2新标杆
今年国产内存的表现非常亮眼,出现了很多高质量的普惠产品,像是最近光威推出的一款内存条龙武ddr5 242就很有竞争力,加上之前神策新加入的ddr5 242版本,都是备受瞩目的新品,凭实力把DIY主机的内存配置拉高到了48GB。 龙…...

矩阵的运算
目标:实现一个能进行稀疏矩阵基本运算(包括加、减、乘)的运算器。 (1)以三元组顺序表表示稀疏矩阵,实现两个矩阵相加、相减、相乘的运算 (2)稀疏矩阵的输入形式为三元组表示,运算结果则以通常…...

Android 获取SIM卡号码权限申请
1.添加权限 在AndroidManifest.xml中添加如下权限 <uses-permission android:name"android.permission.READ_PHONE_STATE"/> 2.获取权限 如果你只在清单文件中添加权限却没有在代码中获取权限,代码还是会报错的。 报错原因: android…...

Linux CentOS 本地yum配置
本地开发用虚拟机,因为有光盘镜像在手,并不需要联网安装组件,只需要设置一下就可以让yum从本地获取源。 将安装盘挂载在合适位置 mount /dev/cdrom /mnt 进入目录 cd /etc/yum.repos.d/ 修改CentOS-Media.repo里面的挂载路径 …...

【c++速通】入门级攻略:什么是内联函数?函数重载又是什么?
🎥 屿小夏 : 个人主页 🔥个人专栏 : C入门到进阶 🌄 莫道桑榆晚,为霞尚满天! 文章目录 📑前言🌤️函数重载☁️函数重载的概念☁️函数重载的作用☁️C支持函数重载的原理…...

ubuntu 安装串口工具和添加虚拟串口
目录 一、串口工具安装 二、使用Windows本身虚拟的串口 (一)添加串口 1、保证虚拟机是关闭状态,打开“虚拟机设置”,点击“添加”。 2、选中“串行端口”,点击“完成”。 3、选中刚添加的串口,下拉选…...

【数据结构】数组和字符串(四):特殊矩阵的压缩存储:稀疏矩阵——三元组表
文章目录 4.2.1 矩阵的数组表示4.2.2 特殊矩阵的压缩存储a. 对角矩阵的压缩存储b~c. 三角、对称矩阵的压缩存储d. 稀疏矩阵的压缩存储——三元组表结构体初始化元素设置打印矩阵主函数输出结果代码整合 4.2.1 矩阵的数组表示 【数据结构】数组和字符串(一ÿ…...

为什么POST请求经常发送两次?
大多数初级前端程序员,在通过浏览器F12的调试工具调试网络请求时,可能都会有一个发现,在进行POST请求时,明明代码里只请求了一次,为什么network里发送了两次呢,难道我代码出bug了?带着疑问点开第…...

打破总分行数据协作壁垒,DataOps在头部股份制银行的实践|案例研究
从银行开始建设数据仓库至今已近20年,当前各银行机构在数据能力建设中面临诸多困扰:如何保证数据使用时的准确性?如何让数据敏捷响应业务变化?如何让更多的业务人员使用数据? 这些问题极大影响了经营指标的达成与业务…...