[BUG] addChart() writes an orphan <c:axId> for BAR/LINE charts — third axis ID has no matching <c:serAx>, triggers "repair" dialog in PowerPoint
Nobody has claimed this yet.
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 78/100
- Issue type
- Bug
- Clarity
- Clearly specified
- Activity status
- Active
- Tech stack
- javascript, node.js, typescript
- Domain
- tooling
Research direction
Run the provided Node.js reproduction and inspect ppt/charts/chart1.xml for the extra axId. Compare the axId emission near line 3846 in dist/pptxgen.cjs.js with the BAR3D-only serAx handling near line 3481, also checking the corresponding .es.js and .bundle.js files. Done means 2D BAR and LINE charts contain two axId elements and open in PowerPoint without repair, while BAR3D retains its series axis reference.
Written by the indexing model from the issue text.
Description
Submission Guidelines
- I am using the latest release (4.0.1) and the issue is still present
- I checked the online Documentation — this isn't addressed there
Issue Category
- Enhancement
- Bug
- Question
- Documentation gap/issue
Product Versions
- Please specify what version of the library you are using......: [4.0.1]
- Please specify what version(s) of PowerPoint you are targeting: [Microsoft 365 desktop + PowerPoint Online — both trigger repair]
- Please specify what web browser you are using.................: [N/A — generated server-side with Node.js]
Desired Behavior
For a 2D BAR chart (and LINE, which shares the same code path), <c:barChart> / <c:lineChart> should declare exactly 2 <c:axId> elements (category + value), matching the two axis definitions actually written to the chart XML. The file should open in PowerPoint without triggering the "repair" dialog.
Observed Behavior
For every BAR (and LINE) chart, PptxGenJS writes three <c:axId> elements:
<c:axId val="2094734554"/><c:axId val="2094734552"/><c:axId val="2094734556"/>
but only two axis parts are ever generated (<c:catAx> with id 2094734554 and <c:valAx> with id 2094734552). The third id, 2094734556 (the AXIS_ID_SERIES_PRIMARY constant), is never backed by a <c:serAx> element unless the chart type is BAR3D.
This is a dangling axis reference, invalid per the OOXML chart schema. LibreOffice ignores it silently, but PowerPoint rejects the file and shows "We found a problem with some content... repair" on every open. PowerPoint's own repair simply strips the extra axId.
This affects every deck containing at least one 2D bar or line chart — not just combo/secondary-axis charts.
Root cause — in dist/pptxgen.cjs.js (same in .es.js / .bundle.js):
// lines 64–68
const AXIS_ID_VALUE_PRIMARY = '2094734552';
const AXIS_ID_CATEGORY_PRIMARY = '2094734554';
const AXIS_ID_SERIES_PRIMARY = '2094734556';
BAR, BAR3D, and LINE share the same switch-case branch when building the plot area. The axId list is written unconditionally there (~line 3846):
strXml += `<c:axId val="${catAxisId}"/><c:axId val="${valAxisId}"/><c:axId val="${AXIS_ID_SERIES_PRIMARY}"/>`;
But the corresponding <c:serAx> element — the only thing that would make the third axId valid — is correctly gated to BAR3D only, elsewhere in the same file (~line 3481):
if (rel.opts._type === CHART_TYPE.BAR3D) {
strXml += makeSerAxis(rel.opts, AXIS_ID_SERIES_PRIMARY, AXIS_ID_VALUE_PRIMARY);
}
The axId-emission line doesn't check _type the way makeSerAxis's caller does, so the reference and the definition fall out of sync for any non-3D bar chart (and for line charts, going through the same branch).
Suggested fix:
strXml += `<c:axId val="${catAxisId}"/><c:axId val="${valAxisId}"/>`;
if (chartType === CHART_TYPE.BAR3D) {
strXml += `<c:axId val="${AXIS_ID_SERIES_PRIMARY}"/>`;
}
Steps to Reproduce
const pptxgen = require("pptxgenjs");
let pres = new pptxgen();
let slide = pres.addSlide();
slide.addChart(pres.ChartType.bar, [
{
name: "Series 1",
labels: ["2023", "2024", "2025"],
values: [10, 20, 30],
},
], { x: 1, y: 1, w: 6, h: 4 });
pres.writeFile({ fileName: "repro.pptx" });
- Run the snippet above.
- Open
repro.pptxin PowerPoint (desktop or online) → "repair" dialog appears. - Open the same file in LibreOffice Impress → opens without warning.
- Unzip the pptx and inspect
ppt/charts/chart1.xml: 3<c:axId>under<c:barChart>, but only 1<c:catAx>and 1<c:valAx>in the whole file — no<c:serAx>.
Workaround for anyone hitting this before a fix ships: post-process the generated .pptx (it's a zip) after writeFile()/write(), stripping <c:axId val="2094734556"/> from any ppt/charts/chart*.xml that has no matching <c:serAx> in the same file. Happy to share the small Node/JSZip snippet if useful.
- Dominant language
- TypeScript
- Stars
- 6.2k
- Forks
- 953
- PR merge metrics
- No merged PRs in 30d
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from gitbrent/PptxGenJS
-
Difficulty 1/5 Under an hour Newbie friendliness 88/100
-
Difficulty 1/5 Under an hour Newbie friendliness 90/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
-
Difficulty 1/5 Under an hour Newbie friendliness 72/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
All issues in gitbrent/PptxGenJS
Similar issues
-
calcite-components needs triage refactor
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
Esri/calcite-design-system#15203 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 91/100
-
community first-timers-only good first issue hacktoberfest help wanted low hanging fruit up-for-grabs
Difficulty 1/5 Under an hour Newbie friendliness 95/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
Automattic/studio#4908 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 90/100