Skip to content

CmdPal: Render Adaptive Cards gauge, donut, and pie charts natively - #51219

Open
Clint Rutkas (crutkas) wants to merge 1 commit into
crutkas-stack-9-network-cardfrom
crutkas-stack-10-gauge-donut-pie-charts
Open

Clint Rutkas (crutkas) wants to merge 1 commit into
crutkas-stack-9-network-cardfrom
crutkas-stack-10-gauge-donut-pie-charts

Conversation

@crutkas

Copy link
Copy Markdown
Member

Summary of the Pull Request

Layer 10 of 13 in a stack that splits #51125 (native Adaptive Cards charts and redesigned Performance Monitor cards) into reviewable PRs. See #51125 for the full picture. This layer is based on layer 9 (#51218, crutkas-stack-9-network-card), so the diff shows only this layer.

The WinUI 3 Adaptive Cards renderer drops elements it doesn't know, even with a fallback. This layer adds the schema's last three chart elements to the polyfills library:

  • Chart.Gauge: a value on a half circle, optionally split into colored segments. The redesigned Battery card (layer 11) uses it for the charge level.
  • Chart.Donut and Chart.Pie: parts of a whole, with a legend that gives each part's share. The Charts and visuals sample page (layer 13) shows both.

With this layer, the polyfills library and its tests match #51125, except for three README changes described below.

