Domphy

chartRadialStacked

A Charts block/component from shadcn/ui — clean-room reimplemented for Domphy (see methodology). Call chartRadialStacked() with no arguments for a working demo, or edit the code below live.

Implementation notes

Half-circle (180deg, startAngle -90) two-segment gauge (renderRadialStackedGauge): segments share one thick band (innerRadiusRatio 0.75) and are drawn back-to-back with round caps and a small angular gap between them. FIDELITY NOTE: the spec describes 'gently rounded [segment] ends' plus 'a thin border in the page background color separating the two segments' — this is approximated as a single small (1.5deg default, configurable) rounded-cap gap at the shared boundary rather than drawing a literal thin divider stroke, which reads as very similar visually (two rounded-cap pill segments meeting almost end-to-end) without needing a third overlay stroke layer. Center total (sum of segment values) + caption uses the same HTML-overlay heading()/small() treatment as chartRadialShape/Text, positioned within the dome's own bounding area. Hover tooltip (swatch + segment label) reuses the shared radial tooltip controller. tsc --noEmit clean; 2/2 tests pass.

Status: ported · Reference: shadcn/ui original

// shadcn/ui "chart-radial-stacked" recipe — clean-room reimplementation.
//
// A half-circle gauge: one thick band spanning the top half of the circle,
// split end-to-end into two (or more) rounded-cap colored segments sized by
// their share of the total, with a large bold total number and a smaller
// muted caption centered in the gauge's open area. Hovering either segment
// shows a swatch + value tooltip.
//
// Implemented purely from the block's public functional/visual spec — no
// upstream shadcn/ui source was viewed or copied.

import type { DomphyElement } from "@domphy/core";
import { chartCardShell, chartTrendFooter, type ChartTrendDirection } from "./chart-area-shared.js";
import {
  RADIAL_STACKED_SEGMENTS,
  createRadialTooltip,
  renderRadialStackedGauge,
  type RadialSeriesDatum,
} from "./chart-radial-shared.js";

export interface ChartRadialStackedProps {
  segments?: RadialSeriesDatum[];
  totalCaptionText?: string;
  title?: string;
  description?: string;
  trendText?: string;
  trendDirection?: ChartTrendDirection;
  footerCaptionText?: string;
  sweepDegrees?: number;
  innerRadiusRatio?: number;
}

/**
 * shadcn/ui "chart-radial-stacked" recipe — a half-circle two-segment gauge
 * with a centered total. Call with no arguments for a working demo.
 */
function chartRadialStacked(props: ChartRadialStackedProps = {}): DomphyElement<"div"> {
  const {
    segments = RADIAL_STACKED_SEGMENTS,
    totalCaptionText = "Total customers",
    title = "Radial Chart - Stacked",
    description = "January - June 2026",
    trendText = "Trending up by 5.2% this month",
    trendDirection = "up",
    footerCaptionText = "Showing total customers for the last 6 months",
    sweepDegrees = 180,
    innerRadiusRatio = 0.75,
  } = props;

  const total = segments.reduce((sum, segment) => sum + segment.value, 0);
  const tooltip = createRadialTooltip();

  return chartCardShell({
    title,
    description,
    content: {
      div: [
        renderRadialStackedGauge({
          segments,
          tooltip,
          totalText: total.toLocaleString("en-US"),
          captionText: totalCaptionText,
          sweepDegrees,
          innerRadiusRatio,
        }),
      ],
      style: { display: "flex", alignItems: "center", justifyContent: "center" },
    },
    footer: chartTrendFooter({ trendText, direction: trendDirection, captionText: footerCaptionText }),
  });
}

export { chartRadialStacked };

← Back to shadcn/ui catalog