Skip to content

Component | RadialBar: Add barMinAngle config property - #114

Draft
rokotyan wants to merge 5 commits into
mainfrom
radial-bar-min-angle
Draft

Component | RadialBar: Add barMinAngle config property#114
rokotyan wants to merge 5 commits into
mainfrom
radial-bar-min-angle

Conversation

@rokotyan

Copy link
Copy Markdown

f5#863

Bars representing tiny values collapse into an invisible hairline: a value of 0.05% of the max is 0.4px of arc, which the browser paints as nothing. barMinAngle gives every bar a floor on its angular extent, the same idea as barMinHeight1Px in StackedBar, but expressed as an angle.

barMinAngle cases in the dev examples app

barMinAngle

  • Radians, defaults to 0.01 — about one pixel wide on a ring of a 100 pixel radius, so small values stay perceptible out of the box. Set it to 0 to get the old behavior back, or raise it to make them prominent.
  • Clamped to the length of angleRange — a value larger than the range simply fills it (last panel above).
  • Applied along the sweep direction — reversed ranges, e.g. [0, -2 * Math.PI], keep rendering counter-clockwise.
  • The floor only ever grows a bar: bars whose natural sweep is already wider are untouched.

Because the minimum is an angle, the same setting is thinner on inner rings (1.19px on the outermost ring vs 0.66px on the fourth, at the default). A pixel-exact floor would need a per-ring minWidthPx / outerRadius; happy to switch if that reads better.

0 vs missing data

The value accessor result used to be coerced with ?? 0, so a missing value and a real 0 were indistinguishable, and both drew nothing. They're now separate cases:

  • 0 is a value — it gets barMinAngle and shows up as a small tick, so an empty metric is visibly empty rather than absent.
  • null / undefined / non-finite is missing data — the arc stays collapsed and hidden, leaving only the background track.

RadialBarArcDatum.value is number | null accordingly, which is visible to tooltips and event handlers.

While wiring this up I also made the default id accessor null-safe: with gaps in the data the record itself can be null (data={[0.5, null, 0.2]}), which used to throw Cannot read properties of null (reading 'id') on the data join.

Docs

Minimum Bar Angle section in the RadialBar docs

Included

  • CorebarMinAngle config property, missing-value handling, null-safe default id accessor.
  • Angular — the new @Input(). Hand-written to match the generated style: pnpm generate currently rewrites every component's imports into internal @/* alias paths, which don't resolve in that package (fallout from the alias migration, worth a separate fix). React / Vue / Svelte / Solid are generic over the config interface and need no change.
  • Dev examplesRadial Bar Min Angle with the cases in the screenshot above.
  • Docs — a Minimum Bar Angle section with a live slider, plus the 0-vs-missing distinction.

Verification

Measured the rendered bar bounding boxes in the dev app (rings of a ~107px radius, trackWidth: 14):

barMinAngle tiny value (0.05%) 0 value null value
0 0.38px hidden hidden
0.01 (default) 1.19px 0.66px hidden
0.2 22.55px 11.98px hidden

Also checked the docs demo across slider positions, half and reversed angle ranges, padAngle interplay, and clamping. tsc --noEmit and eslint are clean; both core commits compile in isolation.

rokotyan and others added 5 commits July 28, 2026 12:57
The `value` accessor result was coerced with `?? 0`, making a missing value
indistinguishable from a real `0`. Keep it as `null` instead, so the arc stays
collapsed and hidden, and let `0` be rendered as an actual data point.

`RadialBarArcDatum.value` is now `number | null` accordingly.

Also make the default `id` accessor null-safe: with gaps in the data, the
record itself can be `null`, which used to throw when reading `d.id`.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Bars representing tiny values were collapsing into an invisible hairline.
`barMinAngle` sets the minimum angular extent of a bar in radians, `0` values
included, so that they stay on screen. It defaults to `0.01`, which is about
one pixel wide on a ring of a 100 pixel radius, and it's clamped to the length
of `angleRange`. Bars with missing values are unaffected: they're never drawn.

The minimum is applied along the sweep direction, so reversed angle ranges,
e.g. `[0, -2 * Math.PI]`, keep rendering counter-clockwise.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Hand-written to match the generated style: `pnpm generate` currently rewrites
every component's imports into internal `@/*` alias paths, which don't resolve
in this package.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Side-by-side cases for `barMinAngle`: disabled, the default, a large value,
combined with `padAngle`, half and reversed angle ranges, and a value above
the angle range to check clamping. The data covers a tiny value, a `0`, and a
`null` to show that missing values stay unrendered.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Document `barMinAngle` with an interactive slider, and the difference between
a `0` value and a missing one.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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