chartPieDonutActive
A Charts block/component from shadcn/ui — clean-room reimplemented for Domphy (see methodology). Call chartPieDonutActive() with no arguments for a working demo, or edit the code below live.
Props
| Prop | Type | Description |
|---|---|---|
data | PieDatum[] | — |
title | string | — |
description | string | — |
trendValue | string | — |
trendDirection | "up" | "down" | — |
caption | string | — |
valueFormatter | (value: number) => string | — |
innerRadius | number | — |
activeKey | string | Category key drawn enlarged. Defaults to the first record. |
activeRadiusDelta | number | Extra outer-radius (viewBox units) the active wedge gets over the rest. |
Implementation notes
One wedge (activeKey, defaults to the first record) is statically drawn with +10 outer-radius units and a thicker stroke (2.5 vs 1.5) at build time, per the spec's explicit instruction that this recipe is a static showcase and must NOT be wired to hover/click (that behavior belongs to chartPieInteractive). Hover tooltips still work normally on every wedge. Same mount-sweep approximation caveat as chartPieSimple.
Status: ported · Reference: shadcn/ui original
// shadcn/ui "charts/pie-donut-active" — clean-room reimplementation.
//
// A donut chart where exactly one wedge is drawn permanently enlarged
// outward (extra outer radius + a slightly thicker stroke) as a static
// showcase of an "active slice" visual treatment — fixed by data
// index/build time, NOT driven by hover or click (that behavior belongs to
// chartPieInteractive). Implemented purely from the block's public
// functional/visual spec — no upstream source was viewed.
import type { DomphyElement } from "@domphy/core";
import { motion } from "@domphy/ui";
import {
createPieTooltipState,
DEFAULT_DONUT_INNER_RADIUS,
DEFAULT_PIE_DATA,
DONUT_SEPARATOR_STROKE_WIDTH,
defaultValueFormatter,
layoutPieSlices,
PIE_OUTER_RADIUS,
type PieDatum,
pieCard,
pieCardDescription,
pieCardFooter,
pieCardTitle,
pieChartContainer,
pieWedgePath,
} from "./pie-chart-shared.js";
export interface ChartPieDonutActiveProps {
data?: PieDatum[];
title?: string;
description?: string;
trendValue?: string;
trendDirection?: "up" | "down";
caption?: string;
valueFormatter?: (value: number) => string;
innerRadius?: number;
/** Category `key` drawn enlarged. Defaults to the first record. */
activeKey?: string;
/** Extra outer-radius (viewBox units) the active wedge gets over the rest. */
activeRadiusDelta?: number;
}
/**
* A donut chart with one wedge statically drawn enlarged to demonstrate an
* "active slice" treatment. Call with no arguments for a fully working demo.
*/
function chartPieDonutActive(
props: ChartPieDonutActiveProps = {},
): DomphyElement<"div"> {
const {
data = DEFAULT_PIE_DATA,
title = "Pie Chart - Donut Active",
description = "January - June 2024",
trendValue = "5.2%",
trendDirection = "up",
caption = "Showing total visitors for the last 6 months",
valueFormatter = defaultValueFormatter,
innerRadius = DEFAULT_DONUT_INNER_RADIUS,
activeKey = data[0]?.key,
activeRadiusDelta = 10,
} = props;
const slices = layoutPieSlices(data);
const tooltipState = createPieTooltipState();
const containerRef = { current: null as HTMLElement | null };
const wedges: DomphyElement<"path">[] = slices.map((slice) => {
const isActive = slice.datum.key === activeKey;
return pieWedgePath(slice, {
innerRadius,
outerRadius: isActive
? PIE_OUTER_RADIUS + activeRadiusDelta
: PIE_OUTER_RADIUS,
// Upstream applies a uniform strokeWidth={5} to the whole <Pie>; the
// active sector only grows its radius, it keeps the same outline weight.
strokeWidth: DONUT_SEPARATOR_STROKE_WIDTH,
tooltip: { containerRef, tooltipState, valueFormatter },
});
});
return pieCard([
pieCardTitle(title),
pieCardDescription(description),
pieChartContainer(
containerRef,
[
{
g: wedges,
style: { transformOrigin: "100px 100px" },
$: [
motion({
initial: { opacity: 0, scale: 0.7 },
animate: { opacity: 1, scale: 1 },
transition: { duration: 700, easing: "ease-out" },
}),
],
} as DomphyElement<"g">,
],
tooltipState,
`${title}: ${description}`,
),
pieCardFooter({ trendValue, trendDirection, caption }),
]);
}
export { chartPieDonutActive };