Functional Weave
Code in Python

charts.shape@1.0.0

impl/python/pie_angles.py

1,288 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_shape_types import PieSlice
from .math_round_float import round_float  ← from math.round-float ^1.0.0 · built alongside by fune

TAU = 6.283185307179586


def pie_angles(values: Sequence[float], start_angle: float, end_angle: float, pad_angle: float) -> List[PieSlice]:
    """Start and end angles of pie slices in input order: d3.pie with
    sort(null), then half the pad trimmed from each side, so the angles go
    straight into arc_path and neighbouring slices show a gap of pad_angle."""
    if not pad_angle >= 0:
        raise ValueError("padAngle must not be negative, received %r" % (pad_angle,))
    n = len(values)
    total = 0.0
    for v in values:
        if not v >= 0:
            raise ValueError("pie values must be zero or more, received %r" % (v,))
        total += float(v)
    a0 = float(start_angle)
    da = min(TAU, max(-TAU, float(end_angle) - a0))
    p = min(abs(da) / n, float(pad_angle)) if n > 0 else 0.0
    pa = p * (-1.0 if da < 0 else 1.0)
    k = (da - n * pa) / total if total > 0 else 0.0
    out: List[PieSlice] = []
    for v in values:
        v = float(v)
        a1 = a0 + (v * k if v > 0 else 0.0) + pa
        out.append(PieSlice(value=v, start_angle=round_float(a0 + pa / 2, 6), end_angle=round_float(a1 - pa / 2, 6)))
        a0 = a1
    return out