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, Tuple
from .charts_shape_types import Point
from .text_format_decimal import format_decimal ← from text.format-decimal ^1.0.0 · built alongside by fune
def line_path(points: Sequence[Point]) -> str:
"""A polyline as SVG path data, in d3.line's format ("M10,20L30,40").
A null y ends the current subpath; a run of one point is "Mx,yZ", as d3
closes it so a round line cap still shows a dot.
"""
out = ""
for run in point_runs(points):
for i, (x, y) in enumerate(run):
out += ("M" if i == 0 else "L") + svg_pair(x, y)
if len(run) == 1:
out += "Z"
return out
# Shared with the other path functions of this group.
def svg_pair(x: float, y: float) -> str:
""""x,y" with each number rounded to 2 places, trailing zeros dropped."""
return format_decimal(x, 2, True, "") + "," + format_decimal(y, 2, True, "")
def point_runs(points: Sequence[Point]) -> List[List[Tuple[float, float]]]:
"""The unbroken runs of a series: a point with a null y separates them."""
runs: List[List[Tuple[float, float]]] = []
current: List[Tuple[float, float]] = []
for p in points:
if p.y is None:
if current:
runs.append(current)
current = []
else:
# float() so integer inputs take the same binary64 path as the
# other languages.
current.append((float(p.x), float(p.y)))
if current:
runs.append(current)
return runs