ai-station/.venv/lib/python3.12/site-packages/textual/widgets/_sparkline.py

109 lines
3.8 KiB
Python

from __future__ import annotations
from typing import Callable, ClassVar, Optional, Sequence
from textual.app import RenderResult
from textual.color import Color
from textual.reactive import reactive
from textual.renderables.sparkline import Sparkline as SparklineRenderable
from textual.widget import Widget
def _max_factory() -> Callable[[Sequence[float]], float]:
"""Callable that returns the built-in max to initialise a reactive."""
return max
class Sparkline(Widget):
"""A sparkline widget to display numerical data."""
COMPONENT_CLASSES: ClassVar[set[str]] = {
"sparkline--max-color",
"sparkline--min-color",
}
"""
Use these component classes to define the two colors that the sparkline
interpolates to represent its numerical data.
Note:
These two component classes are used exclusively for the _color_ of the
sparkline widget. Setting any style other than [`color`](/styles/color.md)
will have no effect.
| Class | Description |
| :- | :- |
| `sparkline--max-color` | The color used for the larger values in the data. |
| `sparkline--min-color` | The color used for the smaller values in the data. |
"""
DEFAULT_CSS = """
Sparkline {
height: 1;
}
Sparkline > .sparkline--max-color {
color: $primary;
}
Sparkline > .sparkline--min-color {
color: $primary 30%;
}
"""
data = reactive[Optional[Sequence[float]]](None)
"""The data that populates the sparkline."""
summary_function = reactive[Callable[[Sequence[float]], float]](_max_factory)
"""The function that computes the value that represents each bar."""
def __init__(
self,
data: Sequence[float] | None = None,
*,
min_color: Color | str | None = None,
max_color: Color | str | None = None,
summary_function: Callable[[Sequence[float]], float] | None = None,
name: str | None = None,
id: str | None = None,
classes: str | None = None,
disabled: bool = False,
) -> None:
"""Initialize a sparkline widget.
Args:
data: The initial data to populate the sparkline with.
min_color: The color of the minimum value, or `None` to take from CSS.
max_color: the color of the maximum value, or `None` to take from CSS.
summary_function: Summarizes bar values into a single value used to
represent each bar.
name: The name of the widget.
id: The ID of the widget in the DOM.
classes: The CSS classes for the widget.
disabled: Whether the widget is disabled or not.
"""
super().__init__(name=name, id=id, classes=classes, disabled=disabled)
self.min_color = None if min_color is None else Color.parse(min_color)
self.max_color = None if max_color is None else Color.parse(max_color)
self.data = data
if summary_function is not None:
self.summary_function = summary_function
def render(self) -> RenderResult:
"""Renders the sparkline when there is data available."""
data = self.data or []
_, base = self.background_colors
min_color = base + (
self.get_component_styles("sparkline--min-color").color
if self.min_color is None
else self.min_color
)
max_color = base + (
self.get_component_styles("sparkline--max-color").color
if self.max_color is None
else self.max_color
)
return SparklineRenderable(
data,
width=self.size.width,
min_color=min_color.rich_color,
max_color=max_color.rich_color,
summary_function=self.summary_function,
)