from typing import List, Sequence from .charts_layout_types import LegendItem from .math_round_float import round_float # 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