From aafcff62b0d65a5ce290d7cb3768ec8a77c8538f Mon Sep 17 00:00:00 2001 From: Ryan Malloy Date: Mon, 2 Mar 2026 02:10:57 -0700 Subject: [PATCH] Use component-aware sizing for schematic element lengths Inductors, capacitors, and diodes use compact length (3.0) while resistors keep full length (4.0) for readable color-coded bands. Reduces vertical stretch in inductor-heavy circuits like Hartley. --- backend/src/spicebook/engine/schematic.py | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/backend/src/spicebook/engine/schematic.py b/backend/src/spicebook/engine/schematic.py index 7a4a0f7..690aac0 100644 --- a/backend/src/spicebook/engine/schematic.py +++ b/backend/src/spicebook/engine/schematic.py @@ -80,7 +80,8 @@ _DEVICE_LABEL_OFST = 0.6 # active device body label offset (clear junction wi _PARALLEL_PATH_SPACING = 4.0 # between parallel vertical paths (was 2.5) _LEAD_STUB_LENGTH = 2.0 # clearance from transistor pin to first component _INPUT_JUNCTION_LENGTH = 1.5 # base/gate junction wire (was 1.0) -_VERT_CHAIN_MIN_LEN = 4.0 # minimum component length in vertical chains +_VERT_CHAIN_LEN = 4.0 # default component length in vertical chains +_VERT_CHAIN_LEN_COMPACT = 3.0 # compact length for inductors, capacitors, diodes def _is_ground(node: str) -> bool: @@ -1175,6 +1176,18 @@ def _choose_label_side(path_index: int, is_left_of_device: bool) -> str: return opposite +def _chain_length(comp: SpiceComponent) -> float: + """Return drawing length for a component in vertical/horizontal chains. + + Color-coded resistors need full length for readable band spacing. + Inductors, capacitors, and diodes use compact length — their symbols + are inherently recognizable at smaller sizes. + """ + if comp.prefix in ("L", "C", "D"): + return _VERT_CHAIN_LEN_COMPACT + return _VERT_CHAIN_LEN + + def _sort_parallel_paths(paths: list[TerminalPath]) -> list[TerminalPath]: """Sort parallel paths: longest chains closest to device (index 0). @@ -1209,7 +1222,7 @@ def _draw_vert_chain( 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) + elem = getattr(elem, direction)().length(_chain_length(comp)) elem = elem.label(_component_label(comp), loc=actual_loc, ofst=_LABEL_OFST) d.add(elem) @@ -1244,7 +1257,7 @@ def _draw_horiz_then_down(d, parsed, start, path, going_right): # For vertical .down() elements: "bottom" = geometric right, "top" = geometric left d.push() down_loc = "bottom" if going_right else "top" - d.add(elem.down().label( + d.add(elem.down().length(_chain_length(comp)).label( _component_label(comp), loc=down_loc, ofst=_LABEL_OFST, )) if path.end_type == "ground":