Fix vertical component labels using perpendicular SchemDraw loc values

SchemDraw's loc="left"/"right" on vertical elements places labels at the
element start/end (along the axis), not perpendicular to the body. Use
loc="top" for geometric-left and loc="bottom" for geometric-right to
position labels beside the component body instead of above/below it.

Affects _draw_vert_chain, _render_loop, and _draw_horiz_then_down.
This commit is contained in:
Ryan Malloy 2026-02-24 09:02:23 -07:00
parent 1b8126cbb8
commit b238c38bfa

View File

@ -652,20 +652,20 @@ def _render_loop(parsed: ParsedNetlist, loop: list[SpiceComponent]) -> str:
path_comps = loop[1:]
if not path_comps:
# Standalone source
# Standalone source — loc="top" places label to geometric left of vertical element
d.add(
_get_element(source, parsed.models)
.up()
.label(_component_label(source), loc="left", ofst=_LABEL_OFST)
.label(_component_label(source), loc="top", ofst=_LABEL_OFST)
)
d.add(elm.Ground())
return d.get_imagedata("svg").decode()
# Source on left side, going up
# Source on left side, going up — loc="top" for geometric left
src = d.add(
_get_element(source, parsed.models)
.up()
.label(_component_label(source), loc="left", ofst=_LABEL_OFST)
.label(_component_label(source), loc="top", ofst=_LABEL_OFST)
)
# All components except the last go right across the top
@ -676,13 +676,13 @@ def _render_loop(parsed: ParsedNetlist, loop: list[SpiceComponent]) -> str:
.label(_component_label(comp), ofst=_LABEL_OFST)
)
# Last component goes down, ending at the same y-level as the source start
# Last component goes down — loc="bottom" for geometric right of vertical element
last_comp = path_comps[-1]
d.add(
_get_element(last_comp, parsed.models)
.down()
.toy(src.start)
.label(_component_label(last_comp), loc="right", ofst=_LABEL_OFST)
.label(_component_label(last_comp), loc="bottom", ofst=_LABEL_OFST)
)
# Return wire along the bottom back to source start
@ -1186,22 +1186,23 @@ def _draw_vert_chain(
label_loc controls which side labels appear on ("left" or "right").
Classic drafting rule: labels face outward from the circuit center.
SchemDraw note: for vertical elements, loc="left"/"right" place labels
at the element start/end (along the axis), not perpendicular to the body.
Use loc="top" for geometric-left and loc="bottom" for geometric-right.
"""
import schemdraw.elements as elm
direction = "up" if going_up else "down"
# Labels push away from terminators: going down → labels above midpoint,
# going up → labels below midpoint (default).
label_valign = "bottom" if not going_up else None
# Map logical left/right to perpendicular label positions for vertical elements
_vert_loc = {"left": "top", "right": "bottom"}
actual_loc = _vert_loc.get(label_loc, label_loc)
for i, comp in enumerate(components):
elem = _get_element(comp, parsed.models)
if i == 0 and start is not None:
elem = elem.at(start)
elem = getattr(elem, direction)().length(_VERT_CHAIN_MIN_LEN)
label_kw: dict = dict(loc=label_loc, ofst=_LABEL_OFST)
if label_valign:
label_kw["valign"] = label_valign
elem = elem.label(_component_label(comp), **label_kw)
elem = elem.label(_component_label(comp), loc=actual_loc, ofst=_LABEL_OFST)
d.add(elem)
# Short gap wire before terminators so ground/Vdd symbols don't
@ -1232,10 +1233,11 @@ def _draw_horiz_then_down(d, parsed, start, path, going_right):
is_last = i == len(comps) - 1
if is_last and len(comps) > 1:
# Turn downward at the bend — label faces outward
# For vertical .down() elements: "bottom" = geometric right, "top" = geometric left
d.push()
down_label = "right" if going_right else "left"
down_loc = "bottom" if going_right else "top"
d.add(elem.down().label(
_component_label(comp), loc=down_label, ofst=_LABEL_OFST, valign="center",
_component_label(comp), loc=down_loc, ofst=_LABEL_OFST,
))
if path.end_type == "ground":
d.add(elm.Ground())