Skip to content

feat(dashboards): OTL-90 — consistent legend width + latest/peak/total calcs - #190

Open
ryanrozich wants to merge 1 commit into
mainfrom
otl-90-legend-format
Open

feat(dashboards): OTL-90 — consistent legend width + latest/peak/total calcs#190
ryanrozich wants to merge 1 commit into
mainfrom
otl-90-legend-format

Conversation

@ryanrozich

Copy link
Copy Markdown
Collaborator

Summary

  • Every time-series panel's right-side legend now uses the same width (280px, up
    from a mix of 240px/200px/none) so values line up column-aligned across panels.
  • Legend calcs normalized to a consistent convention across all three dashboards:
    • Additive per-interval quantities (spend, tokens, tool calls, PRs, commits,
      worker events): exactly three calcs — lastNotNull / max / sum, Grafana's
      built-in labels "Last *" / "Max" / "Total" (the closest available equivalent
      to latest/peak/total — see note below).
    • Monotonic/cumulative accumulator panels (the ai:*_accum:sum family) and
      rate/percentage/duration/concurrency-gauge panels: only lastNotNull /
      max (latest/peak) — no forced "total". Summing a running total double-counts
      (the exact bug OTL-82 fixed); summing a %, ms, or concurrent-session series
      across time buckets is not a meaningful number.
    • Two narrow repeated tiles (gridPos.w=8: the per-model Latency tile and
      operator-usage's "Prompts over time") keep bottom placement — a 280px
      right legend would crowd out the chart at that width.
  • Applied to all three dashboards that share the pattern: unified-dashboard.json
    (Claude Code — 29/29 time-series panels touched, recursed into all 5 collapsed
    rows), codex-usage.json (8/8), operator-usage.json (3/3).
  • Also reconciles repo drift: these files had fallen far behind the live
    dashboards (unified-dashboard.json was at Grafana-internal version: 2 in
    the last commit vs. version: 28 live, i.e. OTL-73/74/80/82–89 never landed
    here). The formatting change was applied live first (pushed via
    scp+file-provisioning, not the API — see note below) and verified via the
    Grafana HTTP API before this commit, which brings the repo current in the same
    diff. That's why the file-level diff is large; the panel/legend classification
    above is the actual semantic change — happy to also paste the isolated
    legend-only diff in a comment if that's easier to review.

Notes for reviewers

  • Grafana calc-header rename isn't supported. Confirmed against
    grafana/grafana's packages/grafana-schema/src/common/common.gen.ts:
    VizLegendOptions has no field to override a calc column's display text.
    "latest/peak/total" is achieved by calc selection, not literal renaming.
  • The live push used file-provisioning, not scripts/deploy.sh dashboards.
    That script POSTs to /api/dashboards/db, which now 403s with "Cannot save provisioned dashboard"grafana-dashboards.yml has allowUiUpdates: false
    and the API refuses writes to provisioned dashboards regardless of credentials.
    This matches OTL-77 ("deploy host is not operable as documented"); worth a
    follow-up to fix or replace push_dashboards(). I instead scp'd the edited
    JSON directly into the host's dashboards/ directory (no git touched on the
    deploy host — it's currently running an unrelated uncommitted change) and let
    the file provisioner's 10s poll pick it up; confirmed live via
    GET /api/dashboards/uid/<uid> (version bumped 28→29 / 5→6 / 6→7, timestamps
    match, legend configs match).

Test plan

  • Verified live via Grafana API immediately after the scp push — all three
    dashboards' version incremented and options.legend on every touched
    panel matches the intended classification (spot-checked a Group A, Group B,
    and Group C panel per dashboard).
  • Confirmed the edit is surgical: diffed the pre/post JSON with every
    options.legend field stripped out — zero remaining differences, so no
    query, threshold, or other panel config changed.
  • Visual screenshot not captured — Grafana sits behind Cloudflare Access and
    the available browser tooling didn't have a quick way to inject the
    CF-Access service-token headers into a real page load; API verification
    was treated as authoritative instead.

🤖 Generated with Claude Code

…l calcs

The Claude Code dashboard's time-series panels had inconsistent legend
placement/width (mostly right+240px, several bottom with no width) and
inconsistent calc sets (lastNotNull/max/sum, mean-only, single-calc),
making legends hard to scan and not column-aligned across panels.

Every right-legend panel now uses the same width (280px, up from 240).
Additive per-interval quantities (spend, tokens, tool calls, PRs,
commits, worker events) get exactly three calcs: lastNotNull (Grafana
label "Last *"), max ("Max"), sum ("Total") — the closest built-in
equivalent to latest/peak/total (Grafana OSS 12.4.2's VizLegendOptions
has no field to rename calc column headers — confirmed against
grafana/grafana's common.gen.ts).

Monotonic/cumulative accumulator panels (ai:*_accum:sum-family) and
rate/percentage/duration/concurrency-gauge panels keep only latest+peak
— a forced "sum" total either double-counts a running total (the exact
OTL-82 bug) or produces a meaningless number for a %, ms, or
concurrent-session series. Two narrow (gridPos.w=8) repeated tiles keep
bottom placement so a 280px right legend doesn't crowd out the chart.

Applied to unified-dashboard.json (29 timeseries panels), codex-usage.json
(8 panels), and operator-usage.json (3 panels) — all three share the
pattern. Also reconciles these files with the live dashboards, which had
drifted far ahead of the last commit (unified-dashboard.json was at
Grafana-internal version 2 in this repo vs. version 28 live) — the
formatting change was applied live first (verified via the Grafana API)
and this brings the repo current in the same commit.

Closes OTL-90

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@ryanrozich
ryanrozich marked this pull request as ready for review August 27, 2026 17:38

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 14f1774545

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines 2 to 4
"annotations": {
"list": []
},

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Preserve the existing dashboard serialization

This reorders and reserializes all three dashboard files, turning roughly 40 targeted legend edits into 8,260 changed lines. A structural comparison shows that, after excluding legends, dashboard versions, and the added null IDs, the configurations are unchanged; the churn therefore obscures the actual behavior change and makes later reviews and backports unnecessarily error-prone. Apply the legend edits without reserializing the surrounding JSON, as required by the dashboard-specific editing guidance.

AGENTS.md reference: AGENTS.md:L13-L18

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant