ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

diagrams Custom 节点完全指南:从本地图标到远程图标的源码级拆解

diagrams Custom 节点完全指南:从本地图标到远程图标的源码级拆解 diagrams Custom 节点完全指南从本地图标到远程图标的源码级拆解【免费下载链接】diagrams:art: Diagram as Code for prototyping cloud system architectures项目地址: https://gitcode.com/GitHub_Trending/di/diagrams内置图标库没有你要画的组件——自研网关、第三方消息队列——怎么把一张本地 PNG 塞进 diagrams 节点答案就是diagrams Custom 节点让你用自己的图标素材画出自定义架构图。本文把图标从传入到渲染的完整链路按源码拆一遍看完可以放心使用。三十秒跑通一个最小可运行的 Custom 节点示例先在运行目录下的icons/里放两张任意 PNG再写脚本from diagrams import Diagram from diagrams.custom import Custom with Diagram(Local Custom Arch, showFalse, filenamelocal_custom): gw Custom(API Gateway, ./icons/gateway.png) svc Custom(Payment Service, ./icons/payment.png) gw svc执行python local_custom.py当前目录会生成local_custom.png。节点的唯一要求就是把图片路径作为Custom的第二个参数传进去路径相对于脚本运行目录。下图是官方本地图标示例Creative Commons 许可证关系图的渲染结果完整脚本见 docs/nodes/custom.md观感与上面脚本一致每个节点一张图标加一行标签箭头表示流向。图标从传入到渲染的完整链路Custom节点的图标要经过四站才落到最终 png 里构造透传 →_load_icon原样返回 → 节点属性注入 →render()烘焙。按这个数据流方向走一遍。构造阶段icon_path 原样透传Custom全类只有 20 行class Custom(Node): _provider custom _type custom _icon_dir None fontcolor #ffffff def _load_icon(self): return self._icon def __init__(self, label, icon_path, *args, **kwargs): self._icon icon_path super().__init__(label, *args, **kwargs)源码见 diagrams/custom/init.py。因为__init__只是把icon_path存进self._icon然后交给基类路径没有任何复制和解析所以你传什么它就用什么相对路径最终由 Graphviz 按运行目录解释文件不在则图标静默丢失。_load_icon 覆写路径不再进资源目录内置节点AWS、K8s 等的图标全路径由框架从包内资源目录拼出来def _load_icon(self): basedir Path(os.path.abspath(os.path.dirname(__file__))) return os.path.join(basedir.parent, self._icon_dir, self._icon)见 diagrams/init.pyEC2之类的图标在类上只是EC2.png短名靠basedir _icon_dir拼全。而Custom把这个方法覆写成return self._icon并把_icon_dir置为None。所以Custom节点返回的图标路径就是用户原样输入的值可以指向磁盘上任意本地文件——这正是自定义二字的来源。节点属性注入图标变成 Graphviz 的 image 属性基类Node.__init__里做了两件事。第一件是全局上下文检查diagrams/init.pyself._diagram getdiagram() if self._diagram is None: raise EnvironmentError(Global diagrams context not set up)这就是节点必须建在with Diagram(...)块内规则的出处。第二件是有图标时注入 Graphviz 节点属性diagrams/init.py# Increase the height by the number of new lines included in the label. padding 0.4 * (self.label.count(\n)) self._attrs { shape: none, height: str(self._height padding), image: self._load_icon(), } if self._icon else {} self._attrs.update(attrs)逐条读因为shape是none节点没有边框图片即节点本身因为image的取值来自_load_icon()图标路径在这一刻被固定并写进 dot 文件因为节点基础高度是_height 1.9第 294 行标签每出现一个\n高度再加 0.4所以两行标签的节点会画得更高文字不会压在图标上。渲染阶段render() 把图片烘进最终 png图片文件并不是在构造节点时被读取的真正读图发生在with Diagram(...)块退出时diagrams/init.pydef __exit__(self, exc_type, exc_value, traceback): self.render() # Remove the graphviz file leaving only the image. os.remove(self.filename) setdiagram(None)render()按outformat调用 graphviz 绑定完成布局第 194-199 行Graphviz 此时才从 dot 文件里读出节点的image属性、加载本地 PNG 并烘进最终图片。所以图标只有一个硬性要求with 块退出的那一刻文件必须已经存在于磁盘上。本地与远程图标的选型对比维度本地图标远程图标适用场景图标来源工作目录里现成的图片文件网络地址先urlretrieve下载为本地文件再传给节点图标随仓库管理、离线开发网络依赖无纯本地文件读取下载时必须可达Custom自身零网络代码图标托管在线上、临时引用文件就位时点with块退出render()触发前存在即可必须在with块内、渲染前完成下载—典型报错图标缺失相对路径按运行目录解析不到文件文件不存在 / 下载失败下载位置或时点不对—两种模式的差别只在文件从哪来。因为Custom只认本地路径所谓 diagrams 远程图标下载模式本质是先下载再走本地图标节点的路子所有网络代码都在脚本侧。本地图标的精简用法路径相对、绝对均可# 离线场景图标文件提前放进仓库或运行目录 Custom(离线组件, /data/icons/offline.png) Custom(下游, ./icons/down.png)远程图标的精简用法下载必须发生在with块内、渲染前from urllib.request import urlretrieve urlretrieve(https://your-icon-host/icon.png, icon.png) # 渲染前完成下载 Custom(在线组件, icon.png)官方远程示例下载 OpenStack、Elastic 图标后绘制的渲染效果Cluster 子图、列表扇出与内置节点混用理解了加载链路Custom在拓扑层面没有任何特殊之处——它和内置节点共享同一套Node运算符重载。下面四种组合是实际项目里最常用的。用 Cluster 给一组 Custom 节点加框意图把几个自研组件在视觉上归为一组。with Cluster(Consumers): consumers [Custom(w1, ./icons/w.png), Custom(w2, ./icons/w.png)]为什么这样连节点构造时Node.__init__通过getcluster()拿到当前簇上下文把节点写进簇的 dot第 331-337 行with块退出时Cluster.__exit__再调用subgraph()把整个子图挂到父图上第 267-272 行。框是事后画上去的块内建的节点自动入框块外引用变量照常连线。一对多扇出 右侧是列表意图一个队列喂多个 worker。queue Custom(queue, ./icons/queue.png) queue [Custom(w1, ./icons/w.png), Custom(w2, ./icons/w.png), Custom(w3, ./icons/w.png)]为什么一条语句产生三条边Node.__rshift__发现右操作数是列表时逐元素调用connect()每个都带forwardTrue第 366-369 行返回值就是列表本身所以链式表达还能继续往下接。列表扇出是 diagrams 里表达一对多的标准语法。多对一聚合 左侧是列表意图所有 worker 的结果汇入同一个数据库。workers [Custom(w1, ./icons/w.png), Custom(w2, ./icons/w.png)] workers Custom(db, ./icons/db.png)为什么能连上列表自身没有运算符Python 回退到Node.__rrshift__第 389-397 行对列表每个元素分别向右侧节点建边。扇出与聚合对称queue workers db一个表达式就能表达扇出-聚合完整拓扑。Custom 与 Pod / Aurora 混用意图broker 是自研组件没有内置图标消费端和数据库用标准节点。from diagrams.aws.database import Aurora from diagrams.k8s.compute import Pod queue Custom(Message queue, rabbitmq.png) queue [Pod(worker), Pod(worker)] Aurora(Database)为什么能随便混Custom、Pod、Aurora都继承自Nodeconnect()统一通过全局 Diagram 上下文建边第 414-427 行边并不关心节点属于哪个 provider。这个拓扑加上Cluster包裹的完整版本在 docs/getting-started/examples.md 的 R【免费下载链接】diagrams:art: Diagram as Code for prototyping cloud system architectures项目地址: https://gitcode.com/GitHub_Trending/di/diagrams创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表