Skip to content

Add first-class PowerPoint bubble charts#2179

Open
PrzemyslawKlys wants to merge 4 commits into
masterfrom
feature/powerpoint-bubble-charts
Open

Add first-class PowerPoint bubble charts#2179
PrzemyslawKlys wants to merge 4 commits into
masterfrom
feature/powerpoint-bubble-charts

Conversation

@PrzemyslawKlys

@PrzemyslawKlys PrzemyslawKlys commented Jul 25, 2026

Copy link
Copy Markdown
Member

Summary

Adds first-class PowerPoint bubble charts to the shared chart contract. Callers can create a bubble series with X, Y, and per-point size values, then add it with the existing PowerPoint chart APIs.

Bubble data survives save/reopen, UpdateData(...), accessibility summaries, and the embedded workbook. Shared PNG, SVG, HTML, PDF, and raster output preserves point colors, outline color and width, zero-sized bubbles, native bubble scale, and exact area-versus-width sizing. Numeric ticks, gridlines, labels, and bubble centers share the same radius-safe coordinate map, so large extrema stay inside the plot without drifting away from their axes.

Semantic PowerPoint HTML stores X and bubble-size metadata and restores a native bubble chart on import. Malformed semantic data and invalid, non-finite, negative, missing, or mismatched native caches fail through the safe snapshot contract instead of silently changing the chart. Enabled 3-D bubble rendering is rejected because the shared renderers provide a flat bubble-chart surface.

The shared Excel entry point rejects the bubble kind explicitly instead of creating a different chart. Excel callers can continue to use the native Excel bubble-chart API.

Usage

var data = new OfficeChartData(
    new[] { "1", "2", "3" },
    new[] {
        OfficeChartSeries.CreateBubble(
            "Portfolio",
            xValues: new[] { 1D, 2D, 3D },
            yValues: new[] { 12D, 18D, 15D },
            bubbleSizes: new[] { 9D, 36D, 16D })
    });

slide.AddChartCm(OfficeChartKind.Bubble, data, 2, 3, 20, 10);

Bubble sizes must be finite and non-negative, with one size for every X/Y point.

Validation

The complete .NET 8 suites pass for Drawing (1,001), PowerPoint (1,407), HTML (1,225), and Excel (2,657), with seven opt-in live/Desktop tests skipped. Focused bubble tests pass on .NET 10. Drawing, PowerPoint, PowerPoint PDF, and PowerPoint HTML build for .NET Standard 2.0 with zero warnings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 73d4b26047

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread OfficeIMO.Drawing/OfficeChartDrawingRenderer.Bubbles.cs Outdated
Comment thread OfficeIMO.Drawing/OfficeChartKind.cs
Comment thread OfficeIMO.PowerPoint/PowerPointChart.SharedContract.cs Outdated
Comment thread OfficeIMO.PowerPoint/PowerPointChart.Snapshot.Bubbles.cs Outdated
Comment thread OfficeIMO.PowerPoint.Html/PowerPointHtmlConverterExtensions.cs

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4665a48e72

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread OfficeIMO.Drawing/OfficeChartSeries.cs
Comment thread OfficeIMO.PowerPoint/PowerPointChart.SharedContract.cs
Comment thread OfficeIMO.PowerPoint/PowerPointChart.Snapshot.cs
Comment thread OfficeIMO.PowerPoint.Html/HtmlPowerPointConverterExtensions.cs
Comment thread OfficeIMO.Drawing/OfficeChartDrawingRenderer.cs Outdated
Comment thread OfficeIMO.PowerPoint/PowerPointChart.Snapshot.Bubbles.cs Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6da4f7acac

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread OfficeIMO.PowerPoint.Pdf/PowerPointPdfConverterExtensions.Charts.cs Outdated
Comment thread OfficeIMO.Drawing/OfficeChartDrawingRenderer.cs Outdated
Comment thread OfficeIMO.Drawing/OfficeChartDrawingRenderer.Bubbles.cs Outdated
Comment thread OfficeIMO.PowerPoint/PowerPointChart.Snapshot.cs

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a11c1d98f6

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

