Animated inline-SVG pie and donut chart with configurable legend, percentage labels, and color palette. 1 control, 13 properties. Renders entirely in a single Image control via data:image/svg+xml.
This component requires Modern controls to be enabled. Settings → Updates → Preview → Modern controls and themes
If your users are in a comma-decimal region, wrap the numbers
This chart draws with an SVG built by string concatenation, and Power Fx & converts numbers using the viewer’s locale. In regions that write 123,45 rather than 123.45, SVG reads that comma as a separator between two numbers and the arc endpoints from Sin/Cos silently fail to draw. Axes and labels still render, because whole numbers are unaffected.
The fix is to format explicitly at the point of concatenation. In this component that means arc endpoints from Sin/Cos, the donut inner radius, and label positions:
- " A " & radius & " " & radius & " 0 " & largeArc & " 1 " & x2 & " " & y2+ " A " & radius & " " & radius & " 0 " & largeArc & " 1 " & Text(x2, "[$-en-US]0.##") & " " & Text(y2, "[$-en-US]0.##")Do not repair the finished string with Substitute(s, ",", "."). That also rewrites thousands separators in your labels, turning 1,420 into 1.420, and breaks comma-separated font stacks.
# In Power Apps Studio:
1. Components tab → New component → Import from code
2. Paste the full YAML definition
3. Add the component to any screen
4. Press F5 (Preview) to trigger the entry animation// ChartData: one row per slice with Label, Value, optional Color
cmpPieChart.ChartData = Table(
{ Label: "Marketing", Value: 35000, Color: "#3B82F6" },
{ Label: "Sales", Value: 28000, Color: "#10B981" },
{ Label: "Engineering", Value: 22000, Color: "#F59E0B" },
{ Label: "Operations", Value: 15000, Color: "#EF4444" }
)
cmpPieChart.ChartTitle = "Budget Allocation"
cmpPieChart.ShowPercentages = true
cmpPieChart.ShowLegend = true// Shape data into Label + Value + Color rows
cmpPieChart.ChartData =
AddColumns(
GroupBy(SalesData, "Region", "Sales"),
"Label", Region,
"Value", Sum(Sales, Amount),
"Color", Switch(
Region,
"North", "#3B82F6",
"South", "#10B981",
"East", "#F59E0B",
"West", "#8B5CF6",
"#6B7280"
)
)
cmpPieChart.ChartTitle = "Sales by Region"
cmpPieChart.DonutMode = true
cmpPieChart.DonutThickness = 0.7cmpPieChart.Theme = "Dark"
cmpPieChart.Animate = true
cmpPieChart.ShowValues = true
cmpPieChart.ShowPercentages = true
// Custom color palette (used when Color column is blank)
cmpPieChart.DefaultColors = Table(
{ Color: "#1E40AF" },
{ Color: "#3B82F6" },
{ Color: "#60A5FA" },
{ Color: "#93C5FD" }
)| Property | Type | Default |
|---|---|---|
ChartDataTable with Label (text), Value (number), and optional Color (text) columns. One row per slice. | Table | 4-item sample |
ChartTitleTitle text rendered at the top-left of the SVG. | Text | "Budget Allocation" |
DefaultColorsFallback color palette when Color column is blank. Cycles via Mod(). | Table | 8-color palette |
DonutModeRender as donut chart with center hole. | Boolean | false |
DonutThicknessThickness of donut ring. 0.3 = thin ring, 0.9 = nearly full pie. | Number | 0.6 |
ShowLabelsShow text labels on slices. Only rendered for slices ≥ 5%. | Boolean | true |
ShowLegendShow legend with color swatches on the right side. | Boolean | true |
ShowPercentagesShow percentage values on slice labels and in legend. | Boolean | true |
ShowTitleShow the ChartTitle text. | Boolean | true |
ShowValuesShow actual numeric values in the legend. | Boolean | false |
Theme"Light" or "Dark". Controls background, title, legend, and empty state colors. | Text | "Light" |
AnimateEnable slice fade-in animation with staggered delays. | Boolean | true |
AnimationDurationDuration of each slice’s animation in seconds. | Number | 0.8 |
No output properties or events — the component is purely visual (SVG rendering). 13 input properties total.
| Field | Type | Notes |
|---|---|---|
| Label | Text | Slice label. Displayed in legend and optionally on the slice itself. |
| Value | Number | Numeric value. The chart auto-calculates percentages from Sum(Data, Value). |
| Color | Text (optional) | Hex color string (e.g. "#3B82F6"). Falls back to DefaultColors palette if blank. |
| Field | Type | Notes |
|---|---|---|
| Color | Text | Hex color string. Palette cycles via Mod(idx - 1, CountRows(Colors)) + 1. |
The entire chart is a single Image control generating a data:image/svg+xml URI. No dependencies — works anywhere Power Apps renders images, including galleries and PDF exports.
Each slice is an SVG <path> using arc commands. Start angles accumulate from -90° (12 o'clock). The large-arc-flag switches at 180°. A single-slice 100% case (sweep ≥ 359.9) falls back to a full <circle> since SVG arcs can't draw a complete ring.
When DonutMode = true, paths become ring arcs: outer arc forward, inner arc backward, forming closed annular sectors. The inner radius is radius × (1 - DonutThickness). Labels position at the midpoint of the ring: (radius + innerR) / 2.
Each slice first checks its own Color column. If blank, it indexes into DefaultColors with modular cycling: Mod(idx - 1, CountRows(Colors)) + 1. This means 12 slices with an 8-color palette will wrap and reuse.
Three CSS @keyframes injected via <style> when Animate is on:pieGrow (scale 0→1 for single-slice),sliceFade (opacity + scale, staggered at 0.08s intervals), andlabelFade (delayed until half-way through slice animation).
Slice labels only render when percent ≥ 5. This prevents overlapping text on tiny slices. When ShowPercentages is on, labels show the rounded percentage; otherwise they show the Label text.
No interactive tooltips (inline SVG in Image controls doesn't support hover events). Legend is fixed to the right side — the pie repositions from center to cx=200 when legend is on. Empty state renders a centered “No data” message when ChartData is empty or total is zero.
cmpPieChart.ChartData = Table(
{Label:"Marketing",Value:35,Color:"#3B82F6"},
{Label:"Sales",Value:28,Color:"#10B981"},
{Label:"Engineering",Value:22,Color:"#F59E0B"},
{Label:"Operations",Value:15,Color:"#EF4444"}
)
cmpPieChart.ChartTitle = "Budget Allocation"
cmpPieChart.ShowPercentages = true
cmpPieChart.ShowValues = true
cmpPieChart.DonutMode = falsecmpPieChart.Theme = "Dark"
cmpPieChart.DonutMode = true
cmpPieChart.DonutThickness = 0.6
cmpPieChart.ChartTitle = "Sales by Region"
cmpPieChart.ShowPercentages = true// Minimal donut — labels only
cmpPieChart.ShowTitle = false
cmpPieChart.ShowLegend = false
cmpPieChart.ShowValues = false
cmpPieChart.ShowLabels = true
cmpPieChart.DonutMode = true1 control — a single Image control rendering an inline SVG via EncodeUrl().
13 properties — all input. No output properties or events.
Default size — App.Width × 400px. SVG viewBox is 700 × 350.
cmpPieChart (App.Width × 400, Fill: transparent)
└── imgPieChart (Image control)
└── Image = "data:image/svg+xml," & EncodeUrl(svg)
SVG structure (viewBox 700×350):
├── <style> @keyframes (conditional on Animate)
├── <text> ChartTitle (top-left, conditional on ShowTitle)
├── For each slice in ChartData:
│ ├── <path> Pie slice (or donut ring arc)
│ │ └── style: sliceFade animation (staggered 0.08s)
│ └── <text> Percentage/label (conditional: ShowLabels && pct ≥ 5%)
├── <circle> Donut center hole (conditional on DonutMode)
└── Legend (conditional on ShowLegend, positioned at x=380):
└── For each slice:
├── <rect rx=3> Color swatch
├── <text> Label name
└── <text> Value / percentageOne email when something new ships. Unsubscribe anytime.
Use the toolbar to format · or type markdown directly