Source code for persunraveltorch.draw.viewbox

from typing import Any, Protocol, Tuple
from dataclasses import dataclass
from collections.abc import Sequence
from enum import StrEnum, auto

from .strip_orientation import StripOrientation


__all__ = [ 'Viewbox',
            'VerticalOrientation',
            'ViewboxCreator',
            'ViewboxWithPadding'
           ]


[docs] class VerticalOrientation(StrEnum): UP = auto() DOWN = auto()
[docs] @dataclass(frozen=True, slots=True, kw_only=True) class Viewbox: """Dataclass for attributes specifying a viewbox.""" vertical_orientation: VerticalOrientation """:class:`VerticalOrientation`: Orientation of the y axis.""" top: float right: float bottom: float left: float def __str__(self): or_down = self.vertical_orientation == VerticalOrientation.DOWN return ( f"{self.left} {self.top if or_down else -self.top} " f"{self.right - self.left} {abs(self.top - self.bottom)}" )
[docs] class ViewboxCreator(Protocol): """Callable for creating a :class:`Viewbox` from parameters."""
[docs] def __call__(self, *, range_intervals: Tuple[float, float], strip_orientation: StripOrientation, unravelled_intervals: Sequence, **kwargs: Any ) -> Viewbox: """Creates a :class:`Viewbox` from parameters. Parameters ---------- range_intervals : :class:`Tuple[float, float]` The finite range containing all persistence intervals. strip_orientation : :class:`StripOrientation` The orientation of the strip to be drawn. unravelled_intervals : :class:`Sequence` The unravelled persistence intervals as a sequence by degree. **kwargs : :class:`Any` Any descendent of :class:`ViewboxCreator` needs this so the protocol can be extended in the future. Returns ------- :class:`Viewbox` """ ...
def _maybe_flip_x(strip_orientation: StripOrientation, left: float, right: float ) -> Tuple[float, float]: match strip_orientation: case StripOrientation.ORDINARY: return (left, right) case StripOrientation.CROSS: return (-right, -left)
[docs] @dataclass(kw_only=True, slots=True) class ViewboxWithPadding(ViewboxCreator): """Creates a :class:`Viewbox` based on highest degree with padding.""" padding: float """:class:`float`: The amount of padding to be added in local coordinates. """
[docs] def __call__(self, *, range_intervals: Tuple[float, float], strip_orientation: StripOrientation, unravelled_intervals: Sequence, **kwargs: Any ) -> Viewbox: min, max = range_intervals strip_width = max - min padding = self.padding * strip_width left, right = _maybe_flip_x( strip_orientation = strip_orientation, left = min - ( len(unravelled_intervals) // 2 ) * strip_width, right = max ) return Viewbox( vertical_orientation = VerticalOrientation.UP, top = max + padding, right = right + padding, bottom = ( max - ( (len(unravelled_intervals) + 1) // 2 ) * strip_width - padding ), left = left - padding, )