Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions docs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@

TODO

### New features

- Add `sleeve_color` cable attribute to draw a colored braided sleeve/wrap around a bundle ([#503](https://github.com/wireviz/WireViz/issues/503))


## [0.4.1](https://github.com/wireviz/WireViz/tree/v0.4.1) (2024-07-13)

Expand Down
3 changes: 3 additions & 0 deletions docs/syntax.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,9 @@ tweak: # optional tweaking of .gv output
# using a color (see below) will render the shield in that color
# A shield can be accessed by using 's' as the wire ID
color: <color> # see below
sleeve_color: <color> # defaults to none; see below
# draws a colored braided sleeve/wrap around the bundle
# and shows a "+ Sleeve" indicator with the color name
image: <image> # see below
notes: <str>

Expand Down
10 changes: 7 additions & 3 deletions src/wireviz/wv_dataclasses.py
Original file line number Diff line number Diff line change
Expand Up @@ -510,7 +510,7 @@ def gauge_str(self):
if not self.gauge:
return None
actual_gauge = f"{self.gauge.number} {self.gauge.unit}"
actual_gauge = actual_gauge.replace("mm2", "mm\u00B2")
actual_gauge = actual_gauge.replace("mm2", "mm\u00b2")
return actual_gauge

@property
Expand Down Expand Up @@ -547,6 +547,9 @@ class Cable(TopLevelGraphicalComponent):
# wire information in particular
wirecount: Optional[int] = None
shield: Union[bool, MultiColor] = False
sleeve_color: Optional[SingleColor] = (
None # outer wrap/sleeve drawn around the bundle
)
colors: List[str] = field(default_factory=list) # legacy
wirelabels: List[Wire] = field(default_factory=list) # legacy
wire_objects: Dict[Any, WireClass] = field(default_factory=dict) # new
Expand All @@ -571,7 +574,7 @@ def gauge_str(self):
if not self.gauge:
return None
actual_gauge = f"{self.gauge.number} {self.gauge.unit}"
actual_gauge = actual_gauge.replace("mm2", "mm\u00B2")
actual_gauge = actual_gauge.replace("mm2", "mm\u00b2")
return actual_gauge

@property
Expand All @@ -587,7 +590,7 @@ def gauge_str_with_equiv(self):
elif self.gauge.unit.upper() == "AWG":
equivalent_gauge = f" ({mm2_equiv(self.gauge.number)} mm2)"
out = f"{actual_gauge}{equivalent_gauge}"
out = out.replace("mm2", "mm\u00B2")
out = out.replace("mm2", "mm\u00b2")
return out

@property
Expand Down Expand Up @@ -647,6 +650,7 @@ def __post_init__(self) -> None:

self.bgcolor_title = SingleColor(self.bgcolor_title)
self.color = MultiColor(self.color)
self.sleeve_color = SingleColor(self.sleeve_color)

# cables do not support custom qty or amount
if self.qty is None:
Expand Down
46 changes: 45 additions & 1 deletion src/wireviz/wv_graphviz.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ def gv_node_component(component: Component) -> Table:
"+ S" if component.shield else None,
component.length_str,
str(component.color) if component.color else None,
"+ Sleeve" if component.sleeve_color else None,
str(component.sleeve_color) if component.sleeve_color else None,
]

if component.additional_parameters:
Expand Down Expand Up @@ -301,9 +303,47 @@ def gv_connector_loops(connector: Connector) -> List:
return loop_edges


def gv_sleeve_braid_band(
hex_main: str, ncells: int = 26, cw: int = 9, ch: int = 5
) -> Table:
"""Return a Table that fakes a braided-sleeve band.

Two offset rows of alternating cells (the sleeve color and a darker shade)
read as an interlaced basket weave -- the closest braid approximation that
GraphViz HTML labels allow without diagonal hatching or image tiling.
"""
try:
h = hex_main.lstrip("#")
r, g, b = int(h[0:2], 16), int(h[2:4], 16), int(h[4:6], 16)
f = 0.55 # darken factor for the interlacing strands
hex_alt = f"#{int(r * f):02x}{int(g * f):02x}{int(b * f):02x}"
except (ValueError, IndexError):
hex_alt = hex_main # non-hex color name: fall back to a single tone
band_rows = []
for row in range(2):
cells = [
Td(
"",
bgcolor=(hex_main if (c + row) % 2 == 0 else hex_alt),
width=cw,
height=ch,
border=0,
)
for c in range(ncells)
]
band_rows.append(Tr(cells))
return Table(band_rows, border=0, cellborder=0, cellspacing=0, cellpadding=0)


def gv_conductor_table(cable) -> Table:
rows = []
# a colored sleeve is drawn as a woven braid band across the top and bottom
# of the conductor bundle, with thin colored side rails around the table
sleeve_hex = cable.sleeve_color.html if cable.sleeve_color else None
sleeve_colspan = 6 if cable.category == "bundle" else 5
rows.append(Tr(Td("&nbsp;"))) # spacer row on top
if sleeve_hex:
rows.append(Tr(Td(gv_sleeve_braid_band(sleeve_hex), colspan=sleeve_colspan)))

inserted_break_inbetween = False
for wire in cable.wire_objects.values():
Expand Down Expand Up @@ -358,7 +398,11 @@ def gv_conductor_table(cable) -> Table:
rows.append(Tr(Td(table_below, colspan=len(cells_above))))

rows.append(Tr(Td("&nbsp;"))) # spacer row on bottom
tbl = Table(rows, border=0, cellborder=0, cellspacing=0)
if sleeve_hex:
rows.append(Tr(Td(gv_sleeve_braid_band(sleeve_hex), colspan=sleeve_colspan)))
tbl = Table(rows, border=2, color=sleeve_hex, cellborder=0, cellspacing=0)
else:
tbl = Table(rows, border=0, cellborder=0, cellspacing=0)
return tbl


Expand Down
7 changes: 7 additions & 0 deletions tutorial/tutorial09.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
## Cable sleeves

* Cable sleeve / wrap
* `sleeve_color` draws a colored braided sleeve around the bundle
* Rendered as a woven band across the top and bottom of the conductors
* Adds a `+ Sleeve` indicator with the color name to the cable header
* Works for bundles and sheathed cables, and composes with `shield`
23 changes: 23 additions & 0 deletions tutorial/tutorial09.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
connectors:
X1:
pinlabels: [GND, GND, +24V, +24V]
type: Molex Mini-Fit Jr
subtype: female
X2:
pinlabels: [GND, GND, +24V, +24V]
type: Molex Mini-Fit Jr
subtype: female

cables:
W1:
category: bundle
gauge: 18 AWG
length: 0.8
colors: [BK, BK, RD, RD]
sleeve_color: RD # draw a red braided sleeve around the bundle

connections:
-
- X1: [1-4]
- W1: [1-4]
- X2: [1-4]