Imports name this capability’s declared dependencies, which fune builds next to it in your project; each one links to its page.
import math
from typing import Optional, Sequence
from .charts_extent import extent ← from charts.extent ^1.0.0 · built alongside by fune
from .charts_scale_linear_scale import linear_scale
from .charts_shape_line_path import line_path
from .charts_shape_types import Point
from .charts_sparkline_types import SparkPoint, Sparkline
from .math_round_float import round_float ← from math.round-float ^1.0.0 · built alongside by fune
def _check_size(value: float, what: str) -> None:
if isinstance(value, bool) or not isinstance(value, (int, float)) or not math.isfinite(value) or value < 0:
raise ValueError("%s must be a finite number of zero or more, received %r" % (what, value))
def sparkline(values: Sequence[Optional[float]], width: float, height: float, padding: float) -> Sparkline:
"""A sparkline in a box; see the README for flat and single-value series."""
_check_size(width, "width")
_check_size(height, "height")
_check_size(padding, "padding")
if width - 2 * padding <= 0 or height - 2 * padding <= 0:
raise ValueError(
"the box is too small for its padding: %r by %r with %r on each side" % (width, height, padding)
)
rng = extent(values)
if rng is None:
return Sparkline(path="", end=None)
lo, hi = rng
n = len(values)
points = []
for i, v in enumerate(values):
x = width - padding if n == 1 else linear_scale([0, n - 1], [padding, width - padding], i, False)
if v is None:
points.append(Point(x=x, y=None))
continue
y = height / 2 if lo == hi else linear_scale([lo, hi], [height - padding, padding], v, False)
points.append(Point(x=x, y=y))
end = None
for p in points:
if p.y is not None:
end = SparkPoint(x=round_float(p.x, 2), y=round_float(p.y, 2))
return Sparkline(path=line_path(points), end=end)