+ plotArea.Elements<C.AreaChart>().Count()
+ plotArea.Elements<C.RadarChart>().Count()
+ plotArea.Elements<C.ScatterChart>().Count()
+ plotArea.Elements<C.BubbleChart>().Count()

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Reject mixed snapshots that omit bubble layers

When a native plot area contains a bubble layer plus at least two other compatible layers, this count sends it through TryCreateMixedChartSnapshot, but that method has no C.BubbleChart branch. The two other layers can therefore make parts.Count > 1 and produce a successful snapshot that silently excludes every bubble, causing shared image, HTML, and PDF exports to omit source data; explicitly reject such mixed plots or include the bubble layer in the mixed snapshot.

Useful? React with 👍 / 👎.

Comment on lines +551 to +554
if (series.BubbleSizes != null && i < series.BubbleSizes.Count) {
body.Append(" data-officeimo-bubble-size=\"")
.Append(OfficeHtmlText.EscapeAttribute(series.BubbleSizes[i].ToString("G17", CultureInfo.InvariantCulture)))
.Append('"');

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve bubble sizing semantics in semantic HTML

For a bubble chart whose native BubbleScale is not 100 or whose SizeRepresents is Width, semantic export records only the raw per-point sizes here. On import, TryCreateBubbleChartData recreates the chart through CreateSharedBubbleChart, which always uses scale 100 and Area, so an export/import round trip materially changes bubble dimensions and proportions without an approximation diagnostic; serialize and restore both chart-level settings alongside the size values.

Useful? React with 👍 / 👎.

Comment on lines +148 to +149
markerOutlineColor: item.StrokeColor ?? item.Color,
markerOutlineWidth: item.StrokeWidth));

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve explicitly disabled bubble outlines

When an imported bubble series explicitly uses <a:noFill/> for its outline, ReadSeriesStrokeColor returns null, and this fallback substitutes the bubble fill color instead. CreateBubble and AddBubbleMarker then render a visible 1-point (or retained-width) border, so PNG, SVG, HTML, and PDF snapshots add an outline that the native chart explicitly disabled; carry a distinct no-outline state rather than treating it as a missing color.

Useful? React with 👍 / 👎.

Comment on lines 1644 to +1647
if (layout.ShowMarkers && currentSeries.ShowMarkers) {
OfficeColor pointColor = GetPointColor(currentSeries.PointColors, points[i].SourceIndex, color);
AddMarker(drawing, currentSeries, point, 5D, pointColor, 1.25D);
if (currentSeries.BubbleSizes != null) {
AddBubbleMarker(drawing, currentSeries, points[i].SourceIndex, point,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Render bubble glyphs independently of marker visibility

When a Bubble snapshot is rendered with OfficeChartLayout(showMarkers: false), this outer condition skips AddBubbleMarker for every point. Because bubble series have no connecting line or other data glyph, the resulting chart contains axes and possibly labels but none of its bubbles; treat bubble glyphs as the chart's data marks rather than optional scatter markers.

Useful? React with 👍 / 👎.

Comment on lines +1646 to +1651
if (currentSeries.BubbleSizes != null) {
AddBubbleMarker(drawing, currentSeries, points[i].SourceIndex, point,
maximumBubbleSize, maximumBubbleDiameter,
snapshot.BubbleSizeMode, pointColor);
} else {
AddMarker(drawing, currentSeries, point, 5D, pointColor, 1.25D);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Reject Bubble snapshots without size data

The public Drawing contract permits OfficeChartSnapshot to use OfficeChartKind.Bubble with an ordinary OfficeChartSeries whose BubbleSizes is null. For numeric categories, this fallback renders every point as a fixed-size scatter marker and reports success, even though the requested chart has no bubble-size data; validate the Bubble contract or skip/fail the malformed series instead of silently changing chart families.

Useful? React with 👍 / 👎.

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