Learn · 08 of 09

Charts and dashboards.

TerminalUICharts is a separate product for dense operational surfaces. It is intentionally compact: charts are meant to sit next to controls, logs, tables, and status text inside a TUI, not to become a full charting framework.

Add the product to your executable target, import it next to TerminalUI, and compose charts like ordinary views.

A compact operations dashboard.

The dashboard combines current-value meters, a sparkline, a threshold gauge, a bar chart, a timeline, and a legend. Every chart uses semantic tones so host themes can decide the final colors.

OpsDashboard.swift swift
import TerminalUI
import TerminalUICLI
import TerminalUICharts

@main
struct OpsDashboardApp: App {
  var body: some Scene {
    WindowGroup("Ops") {
      OpsDashboard()
    }
  }
}

struct OpsDashboard: View {
  let latency = [42, 38, 45, 51, 47, 44, 49, 53, 46, 43].map(Double.init)

  var body: some View {
    VStack(alignment: .leading, spacing: 1) {
      Text("Production").bold()

      HStack(alignment: .top, spacing: 2) {
        VStack(alignment: .leading, spacing: 1) {
          Meter("CPU", value: 73, total: 100, tone: .warning, barWidth: 16)
          Sparkline("Latency", values: latency, tone: .info)
          ThresholdGauge(
            "SLO",
            value: 99.92,
            total: 100,
            bands: [
              ThresholdBand(upTo: 99.0, tone: .critical),
              ThresholdBand(upTo: 99.9, tone: .warning),
              ThresholdBand(upTo: 100, tone: .success),
            ],
            barWidth: 16
          )
        }

        BarChart(
          "Queue",
          entries: [
            BarChartEntry("ingest", value: 82, tone: .warning),
            BarChartEntry("index", value: 38, tone: .success),
            BarChartEntry("email", value: 12, tone: .info),
          ],
          barWidth: 14,
          labelWidth: 7
        )
      }

      Divider()

      Timeline([
        TimelineEntry("deploy started", detail: "api@1.4.0", tone: .info),
        TimelineEntry("canary healthy", detail: "10% traffic", tone: .success),
        TimelineEntry("queue elevated", detail: "watch ingest", tone: .warning),
      ])

      Legend(
        "Legend",
        items: [
          LegendItem("healthy", tone: .success),
          LegendItem("watch", tone: .warning),
          LegendItem("info", tone: .info),
        ]
      )
    }
    .padding(.init(horizontal: 1, vertical: 0))
  }
}

Choose by job

  • Meter and ProgressView: one current value against a total.
  • ThresholdGauge and BulletChart: status changes at explicit boundaries.
  • Sparkline, Timeline, and HeatStrip: trend and sequence summaries.
  • BarChart, ColumnChart, ComparisonChart, and StackedBarChart: comparing labeled values.
  • Legend: explains tone and series labels when the surrounding view needs it.

Tone, not hard-coded color

Charts use BannerTone values such as .success, .warning, .critical, and .info. That keeps chart intent separate from the active theme. The terminal host, browser host, or embedded GUI host resolves those tones into final display styles.

Dashboard layout

Keep chart widths explicit. Terminal dashboards are scanned in a fixed cell grid, so the best dashboards reserve stable columns and let charts stay compact. Use HStack, VStack, Table, and custom layouts to organize the surface.

Where to go next