当前位置: 首页 > news >正文

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可视化库来画有向无环图

背景 做大数据的项目&#xff0c;必不可少的是要接触到数据血缘图&#xff0c;它在大数据项目中有着很重要的作用。 之前在公司也做过一些案例&#xff0c;也看过很多友商的产品&#xff0c;阿里的DataWork&#xff0c;领英的Datahub&#xff0c; datawork的血缘图使用的是 G6…...

二、判断语句

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

龙智汽车行业客户案例:Jira数据中心版助客户解锁高效项目管理

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

03 vi编辑器

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

Web界面自动化操作工具 - Selenium常见用法

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

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失败解决方案

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

Galaxy生信云平台|Maftools高效地汇总、分析、注释和可视化肿瘤基因突变MAF文件...

2023-10-25&#xff0c;Galaxy中国镜像站 UseGalaxy.cn 平台新增 5 个工具。 MAF Tools Maftools-突变景观图: 绘制肿瘤基因突变景观图Maftools-突变汇总: 汇总MAF文件中的突变信息Maftools-共突变与互斥突变: 计算共突变和互斥突变Maftools-队列比较&#xff1a;比较两个队列之…...

JS三种常见的存储机制

1.localStorage localStorage是HTML5引入的一种持久化存储机制&#xff0c;用于在浏览器中长期保存数据。localStorage中存储的数据没有过期时间&#xff0c;除非被显式清除或代码删除。存储在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&#xff0c;n_features]&#xff0c;batch_size为批次大小&#xff0c;time_step为时间步长&#xff0c;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打印功能,样式对齐&#xff0c;去除滚动条 // 整个页面打印 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等级考试&#xff08;1~6级&#xff09;全部真题・点这里 一、单选题&#xff08;共25题&#xff0c;每题2分&#xff0c;共50分&#xff09; 第1题 表达式len(“学史明理增信 &#xff0c;读史终生受益”) > len(" reading history will benefit you ")的…...

【面试经典150 | 链表】两数相加

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

vue路径中“@/“代表什么

举例&#xff1a; <img src"/../static/imgNew/adv/tupian.jpg"/>其中&#xff0c;/是webpack设置的路径别名&#xff0c;代表什么路径&#xff0c;要看webpack的build文件夹下webpack.base.conf.js里面对于是如何配置&#xff1a; 上图中代表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&#xff1f;2.3 consul的架构2.3 Consul-template 三、consul架构部署3.1 Consul服务器Step1 建立 Consul 服务Step2 查看集群信息Step3 通过…...

PCIe架构的处理器系统介绍

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

国产内存强势崛起,光威龙武挑战D5内存24×2新标杆

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

矩阵的运算

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

Android 获取SIM卡号码权限申请

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

Linux CentOS 本地yum配置

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

【c++速通】入门级攻略:什么是内联函数?函数重载又是什么?

&#x1f3a5; 屿小夏 &#xff1a; 个人主页 &#x1f525;个人专栏 &#xff1a; C入门到进阶 &#x1f304; 莫道桑榆晚&#xff0c;为霞尚满天&#xff01; 文章目录 &#x1f4d1;前言&#x1f324;️函数重载☁️函数重载的概念☁️函数重载的作用☁️C支持函数重载的原理…...

ubuntu 安装串口工具和添加虚拟串口

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

【数据结构】数组和字符串(四):特殊矩阵的压缩存储:稀疏矩阵——三元组表

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

为什么POST请求经常发送两次?

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

打破总分行数据协作壁垒,DataOps在头部股份制银行的实践|案例研究

从银行开始建设数据仓库至今已近20年&#xff0c;当前各银行机构在数据能力建设中面临诸多困扰&#xff1a;如何保证数据使用时的准确性&#xff1f;如何让数据敏捷响应业务变化&#xff1f;如何让更多的业务人员使用数据&#xff1f; 这些问题极大影响了经营指标的达成与业务…...