From b238c38bfae0cb9b60a50d6033298624799516f7 Mon Sep 17 00:00:00 2001 From: Ryan Malloy Date: Tue, 24 Feb 2026 09:02:23 -0700 Subject: [PATCH] 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. --- backend/src/spicebook/engine/schematic.py | 32 ++++++++++++----------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/backend/src/spicebook/engine/schematic.py b/backend/src/spicebook/engine/schematic.py index 8879c1a..b72caee 100644 --- a/backend/src/spicebook/engine/schematic.py +++ b/backend/src/spicebook/engine/schematic.py @@ -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())