conditional-formatting
Data-driven conditional formatting, live data binding, and dynamic diagram updates for draw.io
What this skill does
# Conditional Formatting and Data-Driven Diagrams
## Custom Properties with Object Tags
Wrap `mxCell` in an `<object>` tag to attach arbitrary key-value metadata to any diagram element:
```xml
<object label="Service A" id="2"
service-id="svc-api-gateway"
status="healthy"
latency="45ms"
uptime="99.97%"
owner="platform-team"
environment="production"
region="us-east-1">
<mxCell style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;"
vertex="1" parent="1">
<mxGeometry x="100" y="100" width="120" height="60" as="geometry"/>
</mxCell>
</object>
```
Key points:
- `label` replaces `value` as the display text
- `id` moves from `mxCell` to `<object>`
- Any attribute name is valid (use lowercase with hyphens)
- Properties are visible in draw.io's **Edit Data** dialog (Ctrl+M)
- Properties are searchable via **Edit > Find/Replace**
## Placeholder Variables
Display property values dynamically inside labels using `%property%` syntax. Enable with `placeholders=1` in the style:
```xml
<object label="%name%<br>Status: %status%<br>Latency: %latency%"
id="3" placeholders="1"
name="API Gateway"
status="healthy"
latency="42ms">
<mxCell style="rounded=1;whiteSpace=wrap;html=1;placeholders=1;fillColor=#dae8fc;strokeColor=#6c8ebf;"
vertex="1" parent="1">
<mxGeometry x="100" y="100" width="160" height="80" as="geometry"/>
</mxCell>
</object>
```
**Rendered label:**
```
API Gateway
Status: healthy
Latency: 42ms
```
### Built-in Placeholders
| Placeholder | Value |
|-------------|-------|
| `%label%` | Cell label |
| `%id%` | Cell ID |
| `%date%` | Current date |
| `%time%` | Current time |
| `%timestamp%` | ISO timestamp |
| `%page%` | Page number |
| `%pagenumber%` | Page number (alias) |
| `%pagecount%` | Total pages |
| `%filename%` | File name |
## File-Level Variables
Set global variables at the `<mxfile>` level, accessible by all cells:
```xml
<mxfile vars='{"env":"production","version":"2.1.0","region":"us-east-1","last_updated":"2026-03-14"}'>
<diagram id="page1" name="Status Dashboard">
<mxGraphModel>
<root>
<mxCell id="0"/>
<mxCell id="1" parent="0"/>
<object label="Environment: %env%<br>Version: %version%<br>Region: %region%"
id="header" placeholders="1">
<mxCell style="text;fontSize=14;fontStyle=1;placeholders=1;" vertex="1" parent="1">
<mxGeometry x="20" y="20" width="300" height="60" as="geometry"/>
</mxCell>
</object>
</root>
</mxGraphModel>
</diagram>
</mxfile>
```
File-level variables are inherited by all cells that use `placeholders=1` and do not have a local property with the same name.
## Conditional Formatting Rules
### Status to Color Mapping
The most common pattern: map a property value to fill/stroke colors.
| Status | Fill Color | Stroke Color | Icon |
|--------|-----------|-------------|------|
| healthy / up / ok | `#D5E8D4` | `#82B366` | Green |
| warning / degraded | `#FFF2CC` | `#D6B656` | Yellow |
| critical / down / error | `#F8CECC` | `#B85450` | Red |
| maintenance / paused | `#E1D5E7` | `#9673A6` | Purple |
| unknown / pending | `#F5F5F5` | `#666666` | Gray |
| info / active | `#DAE8FC` | `#6C8EBF` | Blue |
### Threshold-Based Color Gradients
Map numeric values to colors using thresholds:
| Metric | Green | Yellow | Red |
|--------|-------|--------|-----|
| Latency | < 100ms | 100-500ms | > 500ms |
| CPU | < 60% | 60-85% | > 85% |
| Error Rate | < 1% | 1-5% | > 5% |
| Uptime | > 99.9% | 99-99.9% | < 99% |
| Disk | < 70% | 70-90% | > 90% |
### Boolean Visibility
Show or hide elements based on boolean properties:
| Condition | Visible Style | Hidden Style |
|-----------|--------------|-------------|
| Feature enabled | `opacity=100;` | `opacity=20;dashed=1;` |
| Service active | Normal styles | `strokeColor=#CCCCCC;fillColor=#F5F5F5;fontColor=#999999;` |
| Deprecated | Normal + label | `dashed=1;dashPattern=8 4;fontStyle=2;` (italic) |
### Enumeration to Shape/Icon
Map state values to different visual representations:
| State | Visual |
|-------|--------|
| running | Green circle icon |
| stopped | Red square icon |
| starting | Yellow spinner icon |
| terminating | Orange triangle icon |
## Python Update Script
Full-featured script that reads a data source and updates diagram XML:
```python
#!/usr/bin/env python3
"""
update_diagram.py - Update draw.io diagram with live data.
Usage:
python update_diagram.py --input arch.drawio --output arch-live.drawio --data-url https://api.example.com/health
python update_diagram.py --input arch.drawio --output arch-live.drawio --data-file status.json
"""
import xml.etree.ElementTree as ET
import json
import argparse
import re
import sys
import urllib.request
import urllib.error
import base64
import zlib
from datetime import datetime, timezone
# Status-to-color mapping
STATUS_COLORS = {
'healthy': {'fill': '#D5E8D4', 'stroke': '#82B366'},
'up': {'fill': '#D5E8D4', 'stroke': '#82B366'},
'ok': {'fill': '#D5E8D4', 'stroke': '#82B366'},
'warning': {'fill': '#FFF2CC', 'stroke': '#D6B656'},
'degraded': {'fill': '#FFF2CC', 'stroke': '#D6B656'},
'critical': {'fill': '#F8CECC', 'stroke': '#B85450'},
'down': {'fill': '#F8CECC', 'stroke': '#B85450'},
'error': {'fill': '#F8CECC', 'stroke': '#B85450'},
'maintenance': {'fill': '#E1D5E7', 'stroke': '#9673A6'},
'unknown': {'fill': '#F5F5F5', 'stroke': '#666666'},
}
def update_style_property(style: str, key: str, value: str) -> str:
"""Update a single property in a draw.io style string."""
pattern = re.compile(rf'{re.escape(key)}=[^;]*')
if pattern.search(style):
style = pattern.sub(f'{key}={value}', style)
else:
if not style.endswith(';'):
style += ';'
style += f'{key}={value};'
return style
def get_threshold_color(value: float, thresholds: list) -> dict:
"""
Determine color based on value thresholds.
thresholds: list of (max_value, colors_dict) sorted ascending.
Example: [(100, green), (500, yellow), (float('inf'), red)]
"""
for threshold, colors in thresholds:
if value <= threshold:
return colors
return thresholds[-1][1] # fallback to last
def decompress_diagram(compressed: str) -> str:
"""Decompress a draw.io compressed diagram XML string."""
decoded = base64.b64decode(compressed)
decompressed = zlib.decompress(decoded, -15)
return urllib.parse.unquote(decompressed.decode('utf-8'))
def compress_diagram(xml_str: str) -> str:
"""Compress diagram XML back to draw.io compressed format."""
encoded = urllib.parse.quote(xml_str, safe='')
compressed = zlib.compress(encoded.encode('utf-8'), 9)
# Strip zlib header (first 2 bytes) and checksum (last 4 bytes)
raw = compressed[2:-4]
return base64.b64encode(raw).decode('utf-8')
def update_diagram(input_path: str, output_path: str, data: dict,
compress: bool = False):
"""Update diagram cells based on service data."""
tree = ET.parse(input_path)
root = tree.getroot()
# Handle both mxfile wrapper and bare mxGraphModel
if root.tag == 'mxfile':
for diagram_elem in root.findall('diagram'):
# Check if diagram content is compressed
text = diagram_elem.text
if text and text.strip():
# Compressed format
xml_str = decompress_diagram(text.strip())
model = ET.fromstring(xml_str)
process_model(model, data)
if compress:
diagram_elem.text = compress_diagram(
ET.tostring(model, encoding='unicode'))
else:
diagram_elem.text = None
diagram_eRelated in General
modeling-omnistudio-epc-catalog
IncludedSalesforce Industries CME EPC product-modeling skill for Product2-based catalog creation. Use when creating EPC products, configuring product attributes, building offer bundles with Product Child Items, or reviewing EPC DataPack JSON metadata for product catalog changes. TRIGGER when: user creates or updates Product2 EPC records, AttributeAssignment payloads, AttributeMetadata/AttributeDefaultValues, Offer bundles, or ProductChildItem relationships. DO NOT TRIGGER when: designing OmniScripts/FlexCards/Integration Procedures (use building-omnistudio-omniscript, building-omnistudio-flexcard, or building-omnistudio-integration-procedure), implementing Apex business logic (use generating-apex), or troubleshooting deployment pipelines (use deploying-metadata).
relationship-science-coach
IncludedUse this skill for direct, practical adult relationship coaching: couples conflict, repair, trust, marriage, dating, flirting, attachment patterns, emotional connection, sex, desire differences, eroticism, kink negotiation, affection, love languages, breakups, and long-term passion. Draw on Gottman, EFT and Hold Me Tight, attachment science, modern sex research, Perel, Nagoski, Kerner, Schnarch, Love and Stosny, and flexible love-language tools. Be concrete and low-hedge. Redirect only for imminent danger, abuse, coercive control, minors, non-consent, self-harm, stalking, or medical/legal/psychiatric decisions.
building-sf-integrations
IncludedSalesforce integration architecture and runtime plumbing with 120-point scoring. Use this skill to set up Named Credentials, External Credentials, External Services, REST/SOAP callout patterns, Platform Events, and Change Data Capture. TRIGGER when: user sets up Named Credentials, External Services, REST/SOAP callouts, Platform Events, CDC, or touches .namedCredential-meta.xml files. DO NOT TRIGGER when: Connected App/OAuth config (use configuring-connected-apps), Apex-only logic (use generating-apex), or data import/export (use handling-sf-data).
venue-templates
IncludedAccess comprehensive LaTeX templates, formatting requirements, and submission guidelines for major scientific publication venues (Nature, Science, PLOS, IEEE, ACM), academic conferences (NeurIPS, ICML, CVPR, CHI), research posters, and grant proposals (NSF, NIH, DOE, DARPA). This skill should be used when preparing manuscripts for journal submission, conference papers, research posters, or grant proposals and need venue-specific formatting requirements and templates.
let-fate-decide
IncludedDraws the 12 Houses of the Zodiac Tarot spread to inject entropy into planning when prompts are vague, ambiguous, or casually delegated. Interprets the spread to guide next steps. Use when the user says 'let fate decide', 'YOLO', 'whatever', 'idk', or other nonchalant phrases, makes Yu-Gi-Oh references, or when you are about to arbitrarily pick between multiple reasonable approaches. Prefer over ask-questions-if-underspecified when the user's tone is casual or playful rather than precision-seeking.
net-ops
IncludedCross-platform network troubleshooting (Windows, macOS, Linux) via local or remote shell. Use for: DNS broken, can't resolve hostnames, nslookup/dig works but apps fail, NRPT, WFP, scutil, /etc/resolver, systemd-resolved, /etc/resolv.conf, NetworkManager, VPN DNS leak residue (ProtonVPN/Mullvad/WireGuard/AnyConnect), AV/firewall blocking DNS or DoH, Tailscale DNS interaction, intermittent connectivity, remote diagnostics over SSH.