
Drawio Diagram Forge
- 110 installs
- 23 repo stars
- Updated August 4, 2026
- aktsmm/agent-skills
Generate architecture, flow, and system diagrams in draw.io XML from natural-language specs during design and documentation work.
About
drawio-diagram-forge turns spoken or written system descriptions into editable draw.io diagrams for architecture, sequence, and data-flow documentation. It accelerates technical docs during build by producing standardized visual artifacts teams can iterate in draw.io or embed in repos and wikis.
- draw.io XML output
- architecture and flow diagrams
- natural-language to diagram
- system design visualization
- documentation-ready exports
Drawio Diagram Forge by the numbers
- 110 all-time installs (skills.sh)
- Ranked #634 of 1,879 Documentation skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/aktsmm/agent-skills --skill drawio-diagram-forgeAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 110 |
|---|---|
| repo stars | ★ 23 |
| Last updated | August 4, 2026 |
| Repository | aktsmm/agent-skills ↗ |
What it does
Generate architecture, flow, and system diagrams in draw.io XML from natural-language specs during design and documentation work.
Files
Draw.io Diagram Forge
Generate draw.io editable diagrams using AI-powered workflow.
When to Use
- Creating architecture diagrams (Azure, AWS)
- Converting flowcharts from text descriptions
- Transforming images/screenshots into editable format
- Generating swimlane, sequence diagrams
- Editing Azure/AWS icons in existing .drawio files
Choose this skill when the result will need later GUI editing in draw.io, cloud icons, or documentation-facing diagram assets.
When NOT to Use
- Quick inline diagrams that are easier to keep as Mermaid in README or Markdown
- One-off text-native diagrams where manual GUI adjustment is not expected
Prerequisites
| Tool | Required |
|---|---|
| VS Code | Yes |
| Draw.io Integration | Yes |
| GitHub Copilot | Yes |
Quick Start
Create a login flow diagramGenerate an Azure Hub-Spoke architecture diagramFrom inputs/requirements.md, create a system diagramOutput Formats
| Extension | Description | When to Use |
|---|---|---|
*.drawio | Native format | Recommended |
*.drawio.svg | SVG + metadata | Markdown/Web |
*.drawio.png | PNG + metadata | Image with edit |
Output: outputs/
Recommended Delivery Pattern
For documentation-facing diagrams, generate outputs as a pair:
name.drawiofor editing in VS Code Draw.ioname.drawio.svgfor README / web embedding
Reserve *.drawio.svg for SVG files that actually contain draw.io metadata. If you hand-author or post-process a plain SVG without embedded draw.io metadata, name it *.svg instead of *.drawio.svg.
If the visible asset started from manual SVG cleanup or hand-authored layout tweaks, still keep a matching name.drawio as the editable SSOT. Do not leave documentation diagrams as SVG-only when future edits are expected.
Recommended markdown pattern:
Use `outputs/name.drawio.svg` as the embedded image path.
- outputs/name.drawio.svg
- outputs/name.drawioIf multilingual variants are needed, keep parallel filenames instead of overwriting a single asset:
name.drawio/name.drawio.svgname-ja.drawio/name-ja.drawio.svg
This keeps the editable source, the embeddable image, and the language variants aligned.
For local article drafting, if the Markdown preview surface does not reliably render the SVG variant, it is acceptable to:
- keep
.drawioas the editable source - keep
.drawio.svgas the web / embeddable artifact - temporarily reference a generated
*.pngfrom the draft article for local preview stability
At publish time, replace local relative preview paths with the final hosted asset URL.
For Qiita articles, do not leave non-trivial diagrams as Mermaid blocks in the article body. Qiita rendering can be inconsistent. Create a .drawio source, export PNG for Qiita image upload, keep .drawio.svg as the web artifact, and replace the draft-local path with the hosted Qiita image URL before publish.
Workflow
USER INPUT → ORCHESTRATOR → MANIFEST GATEWAY → SVG FORGE → COMPLETEDQuality Gates
| Score | Action |
|---|---|
| 90-100 | Proceed |
| 70-84 | Fix and retry |
| 50-69 | Simplify |
| 0-29 | Ask user |
Limits
| Limit | Value |
|---|---|
| Manifest revision | 2 |
| SVG revision | 2 |
| Total timeout | 45min |
Cloud Icons
→ [references/cloud-icons.md](references/cloud-icons.md)
For Azure-centric diagrams, proactively use the official Azure icon set when a verified Azure2 icon exists. Prefer icon + short label over plain rounded boxes for first-class Azure services. Fall back to generic boxes only when the icon is missing, misleading, or would hurt readability.
Enable in VS Code
1. Open .drawio file 2. Click "+ More Shapes" (bottom-left) 3. Enable: Azure, AWS 4. Apply
Azure Format (Critical)
This format applies to both new diagrams and edits to existing .drawio files. When fixing or replacing Azure icons, always use this format.
<!-- WRONG -->
<mxCell style="shape=mxgraph.azure.front_door;..." />
<!-- CORRECT -->
<mxCell style="aspect=fixed;image=img/lib/azure2/networking/Front_Doors.svg;..." />Azure Icon Preference
- Use Azure service icons aggressively for Azure architecture diagrams when the service has a verified Azure2 path.
- Keep the service name as a short text label even when the icon is obvious.
- Do not mix verified Azure2 icons with generic blue boxes for the same diagram layer unless there is a clear reason.
- If only some services have official icons, use icons for those services and use neutral fallback boxes for the rest.
References
| File | Description |
|---|---|
| mxcell-structure.md | mxCell XML structure |
| cloud-icons.md | Azure/AWS icon guide |
| style-guide.md | Node colors, edge styles |
Scripts
| Script | Description |
|---|---|
scripts/validate_drawio.py | Validate mxCell structure |
Troubleshooting
| Issue | Solution |
|---|---|
| Blank in draw.io | Check content attribute |
| Edges not visible | Verify node IDs |
| Icons missing | Enable Azure/AWS shapes |
| Text overlaps near outer frame | Inset top note/callout boxes 16-24px from the panel border, increase box height, and wrap to 3-4 lines. Review at actual embed width before finishing. See style-guide.md Top Callouts / Note Boxes |
| README image only links to source | Generate *.drawio.svg and embed that instead of linking only to *.drawio |
| SVG is viewable but hard to edit later | Keep a paired *.drawio source and treat it as the editable SSOT; use SVG as delivery output, not as the only source file |
VS Code says a .drawio.svg or .drawio file cannot be opened even though the file exists | Check whether the file is actually a plain SVG misnamed as .drawio.svg; if so, rename it to *.svg. If path resolution still looks stale, create a short alias filename such as current-understanding.drawio / current-understanding.svg and repoint links |
| Local Markdown preview does not show the expected diagram | Export *.png from .drawio and use that in the draft article preview. Keep .drawio and *.drawio.svg as the editable and embeddable pair for final delivery |
| Too many crossing arrows | Align source/target y to make edges horizontal; spread entryY on shared targets. See style-guide.md Edge Crossing Prevention |
| Legend inside a container | Move legend outside the outermost box. See style-guide.md Nested Containers |
| Diagonal edge crosses a box | Move annotation boxes below diagonal endpoints. See style-guide.md Flow Diagrams |
| Title duplicated in PDF/HTML | Remove title mxCell from diagram; let the document layer handle captions |
| PNG export blurry or cropped | Use draw.io --export --format png --scale 2 instead of browser screenshot. See style-guide.md Export for PDF Pipelines |
Done Criteria
- [ ]
.drawioor.drawio.svgfile generated - [ ] Diagram opens correctly in VS Code Draw.io extension
- [ ] All nodes and edges visible
- [ ] Quality gate score ≥ 85
- [ ] If diagram is referenced from documentation, both editable source and embeddable image are provided
- [ ] Render review completed at the target embed width with no text overlap, clipping, or border collisions
# Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0)
## English
Copyright (c) 2025-2026 yamapan (aktsmm)
This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 4.0
International License.
You are free to:
- **Share** — copy and redistribute the material in any medium or format
- **Adapt** — remix, transform, and build upon the material
Under the following terms:
- **Attribution** — You must give appropriate credit, provide a link to the
license, and indicate if changes were made. You may do so in any reasonable manner,
but not in any way that suggests the licensor endorses you or your use.
- **NonCommercial** — You may not use the material for commercial purposes.
*(Please contact the author if you wish to use this material for commercial purposes.)*
- **ShareAlike** — If you remix, transform, or build upon the material, you must
distribute your contributions under the same license as the original.
No additional restrictions — You may not apply legal terms or technological
measures that legally restrict others from doing anything the license permits.
**AI/ML Training Restriction** — Use of this content for AI/ML training, data
mining, or other analytical purposes is prohibited without explicit permission.
Full license text: https://creativecommons.org/licenses/by-nc-sa/4.0/legalcode
---
## 日本語
Copyright (c) 2025-2026 yamapan (aktsmm)
この作品はクリエイティブ・コモンズ 表示-非営利-継承 4.0 国際ライセンスの下に提供されています。
あなたは以下の条件に従う限り、自由に:
- **共有** — どのようなメディアやフォーマットでも資料を複製・再配布できます
- **翻案** — 資料をリミックス、変形、および加工することができます
以下の条件に従ってください:
- **表示** — あなたは適切なクレジットを表示し、ライセンスへのリンクを提供し、
変更があったらその旨を示さなければなりません。これらは合理的であればどのような方法で
行っても構いませんが、許諾者があなたやあなたの利用行為を支持していると示唆するような
方法は除きます。
- **非営利** — あなたは営利目的でこの資料を利用してはなりません。
(※商用利用をご希望の場合は、別途ご連絡ください。)
- **継承** — もしあなたがこの資料をリミックス、変形、または加工した場合、
あなたはあなたの貢献部分を元の作品と同じライセンスの下で配布しなければなりません。
追加的な制約は課せません — あなたは、このライセンスが他の者に許諾することを法的に
制限するような法的条項や技術的手段を適用してはなりません。
**AI/MLトレーニング制限** — 本コンテンツをAI/MLモデルのトレーニング、データマイニング、
その他の解析目的での使用は明示的な許可なく禁止されています。
ライセンス全文: https://creativecommons.org/licenses/by-nc-sa/4.0/legalcode.ja
---
## Special Permission for Microsoft Employees / Microsoft 社員向け特別許諾
### English
Microsoft Corporation employees are granted permission to use, copy, modify, and
distribute this material for any purpose within the scope of their employment
duties at Microsoft, including internal business use and customer-facing
activities, without the NonCommercial restriction of this license.
This special permission applies only to work performed as part of official
Microsoft business activities.
### 日本語
Microsoft Corporation の社員は、Microsoft での業務の範疇において、本資料を社内業務
および顧客対応を含むあらゆる目的で使用、複製、改変、配布することが許諾されます。
この場合、本ライセンスの「非営利」制限は適用されません。
この特別許諾は、Microsoft の公式な業務活動の一環として行われる作業にのみ適用されます。
---
## Disclaimer / 免責事項
### English
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR
A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
### 日本語
本ソフトウェアは「現状のまま」で提供され、明示または黙示を問わず、商品性、
特定目的への適合性、および権利非侵害についての保証を含むがこれに限定されない、
いかなる種類の保証も伴いません。作者または著作権者は、契約行為、不法行為、
またはそれ以外であろうと、ソフトウェアに起因または関連し、あるいはソフトウェアの
使用またはその他の扱いによって生じる一切の請求、損害、その他の責任について
責任を負いません。
Cloud Icons Reference
⚠️ Critical: Azure Icon Format
*VS Code Draw.io Integration では `mxgraph.azure.` 形式が正しく表示されない。**
必ず img/lib/azure2/**/*.svg 形式を使用すること。
Icon Selection Policy
Azure 中心の構成図では、使える Azure アイコンは積極的に使う。
- Azure サービスに verified な Azure2 アイコンがあるなら、まずアイコン利用を検討する
- アイコンを使っても、サービス名の短いラベルは残す
- 同じ図の同じレイヤーでは、Azure アイコンと generic box を無秩序に混在させない
- アイコンが存在しない、誤解を招く、または図が読みにくくなる場合だけ generic box に落とす
- 初回レビューでは「この図で icon 化できるノードを box のまま放置していないか」を確認する
目安: Azure Architecture / Hub-Spoke / Landing Zone / Service topology のような図では、主要な Azure サービスは box より icon を優先する。
| 形式 | Web 版 | VS Code 版 | 推奨 |
|---|---|---|---|
shape=mxgraph.azure.* | ✅ | ❌ 青い四角 | ❌ |
image=img/lib/azure2/**/*.svg | ✅ | ✅ | ✅ |
🔧 Initial Setup (Required)
Azure/AWS アイコンを使うには、事前にシェイプライブラリを有効化する必要がある。
手順
1. .drawio ファイルを VS Code で開く 2. 左下の 「+ その他の図形」 (+ More Shapes) をクリック 3. 「図形」ダイアログが開く 4. 「ネットワーク」カテゴリで以下にチェック:
- ✅ Azure - Azure アイコン
- ✅ AWS17 / AWS18 / AWS 2026 - AWS アイコン(用途に応じて)
- ✅ AWS 3D - 3D 表現が必要な場合
5. 「設定を保存」 にチェック(次回以降も有効) 6. 「適用」 をクリック
推奨設定
| ライブラリ | 用途 | 推奨 |
|---|---|---|
| Azure | Azure サービスアイコン | ✅ 必須 |
| AWS 2026 | 最新 AWS アイコン | ✅ 推奨 |
| AWS18 | AWS アイコン(安定版) | ⚪ 任意 |
| AWS17 | AWS アイコン(レガシー) | ⚪ 任意 |
| AWS 3D | 3D アイコン | ⚪ 任意 |
Note: 設定は .drawio ファイルごとではなく、VS Code 全体で保存される。一度設定すれば他のファイルでも有効。Azure Icons (Azure2 形式)
Common Azure Icons
| Service | SVG Path | Category |
|---|---|---|
| Compute | ||
| Virtual Machine | img/lib/azure2/compute/Virtual_Machine.svg | compute |
| VM Scale Sets | img/lib/azure2/compute/VM_Scale_Sets.svg | compute |
| App Service | img/lib/azure2/compute/App_Services.svg | compute |
| Function Apps | img/lib/azure2/compute/Function_Apps.svg | compute |
| AKS | img/lib/azure2/compute/Azure_Kubernetes_Service.svg | compute |
| Container Instances | img/lib/azure2/compute/Container_Instances.svg | compute |
| Disks | img/lib/azure2/compute/Disks.svg | compute |
| Batch Accounts | img/lib/azure2/compute/Batch_Accounts.svg | compute |
| Containers | ||
| Container Registry | img/lib/azure2/containers/Container_Registries.svg | containers |
| Red Hat OpenShift | img/lib/azure2/containers/Azure_Red_Hat_OpenShift.svg | containers |
| Service Fabric | img/lib/azure2/containers/Service_Fabric_Clusters.svg | containers |
| Storage | ||
| Storage Account | img/lib/azure2/storage/Storage_Accounts.svg | storage |
| Databases | ||
| SQL Database | img/lib/azure2/databases/SQL_Database.svg | databases |
| SQL Managed Instance | img/lib/azure2/databases/SQL_Managed_Instance.svg | databases |
| Cosmos DB | img/lib/azure2/databases/Azure_Cosmos_DB.svg | databases |
| Redis Cache | img/lib/azure2/databases/Cache_Redis.svg | databases |
| MySQL | img/lib/azure2/databases/Azure_Database_MySQL_Server.svg | databases |
| PostgreSQL | img/lib/azure2/databases/Azure_Database_PostgreSQL_Server.svg | databases |
| Data Factory | img/lib/azure2/databases/Data_Factory.svg | databases |
| Synapse Analytics | img/lib/azure2/databases/Azure_Synapse_Analytics.svg | databases |
| Data Explorer | img/lib/azure2/databases/Azure_Data_Explorer_Clusters.svg | databases |
| Networking | ||
| Virtual Network | img/lib/azure2/networking/Virtual_Networks.svg | networking |
| Subnet | img/lib/azure2/networking/Subnet.svg | networking |
| Load Balancer | img/lib/azure2/networking/Load_Balancers.svg | networking |
| Application Gateway | img/lib/azure2/networking/Application_Gateways.svg | networking |
| Front Door | img/lib/azure2/networking/Front_Doors.svg | networking |
| ExpressRoute | img/lib/azure2/networking/ExpressRoute_Circuits.svg | networking |
| VPN Gateway | img/lib/azure2/networking/Virtual_Network_Gateways.svg | networking |
| Firewall | img/lib/azure2/networking/Firewalls.svg | networking |
| Bastion | img/lib/azure2/networking/Bastions.svg | networking |
| Private Endpoint | img/lib/azure2/networking/Private_Endpoint.svg | networking |
| Private Link | img/lib/azure2/networking/Private_Link.svg | networking |
| NSG | img/lib/azure2/networking/Network_Security_Groups.svg | networking |
| DNS Zone | img/lib/azure2/networking/DNS_Zones.svg | networking |
| Virtual WAN | img/lib/azure2/networking/Virtual_WANs.svg | networking |
| Virtual WAN Hub | img/lib/azure2/networking/Virtual_WAN_Hub.svg | networking |
| Traffic Manager | img/lib/azure2/networking/Traffic_Manager_Profiles.svg | networking |
| NAT Gateway | img/lib/azure2/networking/NAT.svg | networking |
| Networking (other) | ||
| VNet Peering | img/lib/azure2/other/Peerings.svg | other ⚠️ |
| Peering Service | img/lib/azure2/other/Peering_Service.svg | other ⚠️ |
| Local Network Gateway | img/lib/azure2/other/Local_Network_Gateways.svg | other ⚠️ |
| Private Endpoints | img/lib/azure2/other/Private_Endpoints.svg | other ⚠️ (複数形) |
| ExpressRoute Direct | img/lib/azure2/other/ExpressRoute_Direct.svg | other ⚠️ |
| Azure Network Manager | img/lib/azure2/other/Azure_Network_Manager.svg | other ⚠️ |
| Security | ||
| Key Vault | img/lib/azure2/security/Key_Vaults.svg | security |
| Defender | img/lib/azure2/security/Azure_Defender.svg | security |
| Sentinel | img/lib/azure2/security/Azure_Sentinel.svg | security |
| Security Center | img/lib/azure2/security/Security_Center.svg | security |
| Identity | ||
| Azure AD / Entra ID | img/lib/azure2/identity/Azure_Active_Directory.svg | identity |
| Integration | ||
| API Management | img/lib/azure2/integration/API_Management_Services.svg | integration |
| Logic Apps | img/lib/azure2/integration/Logic_Apps.svg | integration |
| Service Bus | img/lib/azure2/integration/Service_Bus.svg | integration |
| Analytics | ||
| Event Hubs | img/lib/azure2/analytics/Event_Hubs.svg | analytics |
| Databricks | img/lib/azure2/analytics/Azure_Databricks.svg | analytics |
| Stream Analytics | img/lib/azure2/analytics/Stream_Analytics_Jobs.svg | analytics |
| HDInsight | img/lib/azure2/analytics/HD_Insight_Clusters.svg | analytics |
| Power BI Embedded | img/lib/azure2/analytics/Power_BI_Embedded.svg | analytics |
| AI / ML | ||
| Azure OpenAI | img/lib/azure2/ai_machine_learning/Azure_OpenAI.svg | ai_machine_learning |
| Cognitive Services | img/lib/azure2/ai_machine_learning/Cognitive_Services.svg | ai_machine_learning |
| Machine Learning | img/lib/azure2/ai_machine_learning/Machine_Learning.svg | ai_machine_learning |
| Bot Services | img/lib/azure2/ai_machine_learning/Bot_Services.svg | ai_machine_learning |
| AI Studio | img/lib/azure2/ai_machine_learning/AI_Studio.svg | ai_machine_learning |
| Speech Services | img/lib/azure2/ai_machine_learning/Speech_Services.svg | ai_machine_learning |
| Computer Vision | img/lib/azure2/ai_machine_learning/Computer_Vision.svg | ai_machine_learning |
| Form Recognizer | img/lib/azure2/ai_machine_learning/Form_Recognizers.svg | ai_machine_learning |
| IoT | ||
| IoT Hub | img/lib/azure2/iot/IoT_Hub.svg | iot |
| IoT Central | img/lib/azure2/iot/IoT_Central_Applications.svg | iot |
| IoT Edge | img/lib/azure2/iot/IoT_Edge.svg | iot |
| Digital Twins | img/lib/azure2/iot/Digital_Twins.svg | iot |
| DevOps | ||
| Azure DevOps | img/lib/azure2/devops/Azure_DevOps.svg | devops |
| DevTest Labs | img/lib/azure2/devops/DevTest_Labs.svg | devops |
| Management | ||
| Monitor | img/lib/azure2/management_governance/Monitor.svg | management_governance |
| Log Analytics | img/lib/azure2/management_governance/Log_Analytics_Workspaces.svg | management_governance |
| Backup (Recovery) | img/lib/azure2/management_governance/Recovery_Services_Vaults.svg | management_governance |
| Application Insights | img/lib/azure2/management_governance/Application_Insights.svg | management_governance |
| Policy | img/lib/azure2/management_governance/Policy.svg | management_governance |
| Automation | img/lib/azure2/management_governance/Automation_Accounts.svg | management_governance |
| Azure Arc | img/lib/azure2/management_governance/Azure_Arc.svg | management_governance |
| Cost Management | img/lib/azure2/management_governance/Cost_Management_and_Billing.svg | management_governance |
Azure Icon Style (✅ Correct)
<mxCell id="vm1" value="VM-01"
style="aspect=fixed;html=1;points=[];align=center;image;fontSize=12;image=img/lib/azure2/compute/Virtual_Machine.svg;verticalLabelPosition=bottom;verticalAlign=top;"
vertex="1" parent="1">
<mxGeometry x="100" y="100" width="68" height="68" as="geometry"/>
</mxCell>Azure2 Library Structure
img/lib/azure2/
├── ai_machine_learning/ # Azure ML, Cognitive Services
├── analytics/ # Synapse, Event Hubs
├── compute/ # VM, App Service, Functions, AKS
├── containers/ # Container Instances
├── databases/ # SQL, Cosmos DB, Redis
├── devops/ # Azure DevOps
├── identity/ # Azure AD / Entra ID
├── integration/ # API Management, Logic Apps, Service Bus
├── iot/ # IoT Hub
├── management_governance/ # Monitor, Log Analytics, Recovery Services, Policy
├── networking/ # VNet, Load Balancer, Front Door, VPN (Virtual_Network_Gateways)
├── security/ # Key Vault, Defender, Sentinel
├── storage/ # Storage Accounts, Data Lake
└── web/ # App Service Plans⚠️ Common Mistakes (Verified against GitHub)
| サービス | ❌ 間違いやすいパス | ✅ 正しいパス |
|---|---|---|
| VPN Gateway | VPN_Gateway.svg | Virtual_Network_Gateways.svg |
| Azure Monitor | Azure_Monitor.svg | Monitor.svg |
| App Gateway | Application_Gateway.svg | Application_Gateways.svg (複数形) |
| Backup | Backup.svg | Recovery_Services_Vaults.svg |
🚫 Non-Existent Icons & Alternatives
以下のアイコンは draw.io の azure2 ライブラリに存在しない、またはパスが異なる。代替案を使用すること。
| サービス | ❌ よくある間違い | ✅ 正しいパス / 代替案 |
|---|---|---|
| Cloud Shell | general/Cloud_Shell.svg | other/Azure_Cloud_Shell.svg |
| Container Apps | compute/Container_Apps.svg | other/Worker_Container_App.svg または other/Container_App_Environments.svg |
| Communication Services | integration/Communication_Services.svg | other/Azure_Communication_Services.svg |
| Private DNS Zones | networking/Private_DNS_Zones.svg | networking/DNS_Zones.svg |
| GitHub / GitHub Actions | other/GitHub.svg devops/GitHub_Actions.svg | 濃灰の角丸ボックス + テキスト(ライブラリに存在しない) |
| Internet | networking/Internet.svg | shape=cloud (汎用雲形状) |
| App Configuration | integration/App_Configuration.svg | テキストのみ or management_governance/Automation_Accounts.svg |
| Static Web Apps | web/Static_Web_Apps.svg | app_services/Static_Apps.svg (要確認) |
🔍 other/ カテゴリに注目
多くの新しい Azure サービスは other/ カテゴリに配置されている。見つからない場合は other/ を確認:
other/Azure_Cloud_Shell.svgother/Azure_Communication_Services.svgother/Container_App_Environments.svgother/Worker_Container_App.svgother/Grafana.svgother/Azure_Load_Testing.svgother/MS_Dev_Box.svgother/Private_Endpoints.svgother/Local_Network_Gateways.svgother/ExpressRoute_Direct.svg
代替スタイル例
角丸ボックス + テキスト(GitHub 向け):
<mxCell value="Cloud Shell"
style="rounded=1;whiteSpace=wrap;html=1;fillColor=#0078D4;strokeColor=#005A9E;fontColor=#FFFFFF;fontSize=12;fontStyle=1;"
vertex="1" parent="1">
<mxGeometry x="100" y="100" width="100" height="40" as="geometry"/>
</mxCell>雲形状(Internet 向け):
<mxCell value="Internet"
style="ellipse;shape=cloud;whiteSpace=wrap;html=1;fillColor=#F5F5F5;strokeColor=#666666;"
vertex="1" parent="1">
<mxGeometry x="100" y="100" width="120" height="80" as="geometry"/>
</mxCell>💡 Tip: 新しい Azure サービスはアイコンがライブラリに追加されるまで時間がかかる。テキストボックスで対応し、将来のアップデートで置換可能にする。
AWS Icons (AWS4 形式)
Setup
1. Open .drawio file in VS Code 2. Click "+ More Shapes" (bottom-left) 3. Check AWS 4. Click Apply
Common AWS Icons
| Service | resIcon Value | Category |
|---|---|---|
| EC2 | mxgraph.aws4.ec2 | Compute |
| Lambda | mxgraph.aws4.lambda | Compute |
| ECS | mxgraph.aws4.ecs | Containers |
| EKS | mxgraph.aws4.eks | Containers |
| S3 | mxgraph.aws4.s3 | Storage |
| RDS | mxgraph.aws4.rds | Database |
| DynamoDB | mxgraph.aws4.dynamodb | Database |
| VPC | mxgraph.aws4.vpc | Networking |
| ELB | mxgraph.aws4.elastic_load_balancing | Networking |
| CloudFront | mxgraph.aws4.cloudfront | Networking |
| Route 53 | mxgraph.aws4.route_53 | Networking |
| IAM | mxgraph.aws4.identity_and_access_management_iam | Security |
| API Gateway | mxgraph.aws4.api_gateway | Integration |
AWS Icon Style
<mxCell id="ec2" value="EC2"
style="sketch=0;outlineConnect=0;fontColor=#232F3E;gradientColor=none;strokeColor=#ffffff;fillColor=#232F3E;dashed=0;verticalLabelPosition=bottom;verticalAlign=top;align=center;html=1;fontSize=12;fontStyle=0;aspect=fixed;shape=mxgraph.aws4.resourceIcon;resIcon=mxgraph.aws4.ec2;"
vertex="1" parent="1">
<mxGeometry x="100" y="100" width="50" height="50" as="geometry"/>
</mxCell>Style Comparison
| Attribute | Azure2 (✅) | AWS4 | Azure 旧形式 (❌) |
|---|---|---|---|
shape | 不要 | mxgraph.aws4.resourceIcon | mxgraph.azure.* |
image | img/lib/azure2/**/*.svg | 不要 | 不要 |
resIcon | 不要 | mxgraph.aws4.* | 不要 |
aspect | fixed | fixed | なし |
fillColor | 不要(SVG 内) | #232F3E | 指定必要 |
Best Practices
1. Azure は必ず `img/lib/azure2/` 形式を使用 2. Consistency: Use icons from the same provider in one diagram 3. Labeling: Always add text labels below icons 4. Sizing: Keep icon sizes consistent (68x68 for Azure, 50x50 for AWS) 5. Grouping: Use containers/swimlanes to group related services
Validation Checklist
生成後に確認:
- [ ] Azure アイコンが
img/lib/azure2/パスを使用している - [ ]
shape=mxgraph.azure.*が含まれていない - [ ] VS Code Draw.io Integration で正しく表示される
Icon Detection Keywords
When the input mentions these keywords, use corresponding cloud icons:
Azure Keywords
Azure,Microsoft CloudVM,Virtual Machine(in Azure context)App Service,Function App,Logic AppVNET,Virtual NetworkAAD,Azure AD,Entra ID
AWS Keywords
AWS,Amazon Web ServicesEC2,Lambda,ECS,EKSS3,RDS,DynamoDBVPC,CloudFront,Route 53
Reference
AWS → Azure Migration Patterns
AWS 図を Azure 化する際のサービス対応表:
| AWS Service | Azure Equivalent | Azure Icon Path |
|---|---|---|
| VPC | Virtual Network | img/lib/azure2/networking/Virtual_Networks.svg |
| Subnet | Subnet | img/lib/azure2/networking/Subnet.svg |
| EC2 | Virtual Machine | img/lib/azure2/compute/Virtual_Machine.svg |
| RDS | Azure SQL / Cosmos DB | img/lib/azure2/databases/SQL_Database.svg |
| S3 | Storage Account (Blob) | img/lib/azure2/storage/Storage_Accounts.svg |
| Lambda | Function Apps | img/lib/azure2/compute/Function_Apps.svg |
| EKS | AKS | img/lib/azure2/compute/Azure_Kubernetes_Service.svg |
| ALB/NLB | Load Balancer | img/lib/azure2/networking/Load_Balancers.svg |
| CloudFront | Front Door / CDN | img/lib/azure2/networking/Front_Doors.svg |
| Route 53 | Azure DNS | img/lib/azure2/networking/DNS_Zones.svg |
| Network Firewall | Azure Firewall | img/lib/azure2/networking/Firewalls.svg |
| NAT Gateway | Azure Firewall (SNAT) | Azure Firewall に統合可能 |
| VPC Endpoint | Private Endpoint | img/lib/azure2/networking/Private_Endpoint.svg |
| Service Endpoint | Private Endpoint | img/lib/azure2/networking/Private_Endpoint.svg |
| Transit Gateway | Virtual WAN Hub | img/lib/azure2/networking/Virtual_WAN_Hub.svg |
| Direct Connect | ExpressRoute | img/lib/azure2/networking/ExpressRoute_Circuits.svg |
| Site-to-Site VPN | VPN Gateway | img/lib/azure2/networking/Virtual_Network_Gateways.svg |
| IAM | Azure AD / Entra ID | img/lib/azure2/identity/Azure_Active_Directory.svg |
| KMS | Key Vault | img/lib/azure2/security/Key_Vaults.svg |
| CloudWatch | Azure Monitor | img/lib/azure2/management_governance/Monitor.svg |
| GuardDuty | Defender / Sentinel | img/lib/azure2/security/Azure_Defender.svg |
Migration Tips
1. NAT Gateway → Azure Firewall: Azure では Firewall が SNAT 機能を持つため、NAT Gateway を別途配置せず Firewall 直結構成が可能 2. Service Endpoint → Private Endpoint: Azure では Private Endpoint が推奨。より安全なプライベート接続を提供 3. 形式変換: mxgraph.aws4.* や mxgraph.azure.* は img/lib/azure2/**/*.svg 形式に置換
Conversion Commands
# sed での一括置換例(旧形式 → 新形式は手動対応推奨)
sed -i 's/mxgraph\.azure3\./mxgraph.azure./g' diagram.drawio# ID重複チェック(編集時に発生しやすい)
import re, collections, pathlib
p = pathlib.Path('diagram.drawio')
text = p.read_text(encoding='utf-8')
ids = re.findall(r'\bid="([^"]+)"', text)
ctr = collections.Counter(ids)
dups = [i for i,c in ctr.items() if c > 1]
if dups:
print(f'⚠️ Duplicate IDs: {dups}')Azure Architecture Patterns
Hub-Spoke Topology Icons
典型的な Hub-Spoke アーキテクチャで使用するアイコン:
| Layer | Components | Icons |
|---|---|---|
| On-Premises | Users, AD, Servers | 汎用アイコン or カスタム |
| Hybrid Connection | ExpressRoute, VPN Gateway | ExpressRoute_Circuits.svg, Virtual_Network_Gateways.svg |
| Hub VNet | Firewall, Bastion, DNS, Key Vault | Firewalls.svg, Bastions.svg, DNS_Zones.svg, Key_Vaults.svg |
| Hub Services | Monitor, Backup, Defender | Monitor.svg, Recovery_Services_Vaults.svg, Azure_Defender.svg |
| Spoke VNets | Production, Development, Shared Services | Virtual_Networks.svg + ラベルで区別 |
Example: Hub VNet Components
<!-- Firewall -->
<mxCell value="Azure Firewall"
style="aspect=fixed;image=img/lib/azure2/networking/Firewalls.svg;..."
.../>
<!-- Bastion -->
<mxCell value="Bastion"
style="aspect=fixed;image=img/lib/azure2/networking/Bastions.svg;..."
.../>
<!-- Monitor -->
<mxCell value="Azure Monitor"
style="aspect=fixed;image=img/lib/azure2/management_governance/Monitor.svg;..."
.../>
<!-- Backup (Recovery Services) -->
<mxCell value="Backup"
style="aspect=fixed;image=img/lib/azure2/management_governance/Recovery_Services_Vaults.svg;..."
.../>mxCell Structure Reference
mxfile Structure
<mxfile host="app.diagrams.net" generator="diagram-forge">
<diagram id="..." name="Page-1">
<mxGraphModel dx="..." dy="..." grid="1" gridSize="10">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
<!-- Nodes and edges here -->
</root>
</mxGraphModel>
</diagram>
</mxfile>Required Elements
| Element | Description | Required |
|---|---|---|
mxCell id="0" | Root cell | ✅ |
mxCell id="1" parent="0" | Default parent | ✅ |
| Node mxCell | Has vertex="1" | ✅ |
| Edge mxCell | Has edge="1" | ✅ |
Node Examples
Rectangle
<mxCell id="node1" value="Node Name"
style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;"
vertex="1" parent="1">
<mxGeometry x="100" y="100" width="120" height="60" as="geometry"/>
</mxCell>Ellipse (Start/End)
<mxCell id="start" value="Start"
style="ellipse;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;"
vertex="1" parent="1">
<mxGeometry x="100" y="100" width="80" height="50" as="geometry"/>
</mxCell>Diamond (Decision)
<mxCell id="decision1" value="Condition?"
style="rhombus;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;"
vertex="1" parent="1">
<mxGeometry x="100" y="100" width="100" height="80" as="geometry"/>
</mxCell>Edge Examples
Arrow
<mxCell id="edge1" value=""
style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;"
edge="1" parent="1" source="node1" target="node2">
<mxGeometry relative="1" as="geometry"/>
</mxCell>Labeled Edge
<mxCell id="edge2" value="Yes"
style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;"
edge="1" parent="1" source="decision1" target="node3">
<mxGeometry relative="1" as="geometry"/>
</mxCell>Group (Container)
<!-- Container -->
<mxCell id="group1" value="Group Name"
style="swimlane;horizontal=1;startSize=30;fillColor=#f5f5f5;strokeColor=#666666;"
vertex="1" parent="1">
<mxGeometry x="50" y="50" width="300" height="200" as="geometry"/>
</mxCell>
<!-- Child node (parent="group1") -->
<mxCell id="child1" value="Child Node"
style="rounded=1;whiteSpace=wrap;html=1;"
vertex="1" parent="group1">
<mxGeometry x="20" y="40" width="100" height="50" as="geometry"/>
</mxCell>HTML Encoding
Content attribute requires HTML encoding:
| Character | Encoded |
|---|---|
< | < |
> | > |
" | " |
& | & |
Validation Checklist
- [ ]
mxCell id="0"andid="1"exist - [ ] All nodes have
vertex="1" - [ ] All edges have
edge="1" - [ ] Edge
source/targetreference valid node IDs - [ ]
mxGeometrydefined for each mxCell - [ ] Content attribute properly HTML encoded
- [ ] mxCell count >= 2 + nodes + edges
Style Guide
Node Colors
| Purpose | fillColor | strokeColor | Example Use |
|---|---|---|---|
| Standard | #dae8fc | #6c8ebf | Default nodes |
| Start/End | #d5e8d4 | #82b366 | Process start/end |
| Decision | #fff2cc | #d6b656 | Conditions, branches |
| Error/Warning | #f8cecc | #b85450 | Error states |
| External | #e1d5e7 | #9673a6 | External systems |
| Neutral | #f5f5f5 | #666666 | Groups, containers |
Edge Styles
Orthogonal (Recommended)
edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;Curved
edgeStyle=elbowEdgeStyle;elbow=horizontal;rounded=1;Straight
endArrow=classic;html=1;Shape Styles
Rounded Rectangle
rounded=1;whiteSpace=wrap;html=1;Ellipse
ellipse;whiteSpace=wrap;html=1;Diamond
rhombus;whiteSpace=wrap;html=1;Swimlane/Container
swimlane;horizontal=1;startSize=30;Layout Recommendations
Title / Caption
- Do NOT embed title text in the diagram (e.g., "図1-1 ..."). Captions belong in the document layer (Markdown
, Re:VIEW//image[id][caption], etc.). - Embedding titles causes duplication when the document already renders a figure caption.
- If the exported image is likely to circulate standalone (chat, slide, ticket, SNS, pasted image), use the diagram title/subtitle to identify the feature or topic name directly. Avoid generic headings like
before / afteralone. - Good:
Summarized Gateway Prefixes の before / after - Weak:
ExpressRoute の広告ルート数を before / after でみるwhen the feature name is missing from the image itself.
Spacing
| Element | Recommended Gap |
|---|---|
| Horizontal nodes | 50-80px |
| Vertical nodes | 40-60px |
| Group padding | 20px |
| Edge clearance | 10px minimum |
Top Callouts / Note Boxes
For explanatory note boxes placed near the top of a panel or container:
- Inset from the outer frame by at least 16-24px. Do not let the note box kiss or visually merge with the panel border.
- Prefer 3-4 short lines over 2 long lines. If Japanese text feels tight, reduce line length before reducing font size.
- Increase note box height first when text feels crowded. Do not solve crowding only by shrinking fonts.
- Keep arrow labels on a separate Y band from the note box. Labels that sit at the same height tend to look overlapped in exports.
- Review at actual embed width after export. A diagram that looks fine at full canvas size can still collide when embedded in Markdown or docs.
Article Concept / Lifecycle Diagrams
For article-facing concept diagrams that explain a repeated workflow:
- Use a single visible start point. If the flow begins from multiple places, readers often cannot tell what to follow first.
- For metric diagrams such as usage rate, show denominator and numerator explicitly, then summarize the formula in one final node. Avoid long dashed aggregation lines that make the diagram feel like a wiring diagram.
- Keep the main cycle to 3-4 primary nodes. Support tools, marketplaces, and implementation aids should be a footer note or side callout, not peer nodes in the main loop.
- Use outcome-oriented node titles such as
Skill を改善, not implementation-detail titles such asGotchas に戻す. Highlight the important detail (Gotchas) inside the node body instead. - Split long slash-separated phrases into separate short lines. If a line like
description / Gotchas / referencesfeels tight at embed width, rewrite it asdescription を整える+Gotchas / references に分ける. - Shrink-wrap the canvas after layout changes. If footer notes move up, reduce page height so exported assets do not carry large dead whitespace.
- Validate both source and delivery artifacts after wording tweaks:
.drawiois the editable SSOT, and.drawio.svgis the Markdown/web artifact.
Edge Crossing Prevention
For complex diagrams (>15 nodes) with many-to-one or fan-out edges:
- Align source and target y — place each agent/processor at the same y as its output node. Lines stay horizontal, crossing drops to near zero.
- Reorder sibling nodes before drawing detours — if a connector from one item in a stacked group must jump around another item, first swap or move the related item closer to its target/callout. A short straight connector is usually clearer than a routed line that skirts sibling boxes.
- Avoid swimlane-relative coordinates — when edges cross swimlane boundaries,
exitX/entryYresolve to group-relative positions that are hard to predict. Use absolute positioning (parent="1") for all nodes instead. - Spread entryY on shared targets — when multiple edges enter the same node, enlarge the node height and assign distinct
entryYvalues (e.g., 0.1 / 0.5 / 0.9) so lines arrive at different vertical points. - Collapse fan-out into one edge — instead of N individual arrows from an orchestrator to N children, draw a single dashed arrow to a group outline and label it (e.g., "delegates").
- Separate auxiliary elements — legends, data stores, and footnotes must sit below the main flow with ≥40px vertical gap from the lowest flow node. Never place them at the same y as flow outputs.
Nested Containers (Hierarchy Diagrams)
When using nested rectangles to show hierarchy (e.g., Enterprise > Org > Team > Repo):
- Container height = content bottom edge + 15–20px padding. Do not use large fixed heights when children are few.
- Legend placement = always outside the outermost container. Never inside a child container — it reads as part of that group.
- Page size = tightest bounding box of all elements + 20px margin. Avoid "generous" pages that create dead whitespace.
- Edges are optional — spatial containment already conveys hierarchy. Only add arrows when showing data/control flow across containers.
Flow Diagrams (Branch/Merge Lines)
When combining diagonal branch/merge lines with annotation boxes (e.g., GitHub Flow step labels):
- Place step boxes below the diagonal endpoints — if a diagonal goes from (x1,y1) to (x2,y2), boxes must have
y > max(y1, y2)to avoid crossing. - Dashed connectors starting from a box edge should begin at
y - 2px(not exactly at the top edge) to avoid false overlap in validators. - Keep horizontal feature branch and step row on separate Y bands — minimum 40px gap between the branch line Y and the top of step boxes.
Icons On Connectors
When a small service icon sits close to a busy connector or arrow:
- Prefer icon-only and let the nearby node / edge label carry the meaning. Do not force a second label under the icon if it creates collisions.
- Move the icon 10-20px away from the connector centerline before shrinking it further.
- Keep the icon above the connector in z-order / draw order so the arrow does not cut through the symbol.
- If the connector already has a readable label, avoid repeating the same service name under the icon.
Alignment
- Align nodes in grid (gridSize=10)
- Center labels in nodes
- Use consistent node sizes
- Container with children →
verticalAlign=top;spacingTop=5;to keep the label above child nodes - Standalone box (no children) →
verticalAlign=middle;to center text and avoid lopsided whitespace
Public-safe Labels
- For diagrams that may be published externally, avoid customer-specific or vendor-internal acronyms unless the acronym itself is the subject of the diagram.
- Prefer generic labels such as
On-premises gateway,On-premises router, orEdge networkover terms that only make sense in one customer's environment. - If an internal acronym must appear somewhere, keep it in the surrounding article text, not as the primary label inside the figure.
Diagram Size
| Complexity | Recommended Canvas |
|---|---|
| Simple (≤5 nodes) | 800–900 × 400–500 |
| Moderate (6-15 nodes) | 1000–1200 × 500–700 |
| Complex (>15 nodes) | 1200–1600 × 700–1000 |
Always shrink-wrap: set page width/height to tightest bounding box + 20px margin.
Editable Source Policy
- Treat
.drawioas the editable source of truth for documentation diagrams. - Treat
.drawio.svgas the delivery/render artifact for Markdown and web embedding. - Do not label a plain SVG as
.drawio.svg. That suffix is reserved for metadata-embedded SVG exports that Draw.io can reopen. - If a diagram required manual SVG-level cleanup, recreate or preserve the equivalent
.drawiosource before calling it done. - Do not leave a documentation diagram as SVG-only unless the user explicitly asked for a disposable one-off artifact.
- If the editor keeps resolving a stale path or refuses to open a file that exists, it is acceptable to create short alias filenames such as
current-understanding.drawioandcurrent-understanding.svg, then repoint local links to the alias pair.
Font Settings
fontSize=12;fontStyle=0;fontFamily=Helvetica;| Element | Font Size |
|---|---|
| Node label | 12px |
| Edge label | 10px |
| Group title | 14px |
For book/PDF diagrams that are scaled down by the publishing pipeline, raise the floor before export:
- Use at least
13pxfor minor labels,15-17pxfor edge/action labels, and17-23pxfor primary state or step nodes. - Delete legend, tips, and sentence-like explanations from the figure when the surrounding text already explains them. Extra text shrinks the real teaching labels.
- Use dead whitespace to enlarge boxes and labels, then shrink-wrap the canvas. A wide empty margin makes every label smaller in the final PDF.
- Put arrow labels on their own lane, or remove labels already implied by nearby text. Never let a label hide the arrow shaft or arrowhead.
- For hierarchy diagrams, stack sparse sibling groups vertically when that lets labels and child boxes grow.
- For workflow diagrams, move trigger/source groups above the main workflow when side-by-side placement creates wasted width.
Export for PDF Pipelines
When diagrams are embedded in PDF (via Re:VIEW, LaTeX, Pandoc, etc.):
- Export directly from `.drawio` to PNG using the draw.io desktop CLI:
draw.io --export --format png --scale 2 --output out.png source.drawio- Do NOT use browser/Edge `--screenshot` on SVG — this produces a fixed-viewport capture (e.g., 756×488) regardless of diagram size, causing blurriness and cropping.
--scale 2produces 2× resolution for crisp text at print DPI.- The exported SVG from draw.io CLI is "plain SVG" (not re-editable in the VS Code Draw.io extension). Keep the
.drawioas the editable source. - For Markdown preview, reference
*.drawio.svg. For PDF build, use the PNG export. - Render the final PDF page, not only the exported PNG. The publishing layer may scale, float, or move the image.
- If changing a wrapper macro does not affect image size, inspect generated TeX for per-image options such as
width=\maxwidth. In that case, enlarge the diagram content and shrink-wrap the canvas instead of assuming the global width rule applies.
#!/usr/bin/env python3
"""
validate_drawio.py - Validate draw.io file mxCell structure
Usage:
python validate_drawio.py <file.drawio>
python validate_drawio.py <directory>
Checks:
- mxfile generator attribute
- Root cells (id=0, id=1) exist
- mxCell count >= 2 + vertices + edges
- Edge source/target references valid
"""
import xml.etree.ElementTree as ET
import sys
import os
from pathlib import Path
def validate_drawio(filepath: str) -> dict:
"""Validate a single .drawio file and return results."""
result = {
"file": os.path.basename(filepath),
"valid": True,
"errors": [],
"warnings": [],
"stats": {}
}
try:
tree = ET.parse(filepath)
root = tree.getroot()
except ET.ParseError as e:
result["valid"] = False
result["errors"].append(f"XML parse error: {e}")
return result
# Check generator attribute
generator = root.get("generator", "")
result["stats"]["generator"] = generator or "(not set)"
if not generator:
result["warnings"].append("generator attribute not set in mxfile")
# Find all mxCells
cells = root.findall(".//mxCell")
cell_ids = {c.get("id") for c in cells}
# Check for duplicate IDs
from collections import Counter
all_ids = [c.get("id") for c in cells if c.get("id")]
id_counts = Counter(all_ids)
duplicates = [id_ for id_, count in id_counts.items() if count > 1]
if duplicates:
result["valid"] = False
result["errors"].append(
f"Duplicate cell IDs found: {duplicates}"
)
vertices = [c for c in cells if c.get("vertex") == "1"]
edges = [c for c in cells if c.get("edge") == "1"]
result["stats"]["total_mxcells"] = len(cells)
result["stats"]["vertices"] = len(vertices)
result["stats"]["edges"] = len(edges)
# Check root cells
has_root_0 = "0" in cell_ids
has_root_1 = "1" in cell_ids
if not has_root_0:
result["valid"] = False
result["errors"].append("Missing root mxCell id='0'")
if not has_root_1:
result["valid"] = False
result["errors"].append("Missing root mxCell id='1'")
# Check mxCell completeness
expected_min = 2 + len(vertices) + len(edges)
if len(cells) < expected_min:
result["warnings"].append(
f"mxCell count ({len(cells)}) may be incomplete. "
f"Expected >= {expected_min}"
)
# Check edge references
for edge in edges:
edge_id = edge.get("id", "unknown")
source = edge.get("source")
target = edge.get("target")
if source and source not in cell_ids:
result["valid"] = False
result["errors"].append(
f"Edge '{edge_id}' references invalid source '{source}'"
)
if target and target not in cell_ids:
result["valid"] = False
result["errors"].append(
f"Edge '{edge_id}' references invalid target '{target}'"
)
# Check mxGeometry
for cell in vertices + edges:
cell_id = cell.get("id", "unknown")
geom = cell.find("mxGeometry")
if geom is None:
result["warnings"].append(
f"mxCell '{cell_id}' missing mxGeometry"
)
# Check for deprecated Azure icon format (mxgraph.azure.*)
import re
file_content = Path(filepath).read_text(encoding="utf-8")
azure_old_pattern = re.findall(r'mxgraph\.azure[^2]', file_content)
if azure_old_pattern:
result["warnings"].append(
f"Deprecated Azure format detected: 'mxgraph.azure.*' "
f"Use 'img/lib/azure2/**/*.svg' instead for VS Code compatibility"
)
# Check diagonal edges crossing vertex boxes
_check_edge_box_overlap(root, result)
return result
def _check_edge_box_overlap(root, result: dict) -> None:
"""Detect diagonal edges whose path crosses through vertex bounding boxes."""
import re as _re
cells = root.findall(".//mxCell")
vertices = [c for c in cells if c.get("vertex") == "1"]
edges = [c for c in cells if c.get("edge") == "1"]
# Collect vertex bounding boxes
boxes = {}
for v in vertices:
vid = v.get("id", "")
geom = v.find("mxGeometry")
if geom is None:
continue
try:
x = float(geom.get("x", 0))
y = float(geom.get("y", 0))
w = float(geom.get("width", 0))
h = float(geom.get("height", 0))
except (TypeError, ValueError):
continue
if w > 0 and h > 0:
# Skip tiny markers (dots, icons) — only check substantial boxes
if w >= 30 and h >= 30:
boxes[vid] = (x, y, w, h)
# Collect edges with explicit source/target points (diagonal lines)
for edge in edges:
edge_id = edge.get("id", "unknown")
geom = edge.find("mxGeometry")
if geom is None:
continue
src_pt = geom.find("mxPoint[@as='sourcePoint']")
tgt_pt = geom.find("mxPoint[@as='targetPoint']")
if src_pt is None or tgt_pt is None:
continue
try:
sx = float(src_pt.get("x", 0))
sy = float(src_pt.get("y", 0))
tx = float(tgt_pt.get("x", 0))
ty = float(tgt_pt.get("y", 0))
except (TypeError, ValueError):
continue
# Skip horizontal/vertical edges (no diagonal crossing concern)
if sx == tx or sy == ty:
continue
for vid, (bx, by, bw, bh) in boxes.items():
# Quick bounding-box rejection
if bx + bw < min(sx, tx) or bx > max(sx, tx):
continue
if by + bh < min(sy, ty) or by > max(sy, ty):
continue
# Line Y at box center X
cx = bx + bw / 2
line_y = sy + (ty - sy) * (cx - sx) / (tx - sx)
if by <= line_y <= by + bh:
result["warnings"].append(
f"Edge '{edge_id}' diagonal ({sx:.0f},{sy:.0f})->({tx:.0f},{ty:.0f}) "
f"crosses vertex '{vid}' box"
)
def print_result(result: dict) -> None:
"""Print validation result in readable format."""
status = "✅ VALID" if result["valid"] else "❌ INVALID"
print(f"\n{'='*50}")
print(f"File: {result['file']}")
print(f"Status: {status}")
print(f"{'='*50}")
stats = result["stats"]
print(f"\nStatistics:")
print(f" Generator: {stats.get('generator', 'N/A')}")
print(f" Total mxCells: {stats.get('total_mxcells', 0)}")
print(f" Vertices: {stats.get('vertices', 0)}")
print(f" Edges: {stats.get('edges', 0)}")
if result["errors"]:
print(f"\n🚨 Errors ({len(result['errors'])}):")
for err in result["errors"]:
print(f" - {err}")
if result["warnings"]:
print(f"\n⚠️ Warnings ({len(result['warnings'])}):")
for warn in result["warnings"]:
print(f" - {warn}")
def main():
if len(sys.argv) < 2:
print("Usage: python validate_drawio.py <file.drawio|directory>")
sys.exit(1)
target = sys.argv[1]
files = []
if os.path.isdir(target):
# Find all .drawio files in directory
for ext in ["*.drawio", "*.drawio.svg"]:
files.extend(Path(target).glob(ext))
elif os.path.isfile(target):
files = [Path(target)]
else:
print(f"Error: '{target}' not found")
sys.exit(1)
if not files:
print(f"No .drawio files found in '{target}'")
sys.exit(1)
all_valid = True
for filepath in files:
result = validate_drawio(str(filepath))
print_result(result)
if not result["valid"]:
all_valid = False
print(f"\n{'='*50}")
if all_valid:
print("✅ All files validated successfully")
else:
print("❌ Some files have validation errors")
sys.exit(1)
if __name__ == "__main__":
main()