PR Checklist

  • Communication: I've discussed this with core contributors already. If the work hasn't been agreed, this work might be rejected
  • Tests: Added/updated and all pass
  • Localization: All end-user-facing strings can be localized (three new strings, AdaptiveChart_Gauge, AdaptiveChart_DonutChart, and AdaptiveChart_PieChart, in Command Palette's Resources.resw)
  • Dev docs: Added/updated (the library's README.md)
  • New binaries: Added on the required places (N/A, no new binaries)
  • Documentation updated: If checked, please file a pull request on our docs repo and link it here: #xxx

Detailed Description of the Pull Request / Additional comments

Elements

Each element follows layer 2's pattern: a model that parses the element JSON leniently (invalid values read as missing and add a warning), and an AdaptiveVisualControl that draws it with shapes and text. All three are in AdaptiveCardPolyfills' element list, so they're registered as parsers, renderers, and PatchableElements, and data changes update them in place.

  • GaugeChartModel, GaugeChartControl (Chart.Gauge): read title, showTitle (off by default), subLabel, value, min, max, valueFormat, colorSet, showLegend, showMinMax, and showNeedle (these three are on by default), and segments items with legend, size, and color.
    • Range: min defaults to 0. max defaults to min plus the segments' total size, or to 100 without segments. A max that isn't greater than min warns and uses min + 100. Values outside the range draw at its ends.
    • Drawing: the value fills the track in the color of the segment it falls in, and the segments form a thin scale inside the track. Without segments, the fill is the accent color, or the color set's first color. The needle marks the value. Inside the arc are the sub label and the value, either as a percentage of the range (percentage, the default) or as value/max (fraction). showMinMax labels the ends of the arc, and the legend lists the segments. The arc follows the element's width, from 96 to 220 px.
    • Colors: a segment uses its color, or the color set's colors in turn.
    • High contrast: the segments fill the track at full width, solid or (every third and fourth) outlined, and the needle marks the value. The needle has a halo in the window color, because a segment can be the same color as the needle.
  • DonutChartModel, DonutChartControl (Chart.Donut and Chart.Pie): read title, showTitle (off by default), colorSet, showLegend (on by default), and data items with legend, value, and color. Missing data warns. A donut's value is a label in its center, such as "512 GB"; a pie has no center label.
    • Drawing: each slice is its share of the total, and negative values count as zero. The chart is 88 to 160 px across. The legend lists each slice's label and share. It sits beside the chart when the element is at least 300 px wide, and below it otherwise.
    • Colors: a slice uses its item's color, or the color set's colors in turn (categorical by default).
    • High contrast: slices take the contrast theme's colors in turn, and every third and fourth slice is an outline. Filled pie wedges get window-colored edges to keep them apart.
  • Accessibility: each chart is named by its title, or for a gauge without one, by its sub label. Charts with neither get "Gauge", "Donut chart", or "Pie chart". A gauge's help text is its value; a donut's or pie's lists each slice's label and share.

Docs

The library's README.md lists the three elements, and its example of rendering choices made in the control now includes the gauge.

Three README changes from #51125 are left out on purpose:

Screenshots

From a local card harness (not in the repo) that renders cards through IncrementalAdaptiveCardUpdater with the polyfills registered, main's host config, and the real CardOverrideStyles from ContentFormControl.xaml, 776 px wide.

Gauges: battery-style gauges at 12%, 35%, and 100%, with segments and no legend or min and max labels; a gauge without segments or a needle; a titled gauge with the schema's defaults (a legend and min and max labels); and an untitled fraction gauge with the diverging color set.

Dark Light
Gauges at several levels, dark theme Gauges at several levels, light theme

Donut and pie charts: a donut with a center label and a neutral slice; a pie with the categorical color set; an untitled donut with a color for each slice; and an untitled pie with the sequential color set and no legend.

Dark Light
Donut and pie charts, dark theme Donut and pie charts, light theme

The same cards with the Aquatic contrast theme simulated. Charts take the contrast theme's colors, every third and fourth segment or slice is an outline, and gauges with segments draw them at full width while the needle marks the value:

Gauges Donut and pie charts
Gauges with the Aquatic contrast theme simulated Donut and pie charts with the Aquatic contrast theme simulated

Validation Steps Performed

The 6 new files and AdaptiveCardPolyfills.cs are identical to their versions at #51125's head (8858a9e0a7). The polyfills library and its tests now match #51125, except for README.md (the three changes above). Resources.resw differs from #51125 only by a string that main added after #51125 branched.

ARM64 Debug builds, run from a subst drive, at this PR's head (common build options: -nologo -m -restore -t:Build -v:minimal -p:Configuration=Debug -p:Platform=ARM64 -p:RuntimeIdentifier=win-arm64 -p:CIBuild=false -p:GeneratePackageLocally=false -p:GenerateAppxPackageOnBuild=false -p:PublishAppxPackage=false -p:SkipLongPathsCheck=true):

  • MSBuild.exe src\modules\cmdpal\Tests\Microsoft.CmdPal.AdaptiveCards.Polyfills.UnitTests\Microsoft.CmdPal.AdaptiveCards.Polyfills.UnitTests.csproj <options>, with -t:Rebuild: exit code 0, no warnings. It builds the library, which runs the trim and AOT analyzers.
  • vstest.console.arm64.exe ARM64\Debug\WinUI3Apps\CmdPal\tests\Microsoft.CmdPal.AdaptiveCards.Polyfills.UnitTests.dll /Platform:ARM64: 128 passed, 0 failed. That's 113 from layers 2 to 4, plus 15 new ones in DonutChartModelTests and GaugeChartModelTests.
  • MSBuild.exe src\modules\cmdpal\Microsoft.CmdPal.UI\Microsoft.CmdPal.UI.csproj <options>, with -m:4: exit code 0.
  • MSBuild.exe src\modules\cmdpal\Tests\Microsoft.CmdPal.UI.UnitTests\Microsoft.CmdPal.UI.UnitTests.csproj <options>, with -m:4: exit code 0.
  • vstest.console.arm64.exe ARM64\Debug\WinUI3Apps\CmdPal\tests\Microsoft.CmdPal.UI.UnitTests.dll /Platform:ARM64: 715 passed, 0 failed.
  • A local approximation of check-spelling over this diff (the repo's workflow is disabled): no unknown words or forbidden patterns.

Card harness under JIT, dark and light, for 8 seconds; it counts the updates that replaced the whole card:

  • The two cards above: no parse warnings, and they render as shown. The untitled charts' accessible names are "Gauge", "Donut chart", and "Pie chart", read from Resources.resw.
  • A live card with a gauge, a donut, and a pie whose values change every second: 11 updates, and none replaced the card. Each chart kept the same control instance, so all three patch in place.
  • The Aquatic contrast theme, simulated: the screenshots above.

Not run: a native AOT publish of the harness. The library's trim and AOT analyzers pass, and this branch has the same type-preservation attributes as #51125.

@github-actions github-actions Bot added Product-Command Palette Refers to the Command Palette utility Ready for review labels Oct 12, 2026
@github-actions

Copy link
Copy Markdown

🧭 PR intake

Visual evidence: Not needed — The changed files do not indicate a visible UI change. Visual evidence was detected in the PR description.

Recommendation

Link the issue this PR fixes using a closing keyword such as Closes #123.

✅ Ready for review

This PR passed the automated intake checks and is ready for maintainer review.

Automated PR intake; PowerToys maintainers make final decisions.

Adds the Chart.Gauge, Chart.Donut, and Chart.Pie elements to the
Adaptive Cards polyfills library. The WinUI 3 renderer doesn't support
them yet.

- A gauge fills its arc up to the value, in the color of the segment
  that the value falls in, and draws the segments as a thin scale
  inside it. It can show a needle, min and max labels, and a legend,
  and its value as a percentage or a fraction.
- Donut and pie charts draw a slice for each data point, with a legend
  of each slice's share. A donut can show a value in its center.
- Untitled charts get the accessible name "Gauge", "Donut chart", or
  "Pie chart", from three new strings in Resources.resw. A gauge uses
  its sub label first.

Layer 10 of 13 in a stack that splits #51125.
@zadjii-msft
Mike Griese (zadjii-msft) force-pushed the crutkas-stack-10-gauge-donut-pie-charts branch from b69e2cc to aca3fc5 Compare October 15, 2026 11:15

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Product-Command Palette Refers to the Command Palette utility Ready for review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant