Pages & Layout
Without a Page
The smallest dashboard puts widgets straight on it. They land on the default page, "Overview" in the navigation.
import dachshund
from dachshund.widgets import Number, TimeSeriesChart
dachshund.init("My service")
with dachshund.row():
dachshund.add(Number("users"))
dachshund.add(TimeSeriesChart("latency"))
Layout
Widgets live in rows, laid out with with blocks, so the indentation is the layout. add() puts a widget in the innermost open block.
add() inside |
the widget goes |
|---|---|
a column() |
in that column, under the widgets already there |
a row() |
in a column of its own, side by side with the others |
| neither | nowhere: it raises ValueError |
with dachshund.row():
dachshund.add(Text("summary"))
with dachshund.row():
dachshund.add(TimeSeriesChart("latency"))
with dachshund.column(span=4):
dachshund.add(Number("errors"))
dachshund.add(Number("users"))
┌───────────────────────────────┐
│ summary │
├────────────────────┬──────────┤
│ │ errors │
│ latency ├──────────┤
│ │ users │
└────────────────────┴──────────┘
- Every row is a 12-column grid. A column's
spanis its width out of 12: 6 is half, 4 a third, 3 a quarter. - Columns without a span share what's left evenly, so
latencyabove takes 8. - A full-width widget is a row with one widget, like
summary. - Columns line up from one row to the next, since every row uses the same 12 columns.
- Rows show in the order they were opened. On a narrow screen, every column takes the full width.
- Loops work inside blocks:
with dachshund.row():
for name in ("cpu", "memory", "disk"):
dachshund.add(Number(name)) # 4 + 4 + 4
To keep a reference to a widget, build it first, then place it:
sessions = Table("sessions", columns=["user"], key="user")
with dachshund.row():
dachshund.add(sessions)
Pages
A Page groups widgets under its own URL and entry in the navigation. It's laid out the same way, through its own row(), column() and add(), then put on the dashboard with include().
import dachshund
from dachshund import Page
from dachshund.widgets import Number, Text, TimeSeriesChart
overview_page = Page("overview", title="Overview")
with overview_page.row():
overview_page.add(Text("summary"))
with overview_page.row():
overview_page.add(TimeSeriesChart("latency"))
with overview_page.column(span=4):
overview_page.add(Number("errors"))
overview_page.add(Number("users"))
dachshund.include(overview_page)
Pages show in the navigation in the order they're included. Widget and action names are unique across the dashboard, and include() adds nothing if one is already taken.
Tabs
A page holds either widgets or tabs. Each tab is a page of its own, at /<page>/<tab>, listed in a sidebar. Visiting the page shows its first tab.
from dachshund import Page
from dachshund.widgets import BarChart
activity_page = Page("activity", title="Activity")
with activity_page.tab("commands", title="Commands"):
with activity_page.row():
activity_page.add(BarChart("commands", x="name"))
with activity_page.tab("errors", title="Errors"):
with activity_page.row():
activity_page.add(BarChart("errors_per_command", x="name"))
As a dashboard grows, see Bigger Dashboard for how to split it across modules.