Skip to content

Time Series Chart

TimeSeriesChart draws a line over time, one point per event.

import dachshund
from dachshund.widgets import TimeSeriesChart

with dachshund.row():
    dachshund.add(TimeSeriesChart("latency"))
dachshund.emit("latency", value=96)

dachshund.widgets.chart.timeseries.TimeSeriesChart dataclass

TimeSeriesChart(name, *, source='', title=None, actions=list(), action_args=dict(), x='', y='value', aggregate=None, every=None, over=None)

Bases: LineChart

A line over time: one point per event, or an aggregate per bucket of time.

Example

with dachshund.row():
    dachshund.add(TimeSeriesChart("latency", y=["p50", "p95"]))
    dachshund.add(
        TimeSeriesChart("requests", aggregate="count", every=timedelta(minutes=1))
    )
dachshund.emit("latency", p50=10, p95=40)

Options

  • y (str | list[str]) - The field drawn, or one line per field. Defaults to "value".
  • aggregate (str) - "count", "sum", "average", "min", "max" or "distinct" of each field per bucket. Defaults to None, a point per event. See Aggregating.
  • every (timedelta) - A bucket's length, a whole number of minutes. Whole days start at midnight in the dashboard's timezone. Required with aggregate.
  • over (timedelta | str) - How far back the chart goes: a timedelta, or the current "day", "week" or "month". Defaults to None, the latest 500 buckets.

A point's x is the time its event was emitted, or its bucket's start, so there's no x option.

x class-attribute instance-attribute

x = ''

aggregate class-attribute instance-attribute

aggregate = None

every class-attribute instance-attribute

every = None

over class-attribute instance-attribute

over = None

type class-attribute

type = 'timeseries'

window

window()

aggregate of each line per every, None for a point per event.

Source code in dachshund/widgets/chart/timeseries.py
80
81
82
83
84
85
86
87
88
89
90
def window(self) -> Window | None:
    """`aggregate` of each line per `every`, `None` for a point per event."""
    if self.aggregate is None:
        return None

    return Window(
        fields=self.series,
        aggregate=self.aggregate,
        over=self.over,
        every=self.every,
    )

at

at(event)

When the event happened, as the seconds uPlot expects.

Source code in dachshund/widgets/chart/timeseries.py
92
93
94
def at(self, event: Event) -> float:
    """When the event happened, as the seconds uPlot expects."""
    return event.at.timestamp()

render_buckets

render_buckets(buckets)

One point per bucket, the aggregate of each field.

Source code in dachshund/widgets/chart/timeseries.py
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
def render_buckets(self, buckets: Mapping[str, Sequence[Bucket]]) -> dict[str, Any]:
    """One point per bucket, the aggregate of each field."""
    assert self.aggregate is not None
    starts = [bucket.start for bucket in buckets[self.series[0]]]

    return {
        "series": list(self.series),
        "x": starts,
        "y": [
            [aggregated(bucket, self.aggregate) for bucket in buckets[field]]
            for field in self.series
        ],
    }