Functional Weave
Code in TypeScript

charts.layout@1.0.1

impl/python/legend_rows.py

1,559 bytes · the Python implementation · view raw

Imports name this capability’s declared dependencies, which fune builds next to it in your project; each one links to its page.

from typing import List, Sequence

from .charts_layout_types import LegendItem
from .math_round_float import round_float  ← from math.round-float ^1.0.0 · built alongside by fune

# Space between the swatch and its text.
_SWATCH_PADDING = 4.0


def legend_rows(
    labels: Sequence[str],
    max_width: float,
    char_width: float,
    swatch_size: float,
    gap: float,
    row_height: float,
) -> List[LegendItem]:
    """Legend items left to right, wrapping when the next would pass max_width.

    Text width is estimated as code points times char_width; no font is
    measured, so the answer is the same in every language.
    """
    if not max_width > 0:
        raise ValueError("maxWidth must be greater than zero, received %r" % (max_width,))
    if not (char_width >= 0 and swatch_size >= 0 and gap >= 0 and row_height >= 0):
        raise ValueError("legend sizes must not be negative")
    items: List[LegendItem] = []
    row = 0
    x = 0.0
    on_row = 0
    for label in labels:
        width = float(swatch_size) + _SWATCH_PADDING + len(label) * float(char_width)
        if on_row > 0 and x + width > max_width:
            row += 1
            x = 0.0
            on_row = 0
        items.append(
            LegendItem(
                label=label,
                row=row,
                x=round_float(x, 2),
                y=round_float(row * float(row_height), 2),
                width=round_float(width, 2),
                text_x=round_float(x + float(swatch_size) + _SWATCH_PADDING, 2),
            )
        )
        x = x + width + float(gap)
        on_row += 1
    return items