Skip to content

[FEATURE] format: custom unit with display label - #297

Open
colivi wants to merge 1 commit into
perses:mainfrom
colivi:feat/custom-format-unit
Open

colivi wants to merge 1 commit into
perses:mainfrom
colivi:feat/custom-format-unit

Conversation

@colivi

@colivi colivi commented Sep 15, 2026

Copy link
Copy Markdown
Contributor

Description

Adds support for custom unit display labels without expanding the standard CUE unit enum.

Problem

Operational dashboards (and sometimes customer-facing views) use Grafana-era labels such as "pnr/mn", "trx/s", "pax/mn".
Mapping everything to generic units like "ops/sec" is CUE-valid but loses the domain language users expect.
Growing the shared enum with org-specific aliases (e.g. "msg/s" next to "messages/sec") does not scale.

Approach

  • "unit" stays the stable key (multi-axis, format maps, UI config) — still a standard enum value ("ops/sec", "decimal", …).
  • "customLabel" is optional and display-only (axis / legend / tooltip text).
  • Numeric formatting (including SI/short compact values) comes from the standard "unit"; only the visible suffix is overridden.

Changes

Layer Change
CUE ("cue/common/format.cue") Optional "customLabel" on "#simpleFormat" / "#floatFormat" / "#shortenableFormat"
TS "applyCustomLabel()" after standard "formatValue"; "getUnitConfig" can show the custom label
UI Optional Custom label text field in FormatControls (unit selector unchanged)

Example JSON

json { "unit": "ops/sec", "customLabel": "pnr/mn", "shortValues": true }

Renders like 1.5K pnr/mn (numeric formatting from ops/sec, label from customLabel).

Screenshots

image

Checklist

  • Pull request has a descriptive title and context useful to a reviewer.
  • Pull request title follows the [<catalog_entry>] <commit message> naming convention using one of the
    following catalog_entry values: FEATURE, ENHANCEMENT, BUGFIX, BREAKINGCHANGE, DOC,IGNORE.
  • All commits have DCO signoffs.

UI Changes

  • Changes that impact the UI include screenshots and/or screencasts of the relevant changes.
  • Code follows the UI guidelines.
  • E2E tests are stable and unlikely to be flaky.
    See e2e docs for more details. Common issues include:
    • Is the data inconsistent? You need to mock API requests.
    • Does the time change? You need to use consistent time values or mock time utilities.
    • Does it have loading states? You need to wait for loading to complete.

@colivi
colivi requested review from a team and AntoineThebaud as code owners September 15, 2026 09:57
@colivi
colivi force-pushed the feat/custom-format-unit branch from eb9b61a to c0b2398 Compare September 15, 2026 10:01
Comment thread cue/common/format.cue Outdated

Copilot AI 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.

🟡 Changes recommended

Unit replacement fails for several supported formats, and trimming prevents typing labels containing spaces.

Get a fresh assessment by requesting another Copilot review.

Pull request overview

Adds display-only custom labels while retaining standard unit formatting and keys.

Changes:

  • Extends CUE and TypeScript format options with customLabel.
  • Applies custom labels to formatted values and unit metadata.
  • Adds a custom-label field and focused tests.
File summaries
File Description
cue/common/format.cue Adds the optional schema field.
cue-test/common/format.cue Adds a valid schema example.
components/src/model/units.ts Integrates custom-label formatting.
components/src/model/index.ts Exports the new API.
components/src/model/custom.ts Implements label replacement.
components/src/model/custom.test.ts Tests custom-label behavior.
components/src/FormatControls/UnitSelector.tsx Simplifies null handling.
components/src/FormatControls/FormatControls.tsx Adds custom-label controls.
Review details
  • Files reviewed: 8/8 changed files
  • Comments generated: 2
  • Review effort level: Balanced

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread components/src/FormatControls/FormatControls.tsx
Comment thread components/src/model/custom.ts Outdated
Comment on lines +32 to +36
const lastSpace = formatted.lastIndexOf(' ');
if (lastSpace > 0) {
return `${formatted.slice(0, lastSpace)} ${label}`;
}
return `${formatted} ${label}`;

@AntoineThebaud AntoineThebaud Sep 18, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Indeed there are issues with the current logic, that's what I got by trying some units:

  • time units are not properly replaced by the logic
2026-09-18_16h16_18 in some cases you can even end up with a mix of replaced & not replaced like here: image (here it's with a trend at value 1 and unit=Months)
  • for throughput units I guess the output is wrong too?
2026-09-18_16h17_41

@AntoineThebaud

Copy link
Copy Markdown
Contributor

As always, screenshot please 🤓

Comment thread cue/common/format.cue Outdated
@colivi

colivi commented Sep 17, 2026

Copy link
Copy Markdown
Contributor Author

As always, screenshot please 🤓

Hi Antoine, yes here it is

image

@AntoineThebaud

Copy link
Copy Markdown
Contributor

As always, screenshot please 🤓

Hi Antoine, yes here it is

image

I dont see the code related to the "showcase" + detail part at the end, are you sure this screenshot is up to date? I'm fine with the code btw, I dont feel this detail is necessary to display

@colivi

colivi commented Sep 17, 2026

Copy link
Copy Markdown
Contributor Author

As always, screenshot please 🤓

Hi Antoine, yes here it is
image

I dont see the code related to the "showcase" + detail part at the end, are you sure this screenshot is up to date? I'm fine with the code btw, I dont feel this detail is necessary to display

You’re right, the earlier PR description still mentioned a “Custom” unit / showcase detail that we dropped.
Current UI is only the optional Custom label field next to a standard unit (ops/sec + pnr/mn)

@colivi

colivi commented Sep 18, 2026

Copy link
Copy Markdown
Contributor Author

here it is

image

colivi added a commit to colivi/shared that referenced this pull request Sep 18, 2026
Strip Intl time suffixes (ms, month, …) and rate units so customLabel
fully replaces the standard unit text (Antoine review on perses#297).

Signed-off-by: colivi <charles.olivi@gmail.com>
colivi added a commit to colivi/shared that referenced this pull request Sep 18, 2026
@colivi
colivi force-pushed the feat/custom-format-unit branch from 753fcc1 to 0071813 Compare September 18, 2026 15:00
Allow dashboards to keep a CUE-safe unit key (ops/sec, milliseconds, …)
while displaying a business label (pnr/mn, latency, …) on axes, legends,
and tooltips.

- FormatControls: optional Custom label (whitelist of supported units)
- applyCustomLabel: strip Intl time suffixes; count-rate throughput
- Bits/bytes excluded (SI size prefixes not reapplied to free-form labels)
- CUE #format.customLabel (strings.MinRunes(1), factored once)
- Tests for percent/temp/ops/sec, multi-scale months, unsupported units

Signed-off-by: colivi <charles.olivi@gmail.com>
@colivi
colivi force-pushed the feat/custom-format-unit branch from 0071813 to b10aed4 Compare September 18, 2026 15:19
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.

3 participants