Skip to content

SVG Renderer

SVG rendering engine for converting diagrams to SVG files.

render_svg

SVG rendering for GPIO diagrams.

SVGRenderer

SVGRenderer(layout_config: LayoutConfig | None = None)

Render GPIO wiring diagrams to SVG format.

Converts a Diagram object into a scalable SVG image showing the Raspberry Pi board, connected devices, wire connections, and optional GPIO reference diagram.

The renderer handles
  • Board SVG asset embedding
  • Device box rendering with labeled pins
  • Wire routing with rounded corners
  • Inline component symbols (resistors, capacitors, diodes)
  • GPIO pin numbering and color coding
  • Optional GPIO reference diagram
  • Automatic layout via LayoutEngine

Examples:

>>> from pinviz import boards, devices, Connection, Diagram, SVGRenderer
>>>
>>> diagram = Diagram(
...     title="LED Circuit",
...     board=boards.raspberry_pi_5(),
...     devices=[devices.led()],
...     connections=[
...         Connection(11, "LED", "Anode"),
...         Connection(6, "LED", "Cathode")
...     ]
... )
>>>
>>> renderer = SVGRenderer()
>>> renderer.render(diagram, "led_circuit.svg")

Initialize SVG renderer with optional layout configuration.

PARAMETER DESCRIPTION
layout_config

Layout configuration for spacing and margins. If None, uses default LayoutConfig.

TYPE: LayoutConfig | None DEFAULT: None

Source code in src/pinviz/render_svg.py
def __init__(self, layout_config: LayoutConfig | None = None):
    """
    Initialize SVG renderer with optional layout configuration.

    Args:
        layout_config: Layout configuration for spacing and margins.
            If None, uses default LayoutConfig.
    """
    self.layout_config = layout_config or LayoutConfig()
    self.layout_engine = LayoutEngine(self.layout_config)
    self._init_svg_handlers()

render

render(diagram: Diagram, output_path: str | Path) -> None

Render a diagram to an SVG file.

PARAMETER DESCRIPTION
diagram

The diagram to render

TYPE: Diagram

output_path

Output file path

TYPE: str | Path

Source code in src/pinviz/render_svg.py
def render(self, diagram: Diagram, output_path: str | Path) -> None:
    """
    Render a diagram to an SVG file.

    Args:
        diagram: The diagram to render
        output_path: Output file path
    """
    # Calculate layout
    canvas_width, canvas_height, routed_wires = self.layout_engine.layout_diagram(diagram)

    # Create SVG drawing
    dwg = svgwrite.Drawing(str(output_path), size=(f"{canvas_width}px", f"{canvas_height}px"))

    # Add white background
    dwg.add(dwg.rect(insert=(0, 0), size=(canvas_width, canvas_height), fill="white"))

    # Draw title
    if diagram.title:
        dwg.add(
            dwg.text(
                diagram.title,
                insert=(canvas_width / 2, 25),
                text_anchor="middle",
                font_size="20px",
                font_family="Arial, sans-serif",
                font_weight="bold",
                fill="#333",
            )
        )

    # Draw board
    self._draw_board(dwg, diagram.board)

    # Draw wires first so they appear behind devices
    # Sort wires for proper z-order to prevent overlapping/hiding
    # Primary: source pin X position (left column pins first, right column on top)
    # Secondary: destination Y (lower devices first)
    # Tertiary: rail X position (further right first)
    # This ensures wires from right GPIO column are always on top
    sorted_wires = sorted(
        routed_wires,
        key=lambda w: (
            w.from_pin_pos.x,  # Left column first, right column on top
            -w.to_pin_pos.y,  # Lower Y (higher devices) drawn last
            -(w.path_points[2].x if len(w.path_points) > 2 else w.path_points[0].x),
        ),
    )
    for wire in sorted_wires:
        self._draw_wire(dwg, wire)

    # Draw devices on top of wires
    for device in diagram.devices:
        self._draw_device(dwg, device)

    # Draw GPIO pin diagram on the right if enabled
    if diagram.show_gpio_diagram:
        self._draw_gpio_diagram(dwg, canvas_width)

    # Legend removed per user request - cleaner diagram

    # Save
    dwg.save()

render_to_string

render_to_string(diagram: Diagram) -> str

Render a diagram to an SVG string.

PARAMETER DESCRIPTION
diagram

The diagram to render

TYPE: Diagram

RETURNS DESCRIPTION
str

SVG content as string

Source code in src/pinviz/render_svg.py
def render_to_string(self, diagram: Diagram) -> str:
    """
    Render a diagram to an SVG string.

    Args:
        diagram: The diagram to render

    Returns:
        SVG content as string
    """
    import tempfile

    with tempfile.NamedTemporaryFile(mode="w", suffix=".svg", delete=False) as f:
        temp_path = f.name

    try:
        self.render(diagram, temp_path)
        with open(temp_path) as f:
            return f.read()
    finally:
        Path(temp_path).unlink(missing_ok=True)