from typing import List, Sequence from .charts_shape_types import BarSpec, Orientation, Rect from .math_round_float import round_float def bar_rects(bars: Sequence[BarSpec], orientation: Orientation) -> List[Rect]: """Rectangles for bars. Edges are rounded to 2 places and sizes are the differences of the rounded edges, so bars that share an edge share it exactly, and a negative bar's height is still positive.""" if orientation not in ("vertical", "horizontal"): raise ValueError("orientation must be vertical or horizontal, received %r" % (orientation,)) out: List[Rect] = [] for bar in bars: if not bar.thickness >= 0: raise ValueError("bar thickness must not be negative, received %r" % (bar.thickness,)) band = float(bar.band) a0 = round_float(band, 2) a1 = round_float(band + float(bar.thickness), 2) v0 = round_float(min(float(bar.base), float(bar.value)), 2) v1 = round_float(max(float(bar.base), float(bar.value)), 2) across = round_float(a1 - a0, 2) along = round_float(v1 - v0, 2) if orientation == "vertical": out.append(Rect(x=a0, y=v0, width=across, height=along)) else: out.append(Rect(x=v0, y=a0, width=along, height=across)) return out