@rowsncolumns/toolkit 24.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +100 -0
- package/Readme.md +27 -0
- package/dist/cjs/autofilter-condition.d.ts +43 -0
- package/dist/cjs/autofilter-condition.d.ts.map +1 -0
- package/dist/cjs/autofilter-condition.js +155 -0
- package/dist/cjs/csv-export.d.ts +49 -0
- package/dist/cjs/csv-export.d.ts.map +1 -0
- package/dist/cjs/csv-export.js +142 -0
- package/dist/cjs/csv-import-worker.d.ts +16 -0
- package/dist/cjs/csv-import-worker.d.ts.map +1 -0
- package/dist/cjs/csv-import-worker.js +60 -0
- package/dist/cjs/csv-import.d.ts +38 -0
- package/dist/cjs/csv-import.d.ts.map +1 -0
- package/dist/cjs/csv-import.js +166 -0
- package/dist/cjs/csv-parser/helpers.d.ts +14 -0
- package/dist/cjs/csv-parser/helpers.d.ts.map +1 -0
- package/dist/cjs/csv-parser/helpers.js +145 -0
- package/dist/cjs/csv-parser/types.d.ts +66 -0
- package/dist/cjs/csv-parser/types.d.ts.map +1 -0
- package/dist/cjs/csv-parser/types.js +14 -0
- package/dist/cjs/csv-parser/worker.d.ts +2 -0
- package/dist/cjs/csv-parser/worker.d.ts.map +1 -0
- package/dist/cjs/csv-parser/worker.js +200 -0
- package/dist/cjs/excel-export.d.ts +11 -0
- package/dist/cjs/excel-export.d.ts.map +1 -0
- package/dist/cjs/excel-export.js +22 -0
- package/dist/cjs/excel-import-session.d.ts +51 -0
- package/dist/cjs/excel-import-session.d.ts.map +1 -0
- package/dist/cjs/excel-import-session.js +307 -0
- package/dist/cjs/excel-import-worker.d.ts +7 -0
- package/dist/cjs/excel-import-worker.d.ts.map +1 -0
- package/dist/cjs/excel-import-worker.js +119 -0
- package/dist/cjs/excel-parser/builtin-numfmts.d.ts +24 -0
- package/dist/cjs/excel-parser/builtin-numfmts.d.ts.map +1 -0
- package/dist/cjs/excel-parser/builtin-numfmts.js +63 -0
- package/dist/cjs/excel-parser/cfb-decryptor.d.ts +53 -0
- package/dist/cjs/excel-parser/cfb-decryptor.d.ts.map +1 -0
- package/dist/cjs/excel-parser/cfb-decryptor.js +553 -0
- package/dist/cjs/excel-parser/cfb-encryptor.d.ts +23 -0
- package/dist/cjs/excel-parser/cfb-encryptor.d.ts.map +1 -0
- package/dist/cjs/excel-parser/cfb-encryptor.js +200 -0
- package/dist/cjs/excel-parser/dv-cell-stamp.d.ts +29 -0
- package/dist/cjs/excel-parser/dv-cell-stamp.d.ts.map +1 -0
- package/dist/cjs/excel-parser/dv-cell-stamp.js +239 -0
- package/dist/cjs/excel-parser/helpers.d.ts +28 -0
- package/dist/cjs/excel-parser/helpers.d.ts.map +1 -0
- package/dist/cjs/excel-parser/helpers.js +188 -0
- package/dist/cjs/excel-parser/interface.d.ts +179 -0
- package/dist/cjs/excel-parser/interface.d.ts.map +1 -0
- package/dist/cjs/excel-parser/interface.js +1 -0
- package/dist/cjs/excel-parser/plugins/base/index.d.ts +31 -0
- package/dist/cjs/excel-parser/plugins/base/index.d.ts.map +1 -0
- package/dist/cjs/excel-parser/plugins/base/index.js +101 -0
- package/dist/cjs/excel-parser/plugins/ods/conditional-formatting.d.ts +16 -0
- package/dist/cjs/excel-parser/plugins/ods/conditional-formatting.d.ts.map +1 -0
- package/dist/cjs/excel-parser/plugins/ods/conditional-formatting.js +488 -0
- package/dist/cjs/excel-parser/plugins/ods/data-validations.d.ts +15 -0
- package/dist/cjs/excel-parser/plugins/ods/data-validations.d.ts.map +1 -0
- package/dist/cjs/excel-parser/plugins/ods/data-validations.js +353 -0
- package/dist/cjs/excel-parser/plugins/ods/formula.d.ts +8 -0
- package/dist/cjs/excel-parser/plugins/ods/formula.d.ts.map +1 -0
- package/dist/cjs/excel-parser/plugins/ods/formula.js +82 -0
- package/dist/cjs/excel-parser/plugins/ods/index.d.ts +122 -0
- package/dist/cjs/excel-parser/plugins/ods/index.d.ts.map +1 -0
- package/dist/cjs/excel-parser/plugins/ods/index.js +3642 -0
- package/dist/cjs/excel-parser/plugins/ods/sparklines.d.ts +25 -0
- package/dist/cjs/excel-parser/plugins/ods/sparklines.d.ts.map +1 -0
- package/dist/cjs/excel-parser/plugins/ods/sparklines.js +221 -0
- package/dist/cjs/excel-parser/plugins/ods/styles.d.ts +60 -0
- package/dist/cjs/excel-parser/plugins/ods/styles.d.ts.map +1 -0
- package/dist/cjs/excel-parser/plugins/ods/styles.js +808 -0
- package/dist/cjs/excel-parser/plugins/ods/types.d.ts +7 -0
- package/dist/cjs/excel-parser/plugins/ods/types.d.ts.map +1 -0
- package/dist/cjs/excel-parser/plugins/ods/types.js +1 -0
- package/dist/cjs/excel-parser/plugins/xls/index.d.ts +5 -0
- package/dist/cjs/excel-parser/plugins/xls/index.d.ts.map +1 -0
- package/dist/cjs/excel-parser/plugins/xls/index.js +19 -0
- package/dist/cjs/excel-parser/plugins/xlsb/biff-record-reader.d.ts +13 -0
- package/dist/cjs/excel-parser/plugins/xlsb/biff-record-reader.d.ts.map +1 -0
- package/dist/cjs/excel-parser/plugins/xlsb/biff-record-reader.js +49 -0
- package/dist/cjs/excel-parser/plugins/xlsb/index.d.ts +117 -0
- package/dist/cjs/excel-parser/plugins/xlsb/index.d.ts.map +1 -0
- package/dist/cjs/excel-parser/plugins/xlsb/index.js +2972 -0
- package/dist/cjs/excel-parser/plugins/xlsb/rgce-parser.d.ts +18 -0
- package/dist/cjs/excel-parser/plugins/xlsb/rgce-parser.d.ts.map +1 -0
- package/dist/cjs/excel-parser/plugins/xlsb/rgce-parser.js +527 -0
- package/dist/cjs/excel-parser/plugins/xlsm/index.d.ts +5 -0
- package/dist/cjs/excel-parser/plugins/xlsm/index.d.ts.map +1 -0
- package/dist/cjs/excel-parser/plugins/xlsm/index.js +10 -0
- package/dist/cjs/excel-parser/plugins/xlsx/charts.d.ts +60 -0
- package/dist/cjs/excel-parser/plugins/xlsx/charts.d.ts.map +1 -0
- package/dist/cjs/excel-parser/plugins/xlsx/charts.js +2178 -0
- package/dist/cjs/excel-parser/plugins/xlsx/conditional-formatting.d.ts +18 -0
- package/dist/cjs/excel-parser/plugins/xlsx/conditional-formatting.d.ts.map +1 -0
- package/dist/cjs/excel-parser/plugins/xlsx/conditional-formatting.js +620 -0
- package/dist/cjs/excel-parser/plugins/xlsx/data-validations.d.ts +4 -0
- package/dist/cjs/excel-parser/plugins/xlsx/data-validations.d.ts.map +1 -0
- package/dist/cjs/excel-parser/plugins/xlsx/data-validations.js +515 -0
- package/dist/cjs/excel-parser/plugins/xlsx/drawing.d.ts +39 -0
- package/dist/cjs/excel-parser/plugins/xlsx/drawing.d.ts.map +1 -0
- package/dist/cjs/excel-parser/plugins/xlsx/drawing.js +941 -0
- package/dist/cjs/excel-parser/plugins/xlsx/index.d.ts +320 -0
- package/dist/cjs/excel-parser/plugins/xlsx/index.d.ts.map +1 -0
- package/dist/cjs/excel-parser/plugins/xlsx/index.js +6056 -0
- package/dist/cjs/excel-parser/plugins/xlsx/numfmt.d.ts +2 -0
- package/dist/cjs/excel-parser/plugins/xlsx/numfmt.d.ts.map +1 -0
- package/dist/cjs/excel-parser/plugins/xlsx/numfmt.js +3 -0
- package/dist/cjs/excel-parser/plugins/xlsx/pivots.d.ts +40 -0
- package/dist/cjs/excel-parser/plugins/xlsx/pivots.d.ts.map +1 -0
- package/dist/cjs/excel-parser/plugins/xlsx/pivots.js +342 -0
- package/dist/cjs/excel-parser/plugins/xlsx/relationships.d.ts +8 -0
- package/dist/cjs/excel-parser/plugins/xlsx/relationships.d.ts.map +1 -0
- package/dist/cjs/excel-parser/plugins/xlsx/relationships.js +26 -0
- package/dist/cjs/excel-parser/plugins/xlsx/sheet-views.d.ts +26 -0
- package/dist/cjs/excel-parser/plugins/xlsx/sheet-views.d.ts.map +1 -0
- package/dist/cjs/excel-parser/plugins/xlsx/sheet-views.js +59 -0
- package/dist/cjs/excel-parser/plugins/xlsx/styles.d.ts +44 -0
- package/dist/cjs/excel-parser/plugins/xlsx/styles.d.ts.map +1 -0
- package/dist/cjs/excel-parser/plugins/xlsx/styles.js +1377 -0
- package/dist/cjs/excel-parser/plugins/xlsx/theme.d.ts +50 -0
- package/dist/cjs/excel-parser/plugins/xlsx/theme.d.ts.map +1 -0
- package/dist/cjs/excel-parser/plugins/xlsx/theme.js +150 -0
- package/dist/cjs/excel-parser/plugins/xlsx/threaded-comments.d.ts +47 -0
- package/dist/cjs/excel-parser/plugins/xlsx/threaded-comments.d.ts.map +1 -0
- package/dist/cjs/excel-parser/plugins/xlsx/threaded-comments.js +141 -0
- package/dist/cjs/excel-parser/plugins/xlsx/value-type-detection.d.ts +44 -0
- package/dist/cjs/excel-parser/plugins/xlsx/value-type-detection.d.ts.map +1 -0
- package/dist/cjs/excel-parser/plugins/xlsx/value-type-detection.js +407 -0
- package/dist/cjs/excel-parser/registry.d.ts +5 -0
- package/dist/cjs/excel-parser/registry.d.ts.map +1 -0
- package/dist/cjs/excel-parser/registry.js +21 -0
- package/dist/cjs/excel-parser/style-registry.d.ts +51 -0
- package/dist/cjs/excel-parser/style-registry.d.ts.map +1 -0
- package/dist/cjs/excel-parser/style-registry.js +175 -0
- package/dist/cjs/excel-parser/theme-default.d.ts +3 -0
- package/dist/cjs/excel-parser/theme-default.d.ts.map +1 -0
- package/dist/cjs/excel-parser/theme-default.js +19 -0
- package/dist/cjs/excel-parser/types.d.ts +365 -0
- package/dist/cjs/excel-parser/types.d.ts.map +1 -0
- package/dist/cjs/excel-parser/types.js +59 -0
- package/dist/cjs/excel-parser/utils.d.ts +6 -0
- package/dist/cjs/excel-parser/utils.d.ts.map +1 -0
- package/dist/cjs/excel-parser/utils.js +30 -0
- package/dist/cjs/excel-parser/workbook.d.ts +51 -0
- package/dist/cjs/excel-parser/workbook.d.ts.map +1 -0
- package/dist/cjs/excel-parser/workbook.js +317 -0
- package/dist/cjs/excel-parser/worker.d.ts +2 -0
- package/dist/cjs/excel-parser/worker.d.ts.map +1 -0
- package/dist/cjs/excel-parser/worker.js +1149 -0
- package/dist/cjs/excel-parser/zip-parser-streaming.d.ts +13 -0
- package/dist/cjs/excel-parser/zip-parser-streaming.d.ts.map +1 -0
- package/dist/cjs/excel-parser/zip-parser-streaming.js +200 -0
- package/dist/cjs/excel-parser/zip-parser.d.ts +11 -0
- package/dist/cjs/excel-parser/zip-parser.d.ts.map +1 -0
- package/dist/cjs/excel-parser/zip-parser.js +49 -0
- package/dist/cjs/exporter/invalid-data-validation.d.ts +19 -0
- package/dist/cjs/exporter/invalid-data-validation.d.ts.map +1 -0
- package/dist/cjs/exporter/invalid-data-validation.js +39 -0
- package/dist/cjs/exporter/ods/ods-export.d.ts +26 -0
- package/dist/cjs/exporter/ods/ods-export.d.ts.map +1 -0
- package/dist/cjs/exporter/ods/ods-export.js +3714 -0
- package/dist/cjs/exporter/ods/sparkline-builder.d.ts +33 -0
- package/dist/cjs/exporter/ods/sparkline-builder.d.ts.map +1 -0
- package/dist/cjs/exporter/ods/sparkline-builder.js +221 -0
- package/dist/cjs/exporter/xlsx/chart-builder.d.ts +3 -0
- package/dist/cjs/exporter/xlsx/chart-builder.d.ts.map +1 -0
- package/dist/cjs/exporter/xlsx/chart-builder.js +1901 -0
- package/dist/cjs/exporter/xlsx/chart-templates.d.ts +1781 -0
- package/dist/cjs/exporter/xlsx/chart-templates.d.ts.map +1 -0
- package/dist/cjs/exporter/xlsx/chart-templates.js +1798 -0
- package/dist/cjs/exporter/xlsx/future-functions.d.ts +10 -0
- package/dist/cjs/exporter/xlsx/future-functions.d.ts.map +1 -0
- package/dist/cjs/exporter/xlsx/future-functions.js +264 -0
- package/dist/cjs/exporter/xlsx/pivot-builder.d.ts +58 -0
- package/dist/cjs/exporter/xlsx/pivot-builder.d.ts.map +1 -0
- package/dist/cjs/exporter/xlsx/pivot-builder.js +277 -0
- package/dist/cjs/exporter/xlsx/power-query-builder.d.ts +26 -0
- package/dist/cjs/exporter/xlsx/power-query-builder.d.ts.map +1 -0
- package/dist/cjs/exporter/xlsx/power-query-builder.js +306 -0
- package/dist/cjs/exporter/xlsx/slicer-builder.d.ts +11 -0
- package/dist/cjs/exporter/xlsx/slicer-builder.d.ts.map +1 -0
- package/dist/cjs/exporter/xlsx/slicer-builder.js +87 -0
- package/dist/cjs/exporter/xlsx/sparkline-builder.d.ts +61 -0
- package/dist/cjs/exporter/xlsx/sparkline-builder.d.ts.map +1 -0
- package/dist/cjs/exporter/xlsx/sparkline-builder.js +489 -0
- package/dist/cjs/exporter/xlsx/style-builder.d.ts +93 -0
- package/dist/cjs/exporter/xlsx/style-builder.d.ts.map +1 -0
- package/dist/cjs/exporter/xlsx/style-builder.js +813 -0
- package/dist/cjs/exporter/xlsx/threaded-comments-builder.d.ts +58 -0
- package/dist/cjs/exporter/xlsx/threaded-comments-builder.d.ts.map +1 -0
- package/dist/cjs/exporter/xlsx/threaded-comments-builder.js +189 -0
- package/dist/cjs/exporter/xlsx/xlsx-export.d.ts +121 -0
- package/dist/cjs/exporter/xlsx/xlsx-export.d.ts.map +1 -0
- package/dist/cjs/exporter/xlsx/xlsx-export.js +4596 -0
- package/dist/cjs/helpers/theme-xml-generator.d.ts +8 -0
- package/dist/cjs/helpers/theme-xml-generator.d.ts.map +1 -0
- package/dist/cjs/helpers/theme-xml-generator.js +33 -0
- package/dist/cjs/helpers.d.ts +34 -0
- package/dist/cjs/helpers.d.ts.map +1 -0
- package/dist/cjs/helpers.js +189 -0
- package/dist/cjs/index.d.ts +16 -0
- package/dist/cjs/index.d.ts.map +1 -0
- package/dist/cjs/index.js +15 -0
- package/dist/cjs/indexed-colors.d.ts +2 -0
- package/dist/cjs/indexed-colors.d.ts.map +1 -0
- package/dist/cjs/indexed-colors.js +75 -0
- package/dist/cjs/ods-export.d.ts +24 -0
- package/dist/cjs/ods-export.d.ts.map +1 -0
- package/dist/cjs/ods-export.js +23 -0
- package/dist/cjs/parse.d.ts +24 -0
- package/dist/cjs/parse.d.ts.map +1 -0
- package/dist/cjs/parse.js +68 -0
- package/dist/cjs/power-query.d.ts +41 -0
- package/dist/cjs/power-query.d.ts.map +1 -0
- package/dist/cjs/power-query.js +22 -0
- package/dist/cjs/server.d.ts +9 -0
- package/dist/cjs/server.d.ts.map +1 -0
- package/dist/cjs/server.js +8 -0
- package/dist/cjs/theme1.d.ts +3 -0
- package/dist/cjs/theme1.d.ts.map +1 -0
- package/dist/cjs/theme1.js +2 -0
- package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -0
- package/dist/cjs/types.d.ts +14 -0
- package/dist/cjs/types.d.ts.map +1 -0
- package/dist/cjs/types.js +14 -0
- package/dist/cjs/vitest.config.d.ts +3 -0
- package/dist/cjs/vitest.config.d.ts.map +1 -0
- package/dist/cjs/vitest.config.js +16 -0
- package/dist/esm/autofilter-condition.d.ts +43 -0
- package/dist/esm/autofilter-condition.d.ts.map +1 -0
- package/dist/esm/autofilter-condition.js +145 -0
- package/dist/esm/csv-export.d.ts +49 -0
- package/dist/esm/csv-export.d.ts.map +1 -0
- package/dist/esm/csv-export.js +126 -0
- package/dist/esm/csv-import-worker.d.ts +16 -0
- package/dist/esm/csv-import-worker.d.ts.map +1 -0
- package/dist/esm/csv-import-worker.js +60 -0
- package/dist/esm/csv-import.d.ts +38 -0
- package/dist/esm/csv-import.d.ts.map +1 -0
- package/dist/esm/csv-import.js +132 -0
- package/dist/esm/csv-parser/helpers.d.ts +14 -0
- package/dist/esm/csv-parser/helpers.d.ts.map +1 -0
- package/dist/esm/csv-parser/helpers.js +0 -0
- package/dist/esm/csv-parser/types.d.ts +66 -0
- package/dist/esm/csv-parser/types.d.ts.map +1 -0
- package/dist/esm/csv-parser/types.js +14 -0
- package/dist/esm/csv-parser/worker.d.ts +2 -0
- package/dist/esm/csv-parser/worker.d.ts.map +1 -0
- package/dist/esm/csv-parser/worker.js +154 -0
- package/dist/esm/excel-export.d.ts +11 -0
- package/dist/esm/excel-export.d.ts.map +1 -0
- package/dist/esm/excel-export.js +13 -0
- package/dist/esm/excel-import-session.d.ts +51 -0
- package/dist/esm/excel-import-session.d.ts.map +1 -0
- package/dist/esm/excel-import-session.js +255 -0
- package/dist/esm/excel-import-worker.d.ts +7 -0
- package/dist/esm/excel-import-worker.d.ts.map +1 -0
- package/dist/esm/excel-import-worker.js +116 -0
- package/dist/esm/excel-parser/builtin-numfmts.d.ts +24 -0
- package/dist/esm/excel-parser/builtin-numfmts.d.ts.map +1 -0
- package/dist/esm/excel-parser/builtin-numfmts.js +59 -0
- package/dist/esm/excel-parser/cfb-decryptor.d.ts +53 -0
- package/dist/esm/excel-parser/cfb-decryptor.d.ts.map +1 -0
- package/dist/esm/excel-parser/cfb-decryptor.js +493 -0
- package/dist/esm/excel-parser/cfb-encryptor.d.ts +23 -0
- package/dist/esm/excel-parser/cfb-encryptor.d.ts.map +1 -0
- package/dist/esm/excel-parser/cfb-encryptor.js +181 -0
- package/dist/esm/excel-parser/dv-cell-stamp.d.ts +29 -0
- package/dist/esm/excel-parser/dv-cell-stamp.d.ts.map +1 -0
- package/dist/esm/excel-parser/dv-cell-stamp.js +155 -0
- package/dist/esm/excel-parser/helpers.d.ts +28 -0
- package/dist/esm/excel-parser/helpers.d.ts.map +1 -0
- package/dist/esm/excel-parser/helpers.js +160 -0
- package/dist/esm/excel-parser/interface.d.ts +179 -0
- package/dist/esm/excel-parser/interface.d.ts.map +1 -0
- package/dist/esm/excel-parser/interface.js +1 -0
- package/dist/esm/excel-parser/plugins/base/index.d.ts +31 -0
- package/dist/esm/excel-parser/plugins/base/index.d.ts.map +1 -0
- package/dist/esm/excel-parser/plugins/base/index.js +64 -0
- package/dist/esm/excel-parser/plugins/ods/conditional-formatting.d.ts +16 -0
- package/dist/esm/excel-parser/plugins/ods/conditional-formatting.d.ts.map +1 -0
- package/dist/esm/excel-parser/plugins/ods/conditional-formatting.js +405 -0
- package/dist/esm/excel-parser/plugins/ods/data-validations.d.ts +15 -0
- package/dist/esm/excel-parser/plugins/ods/data-validations.d.ts.map +1 -0
- package/dist/esm/excel-parser/plugins/ods/data-validations.js +331 -0
- package/dist/esm/excel-parser/plugins/ods/formula.d.ts +8 -0
- package/dist/esm/excel-parser/plugins/ods/formula.d.ts.map +1 -0
- package/dist/esm/excel-parser/plugins/ods/formula.js +82 -0
- package/dist/esm/excel-parser/plugins/ods/index.d.ts +122 -0
- package/dist/esm/excel-parser/plugins/ods/index.d.ts.map +1 -0
- package/dist/esm/excel-parser/plugins/ods/index.js +2896 -0
- package/dist/esm/excel-parser/plugins/ods/sparklines.d.ts +25 -0
- package/dist/esm/excel-parser/plugins/ods/sparklines.d.ts.map +1 -0
- package/dist/esm/excel-parser/plugins/ods/sparklines.js +188 -0
- package/dist/esm/excel-parser/plugins/ods/styles.d.ts +60 -0
- package/dist/esm/excel-parser/plugins/ods/styles.d.ts.map +1 -0
- package/dist/esm/excel-parser/plugins/ods/styles.js +732 -0
- package/dist/esm/excel-parser/plugins/ods/types.d.ts +7 -0
- package/dist/esm/excel-parser/plugins/ods/types.d.ts.map +1 -0
- package/dist/esm/excel-parser/plugins/ods/types.js +1 -0
- package/dist/esm/excel-parser/plugins/xls/index.d.ts +5 -0
- package/dist/esm/excel-parser/plugins/xls/index.d.ts.map +1 -0
- package/dist/esm/excel-parser/plugins/xls/index.js +7 -0
- package/dist/esm/excel-parser/plugins/xlsb/biff-record-reader.d.ts +13 -0
- package/dist/esm/excel-parser/plugins/xlsb/biff-record-reader.d.ts.map +1 -0
- package/dist/esm/excel-parser/plugins/xlsb/biff-record-reader.js +48 -0
- package/dist/esm/excel-parser/plugins/xlsb/index.d.ts +117 -0
- package/dist/esm/excel-parser/plugins/xlsb/index.d.ts.map +1 -0
- package/dist/esm/excel-parser/plugins/xlsb/index.js +2339 -0
- package/dist/esm/excel-parser/plugins/xlsb/rgce-parser.d.ts +18 -0
- package/dist/esm/excel-parser/plugins/xlsb/rgce-parser.d.ts.map +1 -0
- package/dist/esm/excel-parser/plugins/xlsb/rgce-parser.js +522 -0
- package/dist/esm/excel-parser/plugins/xlsm/index.d.ts +5 -0
- package/dist/esm/excel-parser/plugins/xlsm/index.d.ts.map +1 -0
- package/dist/esm/excel-parser/plugins/xlsm/index.js +6 -0
- package/dist/esm/excel-parser/plugins/xlsx/charts.d.ts +60 -0
- package/dist/esm/excel-parser/plugins/xlsx/charts.d.ts.map +1 -0
- package/dist/esm/excel-parser/plugins/xlsx/charts.js +2036 -0
- package/dist/esm/excel-parser/plugins/xlsx/conditional-formatting.d.ts +18 -0
- package/dist/esm/excel-parser/plugins/xlsx/conditional-formatting.d.ts.map +1 -0
- package/dist/esm/excel-parser/plugins/xlsx/conditional-formatting.js +621 -0
- package/dist/esm/excel-parser/plugins/xlsx/data-validations.d.ts +4 -0
- package/dist/esm/excel-parser/plugins/xlsx/data-validations.d.ts.map +1 -0
- package/dist/esm/excel-parser/plugins/xlsx/data-validations.js +493 -0
- package/dist/esm/excel-parser/plugins/xlsx/drawing.d.ts +39 -0
- package/dist/esm/excel-parser/plugins/xlsx/drawing.d.ts.map +1 -0
- package/dist/esm/excel-parser/plugins/xlsx/drawing.js +905 -0
- package/dist/esm/excel-parser/plugins/xlsx/index.d.ts +320 -0
- package/dist/esm/excel-parser/plugins/xlsx/index.d.ts.map +1 -0
- package/dist/esm/excel-parser/plugins/xlsx/index.js +4654 -0
- package/dist/esm/excel-parser/plugins/xlsx/numfmt.d.ts +2 -0
- package/dist/esm/excel-parser/plugins/xlsx/numfmt.d.ts.map +1 -0
- package/dist/esm/excel-parser/plugins/xlsx/numfmt.js +3 -0
- package/dist/esm/excel-parser/plugins/xlsx/pivots.d.ts +40 -0
- package/dist/esm/excel-parser/plugins/xlsx/pivots.d.ts.map +1 -0
- package/dist/esm/excel-parser/plugins/xlsx/pivots.js +254 -0
- package/dist/esm/excel-parser/plugins/xlsx/relationships.d.ts +8 -0
- package/dist/esm/excel-parser/plugins/xlsx/relationships.d.ts.map +1 -0
- package/dist/esm/excel-parser/plugins/xlsx/relationships.js +13 -0
- package/dist/esm/excel-parser/plugins/xlsx/sheet-views.d.ts +26 -0
- package/dist/esm/excel-parser/plugins/xlsx/sheet-views.d.ts.map +1 -0
- package/dist/esm/excel-parser/plugins/xlsx/sheet-views.js +64 -0
- package/dist/esm/excel-parser/plugins/xlsx/styles.d.ts +44 -0
- package/dist/esm/excel-parser/plugins/xlsx/styles.d.ts.map +1 -0
- package/dist/esm/excel-parser/plugins/xlsx/styles.js +1365 -0
- package/dist/esm/excel-parser/plugins/xlsx/theme.d.ts +50 -0
- package/dist/esm/excel-parser/plugins/xlsx/theme.d.ts.map +1 -0
- package/dist/esm/excel-parser/plugins/xlsx/theme.js +127 -0
- package/dist/esm/excel-parser/plugins/xlsx/threaded-comments.d.ts +47 -0
- package/dist/esm/excel-parser/plugins/xlsx/threaded-comments.d.ts.map +1 -0
- package/dist/esm/excel-parser/plugins/xlsx/threaded-comments.js +103 -0
- package/dist/esm/excel-parser/plugins/xlsx/value-type-detection.d.ts +44 -0
- package/dist/esm/excel-parser/plugins/xlsx/value-type-detection.d.ts.map +1 -0
- package/dist/esm/excel-parser/plugins/xlsx/value-type-detection.js +399 -0
- package/dist/esm/excel-parser/registry.d.ts +5 -0
- package/dist/esm/excel-parser/registry.d.ts.map +1 -0
- package/dist/esm/excel-parser/registry.js +20 -0
- package/dist/esm/excel-parser/style-registry.d.ts +51 -0
- package/dist/esm/excel-parser/style-registry.d.ts.map +1 -0
- package/dist/esm/excel-parser/style-registry.js +163 -0
- package/dist/esm/excel-parser/theme-default.d.ts +3 -0
- package/dist/esm/excel-parser/theme-default.d.ts.map +1 -0
- package/dist/esm/excel-parser/theme-default.js +19 -0
- package/dist/esm/excel-parser/types.d.ts +365 -0
- package/dist/esm/excel-parser/types.d.ts.map +1 -0
- package/dist/esm/excel-parser/types.js +59 -0
- package/dist/esm/excel-parser/utils.d.ts +6 -0
- package/dist/esm/excel-parser/utils.d.ts.map +1 -0
- package/dist/esm/excel-parser/utils.js +25 -0
- package/dist/esm/excel-parser/workbook.d.ts +51 -0
- package/dist/esm/excel-parser/workbook.d.ts.map +1 -0
- package/dist/esm/excel-parser/workbook.js +192 -0
- package/dist/esm/excel-parser/worker.d.ts +2 -0
- package/dist/esm/excel-parser/worker.d.ts.map +1 -0
- package/dist/esm/excel-parser/worker.js +862 -0
- package/dist/esm/excel-parser/zip-parser-streaming.d.ts +13 -0
- package/dist/esm/excel-parser/zip-parser-streaming.d.ts.map +1 -0
- package/dist/esm/excel-parser/zip-parser-streaming.js +119 -0
- package/dist/esm/excel-parser/zip-parser.d.ts +11 -0
- package/dist/esm/excel-parser/zip-parser.d.ts.map +1 -0
- package/dist/esm/excel-parser/zip-parser.js +43 -0
- package/dist/esm/exporter/invalid-data-validation.d.ts +19 -0
- package/dist/esm/exporter/invalid-data-validation.d.ts.map +1 -0
- package/dist/esm/exporter/invalid-data-validation.js +37 -0
- package/dist/esm/exporter/ods/ods-export.d.ts +26 -0
- package/dist/esm/exporter/ods/ods-export.d.ts.map +1 -0
- package/dist/esm/exporter/ods/ods-export.js +3238 -0
- package/dist/esm/exporter/ods/sparkline-builder.d.ts +33 -0
- package/dist/esm/exporter/ods/sparkline-builder.d.ts.map +1 -0
- package/dist/esm/exporter/ods/sparkline-builder.js +165 -0
- package/dist/esm/exporter/xlsx/chart-builder.d.ts +3 -0
- package/dist/esm/exporter/xlsx/chart-builder.d.ts.map +1 -0
- package/dist/esm/exporter/xlsx/chart-builder.js +1805 -0
- package/dist/esm/exporter/xlsx/chart-templates.d.ts +1781 -0
- package/dist/esm/exporter/xlsx/chart-templates.d.ts.map +1 -0
- package/dist/esm/exporter/xlsx/chart-templates.js +1798 -0
- package/dist/esm/exporter/xlsx/future-functions.d.ts +10 -0
- package/dist/esm/exporter/xlsx/future-functions.d.ts.map +1 -0
- package/dist/esm/exporter/xlsx/future-functions.js +264 -0
- package/dist/esm/exporter/xlsx/pivot-builder.d.ts +58 -0
- package/dist/esm/exporter/xlsx/pivot-builder.d.ts.map +1 -0
- package/dist/esm/exporter/xlsx/pivot-builder.js +230 -0
- package/dist/esm/exporter/xlsx/power-query-builder.d.ts +26 -0
- package/dist/esm/exporter/xlsx/power-query-builder.d.ts.map +1 -0
- package/dist/esm/exporter/xlsx/power-query-builder.js +257 -0
- package/dist/esm/exporter/xlsx/slicer-builder.d.ts +11 -0
- package/dist/esm/exporter/xlsx/slicer-builder.d.ts.map +1 -0
- package/dist/esm/exporter/xlsx/slicer-builder.js +84 -0
- package/dist/esm/exporter/xlsx/sparkline-builder.d.ts +61 -0
- package/dist/esm/exporter/xlsx/sparkline-builder.d.ts.map +1 -0
- package/dist/esm/exporter/xlsx/sparkline-builder.js +437 -0
- package/dist/esm/exporter/xlsx/style-builder.d.ts +93 -0
- package/dist/esm/exporter/xlsx/style-builder.d.ts.map +1 -0
- package/dist/esm/exporter/xlsx/style-builder.js +795 -0
- package/dist/esm/exporter/xlsx/threaded-comments-builder.d.ts +58 -0
- package/dist/esm/exporter/xlsx/threaded-comments-builder.d.ts.map +1 -0
- package/dist/esm/exporter/xlsx/threaded-comments-builder.js +175 -0
- package/dist/esm/exporter/xlsx/xlsx-export.d.ts +121 -0
- package/dist/esm/exporter/xlsx/xlsx-export.d.ts.map +1 -0
- package/dist/esm/exporter/xlsx/xlsx-export.js +4062 -0
- package/dist/esm/helpers/theme-xml-generator.d.ts +8 -0
- package/dist/esm/helpers/theme-xml-generator.d.ts.map +1 -0
- package/dist/esm/helpers/theme-xml-generator.js +33 -0
- package/dist/esm/helpers.d.ts +34 -0
- package/dist/esm/helpers.d.ts.map +1 -0
- package/dist/esm/helpers.js +182 -0
- package/dist/esm/index.d.ts +16 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +15 -0
- package/dist/esm/indexed-colors.d.ts +2 -0
- package/dist/esm/indexed-colors.d.ts.map +1 -0
- package/dist/esm/indexed-colors.js +75 -0
- package/dist/esm/ods-export.d.ts +24 -0
- package/dist/esm/ods-export.d.ts.map +1 -0
- package/dist/esm/ods-export.js +12 -0
- package/dist/esm/parse.d.ts +24 -0
- package/dist/esm/parse.d.ts.map +1 -0
- package/dist/esm/parse.js +55 -0
- package/dist/esm/power-query.d.ts +41 -0
- package/dist/esm/power-query.d.ts.map +1 -0
- package/dist/esm/power-query.js +19 -0
- package/dist/esm/server.d.ts +9 -0
- package/dist/esm/server.d.ts.map +1 -0
- package/dist/esm/server.js +8 -0
- package/dist/esm/theme1.d.ts +3 -0
- package/dist/esm/theme1.d.ts.map +1 -0
- package/dist/esm/theme1.js +2 -0
- package/dist/esm/tsconfig.esm.tsbuildinfo +1 -0
- package/dist/esm/types.d.ts +14 -0
- package/dist/esm/types.d.ts.map +1 -0
- package/dist/esm/types.js +14 -0
- package/dist/esm/vitest.config.d.ts +3 -0
- package/dist/esm/vitest.config.d.ts.map +1 -0
- package/dist/esm/vitest.config.js +16 -0
- package/package.json +62 -0
- package/xlsx.d.ts +52 -0
|
@@ -0,0 +1,1901 @@
|
|
|
1
|
+
import { __assign, __read, __spreadArray, __values } from "tslib";
|
|
2
|
+
import { cellRangeToAddress, sanitizeSheetName } from "@rowsncolumns/utils";
|
|
3
|
+
import { XMLBuilder } from "fast-xml-parser";
|
|
4
|
+
import { area_series, bubble_series, chart_template, column_json, column_series, donut_json, line_series, scatter_json, scatter_series, static_title, } from "./chart-templates";
|
|
5
|
+
var XML_DECLARATION = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>";
|
|
6
|
+
var INVALID_XML_CHAR_REGEX = /[\u0000-\u0008\u000B\u000C\u000E-\u001F]/g;
|
|
7
|
+
var chartBuilder = new XMLBuilder({
|
|
8
|
+
ignoreAttributes: false,
|
|
9
|
+
attributesGroupName: "a$",
|
|
10
|
+
textNodeName: "t$",
|
|
11
|
+
suppressEmptyNode: true,
|
|
12
|
+
});
|
|
13
|
+
var sanitizeXmlText = function (value) {
|
|
14
|
+
return value ? value.replace(INVALID_XML_CHAR_REGEX, "") : value;
|
|
15
|
+
};
|
|
16
|
+
var cloneTemplate = function (template) {
|
|
17
|
+
return JSON.parse(JSON.stringify(template));
|
|
18
|
+
};
|
|
19
|
+
var removeProp = function (obj, key) {
|
|
20
|
+
delete obj[key];
|
|
21
|
+
};
|
|
22
|
+
var normalizeFormula = function (formula) {
|
|
23
|
+
var trimmed = formula.startsWith("=") ? formula.slice(1) : formula;
|
|
24
|
+
return sanitizeXmlText(trimmed).replace(/\r\n|\r|\n/g, " ");
|
|
25
|
+
};
|
|
26
|
+
var hasPropertyReference = function (formula) {
|
|
27
|
+
if (!formula)
|
|
28
|
+
return false;
|
|
29
|
+
// Detects cell references with property access: A1.property, $A$1.nested.value, etc.
|
|
30
|
+
var propertyReferencePattern = /[$]?[A-Za-z]{1,3}[$]?[1-9][0-9]*\./;
|
|
31
|
+
return propertyReferencePattern.test(formula);
|
|
32
|
+
};
|
|
33
|
+
var formatRangeRef = function (range, sheetNameById) {
|
|
34
|
+
if (!range)
|
|
35
|
+
return undefined;
|
|
36
|
+
var sheetName = sheetNameById.get(range.sheetId);
|
|
37
|
+
return cellRangeToAddress(sheetName, range);
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* A1 reference over EVERY range of a (possibly multi-area) source list,
|
|
41
|
+
* joined with the union operator — `'Sheet'!$E$19,'Sheet'!$E$26,…`. The old
|
|
42
|
+
* first-range-only behavior silently truncated discontiguous series.
|
|
43
|
+
*/
|
|
44
|
+
var formatSourcesRef = function (sources, sheetNameById) {
|
|
45
|
+
if (!(sources === null || sources === void 0 ? void 0 : sources.length))
|
|
46
|
+
return undefined;
|
|
47
|
+
var parts = sources
|
|
48
|
+
.map(function (range) { return formatRangeRef(range, sheetNameById); })
|
|
49
|
+
.filter(function (ref) { return Boolean(ref); });
|
|
50
|
+
return parts.length ? parts.join(",") : undefined;
|
|
51
|
+
};
|
|
52
|
+
var seriesCategoryRef = function (entry, sheetNameById) {
|
|
53
|
+
return formatSourcesRef(entry === null || entry === void 0 ? void 0 : entry.categorySources, sheetNameById);
|
|
54
|
+
};
|
|
55
|
+
var buildSeriesLabel = function (label, sheetName, labelRef) {
|
|
56
|
+
// A captured source reference (`<c:tx><c:strRef>`) wins over the literal:
|
|
57
|
+
// emitting the ref without a cache lets Excel resolve the live series name
|
|
58
|
+
// on open, instead of freezing a possibly-generic literal.
|
|
59
|
+
if (labelRef) {
|
|
60
|
+
return {
|
|
61
|
+
"c:tx": {
|
|
62
|
+
"c:strRef": {
|
|
63
|
+
"c:f": labelRef,
|
|
64
|
+
},
|
|
65
|
+
},
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
if (label === undefined || label === null || label === "")
|
|
69
|
+
return undefined;
|
|
70
|
+
// Numeric series headers (e.g. a year like 2024) can reach us as numbers
|
|
71
|
+
var text = typeof label === "string" ? label : String(label);
|
|
72
|
+
if (text.startsWith("=")) {
|
|
73
|
+
// If label contains property references (e.g., =A1.propertyName),
|
|
74
|
+
// treat it as static text instead of formula reference
|
|
75
|
+
if (hasPropertyReference(text)) {
|
|
76
|
+
return {
|
|
77
|
+
"c:tx": {
|
|
78
|
+
"c:v": sanitizeXmlText(text),
|
|
79
|
+
},
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
var formula = normalizeFormula(text);
|
|
83
|
+
var resolved = sheetName && !formula.includes("!")
|
|
84
|
+
? "".concat(sanitizeSheetName(sheetName), "!").concat(formula)
|
|
85
|
+
: formula;
|
|
86
|
+
return {
|
|
87
|
+
"c:tx": {
|
|
88
|
+
"c:strRef": {
|
|
89
|
+
"c:f": resolved,
|
|
90
|
+
},
|
|
91
|
+
},
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
return {
|
|
95
|
+
"c:tx": {
|
|
96
|
+
"c:v": sanitizeXmlText(text),
|
|
97
|
+
},
|
|
98
|
+
};
|
|
99
|
+
};
|
|
100
|
+
var buildColorNode = function (color) {
|
|
101
|
+
var normalized = color.startsWith("#") ? color.slice(1) : color;
|
|
102
|
+
var hex = normalized.length === 6
|
|
103
|
+
? normalized
|
|
104
|
+
: normalized.slice(normalized.length - 6);
|
|
105
|
+
return {
|
|
106
|
+
"a:solidFill": {
|
|
107
|
+
"a:srgbClr": {
|
|
108
|
+
a$: {
|
|
109
|
+
val: hex,
|
|
110
|
+
},
|
|
111
|
+
},
|
|
112
|
+
},
|
|
113
|
+
};
|
|
114
|
+
};
|
|
115
|
+
var normalizeHex = function (color) {
|
|
116
|
+
var stripped = color.startsWith("#") ? color.slice(1) : color;
|
|
117
|
+
return stripped.length === 6
|
|
118
|
+
? stripped
|
|
119
|
+
: stripped.slice(stripped.length - 6);
|
|
120
|
+
};
|
|
121
|
+
/**
|
|
122
|
+
* Build an OOXML `<a:gradFill>` node from a series-level gradient
|
|
123
|
+
* descriptor. Matches the DrawingML schema:
|
|
124
|
+
*
|
|
125
|
+
* <a:gradFill flip="none" rotWithShape="1">
|
|
126
|
+
* <a:gsLst>
|
|
127
|
+
* <a:gs pos="0"><a:srgbClr val="FF0000"/></a:gs>
|
|
128
|
+
* <a:gs pos="100000"><a:srgbClr val="0000FF"/></a:gs>
|
|
129
|
+
* </a:gsLst>
|
|
130
|
+
* <a:lin ang="5400000" scaled="0"/> <!-- or <a:path path="rect">…</a:path> -->
|
|
131
|
+
* </a:gradFill>
|
|
132
|
+
*
|
|
133
|
+
* Positions are EMU per-mille (0..100000). Linear angle is in 60000ths
|
|
134
|
+
* of a degree (90° == 5400000) — Excel's chart angle convention runs
|
|
135
|
+
* clockwise from 12 o'clock, so the conversion is `deg * 60000`.
|
|
136
|
+
*
|
|
137
|
+
* Path gradients use `<a:path path="rect">` with a `<a:fillToRect>`
|
|
138
|
+
* child carrying the inset of the inner stop in EMU per-mille.
|
|
139
|
+
*/
|
|
140
|
+
var buildGradFillNode = function (gradient) {
|
|
141
|
+
var _a, _b;
|
|
142
|
+
if (!((_a = gradient === null || gradient === void 0 ? void 0 : gradient.stops) === null || _a === void 0 ? void 0 : _a.length))
|
|
143
|
+
return null;
|
|
144
|
+
var gsList = gradient.stops.map(function (stop) { return ({
|
|
145
|
+
a$: { pos: String(Math.round(Math.max(0, Math.min(1, stop.position)) * 100000)) },
|
|
146
|
+
"a:srgbClr": { a$: { val: normalizeHex(stop.color) } },
|
|
147
|
+
}); });
|
|
148
|
+
var direction = {};
|
|
149
|
+
if (gradient.type === "path") {
|
|
150
|
+
var toEmu = function (v) {
|
|
151
|
+
return v != null ? String(Math.round(v * 100000)) : "0";
|
|
152
|
+
};
|
|
153
|
+
direction["a:path"] = {
|
|
154
|
+
a$: { path: "rect" },
|
|
155
|
+
"a:fillToRect": {
|
|
156
|
+
a$: {
|
|
157
|
+
l: toEmu(gradient.left),
|
|
158
|
+
r: toEmu(gradient.right),
|
|
159
|
+
t: toEmu(gradient.top),
|
|
160
|
+
b: toEmu(gradient.bottom),
|
|
161
|
+
},
|
|
162
|
+
},
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
else {
|
|
166
|
+
var deg = (((_b = gradient.degree) !== null && _b !== void 0 ? _b : 0) % 360 + 360) % 360;
|
|
167
|
+
direction["a:lin"] = {
|
|
168
|
+
a$: {
|
|
169
|
+
ang: String(Math.round(deg * 60000)),
|
|
170
|
+
scaled: "0",
|
|
171
|
+
},
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
return __assign({ a$: { flip: "none", rotWithShape: "1" }, "a:gsLst": { "a:gs": gsList } }, direction);
|
|
175
|
+
};
|
|
176
|
+
/**
|
|
177
|
+
* Replace the series' shape-properties fill with a gradient when one
|
|
178
|
+
* is supplied. Strips any pre-existing solid/scheme fill so the
|
|
179
|
+
* gradient doesn't double up.
|
|
180
|
+
*/
|
|
181
|
+
var applySeriesGradient = function (seriesNode, gradient) {
|
|
182
|
+
if (!gradient)
|
|
183
|
+
return false;
|
|
184
|
+
var gradFill = buildGradFillNode(gradient);
|
|
185
|
+
if (!gradFill)
|
|
186
|
+
return false;
|
|
187
|
+
var spPr = seriesNode["c:spPr"];
|
|
188
|
+
if (!spPr)
|
|
189
|
+
return false;
|
|
190
|
+
delete spPr["a:solidFill"];
|
|
191
|
+
spPr["a:gradFill"] = gradFill;
|
|
192
|
+
return true;
|
|
193
|
+
};
|
|
194
|
+
/**
|
|
195
|
+
* Build the extension list for a series with invertIfNegative support.
|
|
196
|
+
* This adds the c14:invertSolidFillFmt extension for negative fill color.
|
|
197
|
+
*/
|
|
198
|
+
var buildSeriesExtLst = function (negativeColor, uniqueId) {
|
|
199
|
+
var extensions = [];
|
|
200
|
+
// Add unique ID extension (required by Excel)
|
|
201
|
+
extensions.push({
|
|
202
|
+
a$: {
|
|
203
|
+
uri: "{C3380CC4-5D6E-409C-BE32-E72D297353CC}",
|
|
204
|
+
"xmlns:c16": "http://schemas.microsoft.com/office/drawing/2014/chart",
|
|
205
|
+
},
|
|
206
|
+
"c16:uniqueId": {
|
|
207
|
+
a$: {
|
|
208
|
+
val: uniqueId,
|
|
209
|
+
},
|
|
210
|
+
},
|
|
211
|
+
});
|
|
212
|
+
// Add negative fill color extension if specified
|
|
213
|
+
if (negativeColor) {
|
|
214
|
+
var normalizedColor = negativeColor.startsWith("#")
|
|
215
|
+
? negativeColor.slice(1)
|
|
216
|
+
: negativeColor;
|
|
217
|
+
var hex = normalizedColor.length === 6
|
|
218
|
+
? normalizedColor
|
|
219
|
+
: normalizedColor.slice(normalizedColor.length - 6);
|
|
220
|
+
extensions.push({
|
|
221
|
+
a$: {
|
|
222
|
+
uri: "{6F2FDCE9-48DA-4B69-8628-5D25D57E5C99}",
|
|
223
|
+
"xmlns:c14": "http://schemas.microsoft.com/office/drawing/2007/8/2/chart",
|
|
224
|
+
},
|
|
225
|
+
"c14:invertSolidFillFmt": {
|
|
226
|
+
"c14:spPr": {
|
|
227
|
+
"a:solidFill": {
|
|
228
|
+
"a:srgbClr": {
|
|
229
|
+
a$: {
|
|
230
|
+
val: hex,
|
|
231
|
+
},
|
|
232
|
+
},
|
|
233
|
+
},
|
|
234
|
+
"a:ln": {
|
|
235
|
+
"a:noFill": {},
|
|
236
|
+
},
|
|
237
|
+
"a:effectLst": {},
|
|
238
|
+
},
|
|
239
|
+
},
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
return {
|
|
243
|
+
"c:ext": extensions.length === 1 ? extensions[0] : extensions,
|
|
244
|
+
};
|
|
245
|
+
};
|
|
246
|
+
// ─── Round-trip helpers (textFormat, marker, dPt, inline values) ─────
|
|
247
|
+
/**
|
|
248
|
+
* Build a `<c:txPr>` XML node from a ChartTextFormat. Returns
|
|
249
|
+
* `undefined` when the format has no settable properties so callers
|
|
250
|
+
* can skip emission. Used by axis, legend, title, and data-label
|
|
251
|
+
* blocks to preserve authored color/font on round-trip.
|
|
252
|
+
*/
|
|
253
|
+
var buildTxPrNode = function (textFormat) {
|
|
254
|
+
if (!textFormat)
|
|
255
|
+
return undefined;
|
|
256
|
+
var defRPr = { a$: {} };
|
|
257
|
+
if (typeof textFormat.fontSize === "number") {
|
|
258
|
+
// ChartTextFormat stores points; OOXML stores 100ths of a point.
|
|
259
|
+
defRPr.a$.sz = String(Math.round(textFormat.fontSize * 100));
|
|
260
|
+
}
|
|
261
|
+
if (textFormat.bold)
|
|
262
|
+
defRPr.a$.b = "1";
|
|
263
|
+
if (textFormat.italic)
|
|
264
|
+
defRPr.a$.i = "1";
|
|
265
|
+
if (textFormat.underline)
|
|
266
|
+
defRPr.a$.u = "sng";
|
|
267
|
+
if (textFormat.strikethrough)
|
|
268
|
+
defRPr.a$.strike = "sngStrike";
|
|
269
|
+
if (textFormat.color) {
|
|
270
|
+
var hex = String(textFormat.color).replace(/^#/, "").toUpperCase();
|
|
271
|
+
defRPr["a:solidFill"] = {
|
|
272
|
+
"a:srgbClr": { a$: { val: hex } },
|
|
273
|
+
};
|
|
274
|
+
}
|
|
275
|
+
if (textFormat.fontFamily) {
|
|
276
|
+
defRPr["a:latin"] = { a$: { typeface: textFormat.fontFamily } };
|
|
277
|
+
}
|
|
278
|
+
// Only emit when we wrote something useful — otherwise Excel rejects
|
|
279
|
+
// an empty defRPr.
|
|
280
|
+
var hasAttrs = Object.keys(defRPr.a$).length > 0;
|
|
281
|
+
var hasChildren = Object.keys(defRPr).some(function (k) { return k !== "a$"; });
|
|
282
|
+
if (!hasAttrs && !hasChildren)
|
|
283
|
+
return undefined;
|
|
284
|
+
return {
|
|
285
|
+
"a:bodyPr": {
|
|
286
|
+
a$: {
|
|
287
|
+
rot: "0",
|
|
288
|
+
spcFirstLastPara: "1",
|
|
289
|
+
vertOverflow: "ellipsis",
|
|
290
|
+
wrap: "square",
|
|
291
|
+
anchor: "ctr",
|
|
292
|
+
anchorCtr: "1",
|
|
293
|
+
},
|
|
294
|
+
},
|
|
295
|
+
"a:lstStyle": {},
|
|
296
|
+
"a:p": {
|
|
297
|
+
"a:pPr": { "a:defRPr": defRPr },
|
|
298
|
+
"a:endParaRPr": { a$: { lang: "en-US" } },
|
|
299
|
+
},
|
|
300
|
+
};
|
|
301
|
+
};
|
|
302
|
+
/**
|
|
303
|
+
* Build a `<c:strLit>` inline category block from an array of values.
|
|
304
|
+
* Used when a chart's category axis is embedded literally in the chart
|
|
305
|
+
* XML (e.g. Event Budget's `["Estimated", "Actual"]`) instead of
|
|
306
|
+
* referencing the sheet.
|
|
307
|
+
*/
|
|
308
|
+
var buildInlineStrLit = function (values) { return ({
|
|
309
|
+
"c:strLit": {
|
|
310
|
+
"c:ptCount": { a$: { val: String(values.length) } },
|
|
311
|
+
"c:pt": values.map(function (v, i) { return ({
|
|
312
|
+
a$: { idx: String(i) },
|
|
313
|
+
"c:v": sanitizeXmlText(String(v)),
|
|
314
|
+
}); }),
|
|
315
|
+
},
|
|
316
|
+
}); };
|
|
317
|
+
/**
|
|
318
|
+
* Build a `<c:numLit>` inline numeric block from values. Used for
|
|
319
|
+
* inline-value series (rare but legal in OOXML).
|
|
320
|
+
*/
|
|
321
|
+
var buildInlineNumLit = function (values) { return ({
|
|
322
|
+
"c:numLit": {
|
|
323
|
+
"c:formatCode": "General",
|
|
324
|
+
"c:ptCount": { a$: { val: String(values.length) } },
|
|
325
|
+
"c:pt": values.map(function (v, i) { return ({
|
|
326
|
+
a$: { idx: String(i) },
|
|
327
|
+
"c:v": typeof v === "number" ? String(v) : Number(v).toString(),
|
|
328
|
+
}); }),
|
|
329
|
+
},
|
|
330
|
+
}); };
|
|
331
|
+
/**
|
|
332
|
+
* Build a `<c:marker>` node from a ChartData.marker spec. Returns
|
|
333
|
+
* `undefined` when the marker carries no information.
|
|
334
|
+
*/
|
|
335
|
+
var buildMarkerNode = function (marker) {
|
|
336
|
+
if (!marker)
|
|
337
|
+
return undefined;
|
|
338
|
+
var node = {};
|
|
339
|
+
if (marker.symbol) {
|
|
340
|
+
node["c:symbol"] = { a$: { val: marker.symbol } };
|
|
341
|
+
}
|
|
342
|
+
if (typeof marker.size === "number") {
|
|
343
|
+
node["c:size"] = { a$: { val: String(Math.round(marker.size)) } };
|
|
344
|
+
}
|
|
345
|
+
if (marker.color) {
|
|
346
|
+
node["c:spPr"] = {
|
|
347
|
+
"a:solidFill": buildColorNode(marker.color)["a:solidFill"],
|
|
348
|
+
};
|
|
349
|
+
}
|
|
350
|
+
return Object.keys(node).length ? node : undefined;
|
|
351
|
+
};
|
|
352
|
+
/**
|
|
353
|
+
* Build a `<c:dPt>` array from per-point color overrides. Each entry
|
|
354
|
+
* pins a category index to a different fill — Gantt-style charts use
|
|
355
|
+
* this to colour each task individually.
|
|
356
|
+
*/
|
|
357
|
+
var buildDataPointNodes = function (dataPointColors) {
|
|
358
|
+
if (!dataPointColors || !dataPointColors.length)
|
|
359
|
+
return undefined;
|
|
360
|
+
return dataPointColors.map(function (dp) { return ({
|
|
361
|
+
"c:idx": { a$: { val: String(dp.idx) } },
|
|
362
|
+
"c:invertIfNegative": { a$: { val: "0" } },
|
|
363
|
+
"c:bubble3D": { a$: { val: "0" } },
|
|
364
|
+
"c:spPr": {
|
|
365
|
+
"a:solidFill": buildColorNode(dp.color)["a:solidFill"],
|
|
366
|
+
"a:ln": { "a:noFill": {} },
|
|
367
|
+
},
|
|
368
|
+
}); });
|
|
369
|
+
};
|
|
370
|
+
/**
|
|
371
|
+
* Apply transparent fill to a series spPr node. Mirrors the
|
|
372
|
+
* `<a:noFill/>` form Excel uses for invisible "offset" bars (Gantt
|
|
373
|
+
* lag series). Replaces any existing solidFill/gradFill.
|
|
374
|
+
*/
|
|
375
|
+
var applyNoFillToSeriesSpPr = function (seriesNode) {
|
|
376
|
+
var _a;
|
|
377
|
+
var spPr = (seriesNode["c:spPr"] = (_a = seriesNode["c:spPr"]) !== null && _a !== void 0 ? _a : {});
|
|
378
|
+
removeProp(spPr, "a:solidFill");
|
|
379
|
+
removeProp(spPr, "a:gradFill");
|
|
380
|
+
spPr["a:noFill"] = {};
|
|
381
|
+
};
|
|
382
|
+
/**
|
|
383
|
+
* Build the subtitle `<a:p>` paragraph node (fast-xml-parser object form)
|
|
384
|
+
* appended below the chart title inside the same `<c:rich>` block.
|
|
385
|
+
*
|
|
386
|
+
* Mirrors the legacy JS post-patcher (`chart-subtitle-patcher.ts`): the
|
|
387
|
+
* subtitle renders at ~70% of the title font size (9pt floor) in a muted
|
|
388
|
+
* `tx1` scheme colour. `titleSize` is in OOXML hundredths-of-a-point.
|
|
389
|
+
*/
|
|
390
|
+
var buildSubtitleParagraphNode = function (subtitle, titleSize) {
|
|
391
|
+
var subtitleSize = Math.max(900, Math.round(titleSize * 0.7));
|
|
392
|
+
return {
|
|
393
|
+
"a:pPr": {
|
|
394
|
+
"a:defRPr": {
|
|
395
|
+
a$: {
|
|
396
|
+
sz: String(subtitleSize),
|
|
397
|
+
b: "0",
|
|
398
|
+
i: "0",
|
|
399
|
+
u: "none",
|
|
400
|
+
strike: "noStrike",
|
|
401
|
+
kern: "1200",
|
|
402
|
+
spc: "0",
|
|
403
|
+
baseline: "0",
|
|
404
|
+
},
|
|
405
|
+
"a:solidFill": {
|
|
406
|
+
"a:schemeClr": {
|
|
407
|
+
a$: { val: "tx1" },
|
|
408
|
+
"a:lumMod": { a$: { val: "65000" } },
|
|
409
|
+
"a:lumOff": { a$: { val: "35000" } },
|
|
410
|
+
},
|
|
411
|
+
},
|
|
412
|
+
"a:latin": { a$: { typeface: "+mn-lt" } },
|
|
413
|
+
"a:ea": { a$: { typeface: "+mn-ea" } },
|
|
414
|
+
"a:cs": { a$: { typeface: "+mn-cs" } },
|
|
415
|
+
},
|
|
416
|
+
},
|
|
417
|
+
"a:r": {
|
|
418
|
+
"a:rPr": { a$: { lang: "en-US", sz: String(subtitleSize), b: "0", i: "0" } },
|
|
419
|
+
"a:t": sanitizeXmlText(subtitle),
|
|
420
|
+
},
|
|
421
|
+
};
|
|
422
|
+
};
|
|
423
|
+
var applyChartTitle = function (chartNode, title, titleTextFormat, subtitle) {
|
|
424
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
425
|
+
if (!title)
|
|
426
|
+
return;
|
|
427
|
+
var titleBlock = cloneTemplate(static_title);
|
|
428
|
+
titleBlock["c:tx"]["c:rich"]["a:p"]["a:r"]["a:rPr"].a$.lang = "en-US";
|
|
429
|
+
titleBlock["c:tx"]["c:rich"]["a:p"]["a:r"]["a:t"] = sanitizeXmlText(title);
|
|
430
|
+
// Apply authored text format on the rich run's `a:rPr` so Excel
|
|
431
|
+
// preserves color/font on round-trip. We mutate the rPr directly
|
|
432
|
+
// (it's already inside the template's a:p > a:r).
|
|
433
|
+
if (titleTextFormat) {
|
|
434
|
+
var rPr = titleBlock["c:tx"]["c:rich"]["a:p"]["a:r"]["a:rPr"];
|
|
435
|
+
if (typeof titleTextFormat.fontSize === "number") {
|
|
436
|
+
rPr.a$.sz = String(Math.round(titleTextFormat.fontSize * 100));
|
|
437
|
+
}
|
|
438
|
+
if (titleTextFormat.bold)
|
|
439
|
+
rPr.a$.b = "1";
|
|
440
|
+
if (titleTextFormat.italic)
|
|
441
|
+
rPr.a$.i = "1";
|
|
442
|
+
if (titleTextFormat.color) {
|
|
443
|
+
var hex = String(titleTextFormat.color).replace(/^#/, "").toUpperCase();
|
|
444
|
+
rPr["a:solidFill"] = { "a:srgbClr": { a$: { val: hex } } };
|
|
445
|
+
}
|
|
446
|
+
if (titleTextFormat.fontFamily) {
|
|
447
|
+
rPr["a:latin"] = { a$: { typeface: titleTextFormat.fontFamily } };
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
// Append the subtitle as a SECOND `<a:p>` inside the title's `<c:rich>`,
|
|
451
|
+
// matching what the legacy JS post-patcher spliced in. Emitted natively
|
|
452
|
+
// here so no post-processing pass is needed. Scale relative to the
|
|
453
|
+
// authored title size (defaults to the template's 14pt → sz="1400").
|
|
454
|
+
if (subtitle && subtitle.trim().length > 0) {
|
|
455
|
+
var rich = titleBlock["c:tx"]["c:rich"];
|
|
456
|
+
var titlePara = rich["a:p"];
|
|
457
|
+
var titleSizeStr = ((_d = (_c = (_b = (_a = titlePara === null || titlePara === void 0 ? void 0 : titlePara["a:pPr"]) === null || _a === void 0 ? void 0 : _a["a:defRPr"]) === null || _b === void 0 ? void 0 : _b.a$) === null || _c === void 0 ? void 0 : _c.sz) !== null && _d !== void 0 ? _d : (_g = (_f = (_e = titlePara === null || titlePara === void 0 ? void 0 : titlePara["a:r"]) === null || _e === void 0 ? void 0 : _e["a:rPr"]) === null || _f === void 0 ? void 0 : _f.a$) === null || _g === void 0 ? void 0 : _g.sz);
|
|
458
|
+
var titleSize = titleSizeStr && Number.isFinite(parseInt(titleSizeStr, 10))
|
|
459
|
+
? parseInt(titleSizeStr, 10)
|
|
460
|
+
: 1400;
|
|
461
|
+
rich["a:p"] = [titlePara, buildSubtitleParagraphNode(subtitle, titleSize)];
|
|
462
|
+
}
|
|
463
|
+
chartNode["c:title"] = titleBlock;
|
|
464
|
+
};
|
|
465
|
+
var getPrimarySource = function (entry) { var _a; return (_a = entry === null || entry === void 0 ? void 0 : entry.sources) === null || _a === void 0 ? void 0 : _a[0]; };
|
|
466
|
+
/**
|
|
467
|
+
* c15 extension namespace (Excel 2012+) — histogram / boxplot /
|
|
468
|
+
* waterfall / funnel charts are emitted with a `c:barChart` body
|
|
469
|
+
* inside `mc:Fallback` (so older Excel still renders something) plus a
|
|
470
|
+
* full c15 chart element inside `mc:Choice` (so Excel 2016+ renders
|
|
471
|
+
* the chart natively). See `buildC15AlternateContent` and the per-type
|
|
472
|
+
* builders below.
|
|
473
|
+
*/
|
|
474
|
+
var C15_NS = "http://schemas.microsoft.com/office/drawing/2012/chart";
|
|
475
|
+
var C15_ELEMENT_NAMES = {
|
|
476
|
+
histogram: "c15:histogramChart",
|
|
477
|
+
boxplot: "c15:boxWhiskerChart",
|
|
478
|
+
waterfall: "c15:waterfallChart",
|
|
479
|
+
funnel: "c15:funnelChart",
|
|
480
|
+
};
|
|
481
|
+
var isC15ChartType = function (t) {
|
|
482
|
+
return t === "histogram" || t === "boxplot" || t === "waterfall" || t === "funnel";
|
|
483
|
+
};
|
|
484
|
+
var MC_NS = "http://schemas.openxmlformats.org/markup-compatibility/2006";
|
|
485
|
+
/**
|
|
486
|
+
* Phase 5.5b — build the full c15:histogramChart body that Excel 2016+
|
|
487
|
+
* uses to render histograms natively. Lives inside `mc:Choice` next to
|
|
488
|
+
* the older `c:barChart` fallback (in `mc:Fallback`). Both share the
|
|
489
|
+
* `c:catAx`/`c:valAx` declared at `c:plotArea` level — c15 axId values
|
|
490
|
+
* are picked to match the bar chart's axId so Excel can resolve them.
|
|
491
|
+
*/
|
|
492
|
+
var buildC15HistogramChartNode = function (spec, seriesRefs, series, domainRef, axIds) {
|
|
493
|
+
var c15SeriesEntries = [];
|
|
494
|
+
seriesRefs.forEach(function (ref, index) {
|
|
495
|
+
var _a;
|
|
496
|
+
if (!ref)
|
|
497
|
+
return;
|
|
498
|
+
var seriesNode = {
|
|
499
|
+
"c15:idx": { a$: { val: String(index) } },
|
|
500
|
+
"c15:order": { a$: { val: String(index) } },
|
|
501
|
+
};
|
|
502
|
+
// Series title — only if the consumer set a non-formula dataLabel.
|
|
503
|
+
var dataLabel = (_a = series[index]) === null || _a === void 0 ? void 0 : _a.dataLabel;
|
|
504
|
+
if (dataLabel && !dataLabel.startsWith("=")) {
|
|
505
|
+
seriesNode["c15:tx"] = {
|
|
506
|
+
"c15:v": dataLabel,
|
|
507
|
+
};
|
|
508
|
+
}
|
|
509
|
+
seriesNode["c15:val"] = {
|
|
510
|
+
"c15:numRef": {
|
|
511
|
+
"c15:f": ref,
|
|
512
|
+
},
|
|
513
|
+
};
|
|
514
|
+
c15SeriesEntries.push(seriesNode);
|
|
515
|
+
});
|
|
516
|
+
var histogramChart = {
|
|
517
|
+
"c15:varyColors": { a$: { val: "0" } },
|
|
518
|
+
"c15:ser": c15SeriesEntries.length === 1 ? c15SeriesEntries[0] : c15SeriesEntries,
|
|
519
|
+
"c15:axId": [
|
|
520
|
+
{ a$: { val: axIds.catAxId } },
|
|
521
|
+
{ a$: { val: axIds.valAxId } },
|
|
522
|
+
],
|
|
523
|
+
};
|
|
524
|
+
// Bin configuration: explicit binCount when set, otherwise let Excel
|
|
525
|
+
// auto-bin (Sturges-like).
|
|
526
|
+
if (typeof (spec === null || spec === void 0 ? void 0 : spec.binCount) === "number" && spec.binCount > 0) {
|
|
527
|
+
histogramChart["c15:binCount"] = { a$: { val: String(spec.binCount) } };
|
|
528
|
+
}
|
|
529
|
+
else {
|
|
530
|
+
histogramChart["c15:binsAuto"] = { a$: { val: "1" } };
|
|
531
|
+
}
|
|
532
|
+
return histogramChart;
|
|
533
|
+
};
|
|
534
|
+
/**
|
|
535
|
+
* Phase 5.5b — c15:boxWhiskerChart body. Excel 2016+ renders box & whisker
|
|
536
|
+
* natively from this. Each series carries its raw values; Excel computes
|
|
537
|
+
* the quartiles + median + outliers from `c15:quartileMethod`.
|
|
538
|
+
*/
|
|
539
|
+
var buildC15BoxplotChartNode = function (_spec, seriesRefs, series, domainRef, axIds) {
|
|
540
|
+
var c15SeriesEntries = [];
|
|
541
|
+
seriesRefs.forEach(function (ref, index) {
|
|
542
|
+
var _a;
|
|
543
|
+
if (!ref)
|
|
544
|
+
return;
|
|
545
|
+
var seriesNode = {
|
|
546
|
+
"c15:idx": { a$: { val: String(index) } },
|
|
547
|
+
"c15:order": { a$: { val: String(index) } },
|
|
548
|
+
"c15:invertIfNegative": { a$: { val: "0" } },
|
|
549
|
+
"c15:bubble3D": { a$: { val: "0" } },
|
|
550
|
+
};
|
|
551
|
+
var dataLabel = (_a = series[index]) === null || _a === void 0 ? void 0 : _a.dataLabel;
|
|
552
|
+
if (dataLabel && !dataLabel.startsWith("=")) {
|
|
553
|
+
seriesNode["c15:tx"] = { "c15:v": dataLabel };
|
|
554
|
+
}
|
|
555
|
+
if (domainRef) {
|
|
556
|
+
seriesNode["c15:cat"] = {
|
|
557
|
+
"c15:strRef": { "c15:f": domainRef },
|
|
558
|
+
};
|
|
559
|
+
}
|
|
560
|
+
seriesNode["c15:val"] = {
|
|
561
|
+
"c15:numRef": { "c15:f": ref },
|
|
562
|
+
};
|
|
563
|
+
c15SeriesEntries.push(seriesNode);
|
|
564
|
+
});
|
|
565
|
+
return {
|
|
566
|
+
"c15:varyColors": { a$: { val: "0" } },
|
|
567
|
+
"c15:ser": c15SeriesEntries.length === 1 ? c15SeriesEntries[0] : c15SeriesEntries,
|
|
568
|
+
"c15:showInnerPoints": { a$: { val: "0" } },
|
|
569
|
+
"c15:showOutlierPoints": { a$: { val: "1" } },
|
|
570
|
+
"c15:showMeanMarker": { a$: { val: "1" } },
|
|
571
|
+
"c15:showMeanLine": { a$: { val: "0" } },
|
|
572
|
+
"c15:quartileMethod": { a$: { val: "exclusive" } },
|
|
573
|
+
"c15:axId": [
|
|
574
|
+
{ a$: { val: axIds.catAxId } },
|
|
575
|
+
{ a$: { val: axIds.valAxId } },
|
|
576
|
+
],
|
|
577
|
+
};
|
|
578
|
+
};
|
|
579
|
+
/**
|
|
580
|
+
* Phase 5.5b — c15:waterfallChart body. Each c15:ser carries one data
|
|
581
|
+
* point per category. Subtotals are marked at the series level via
|
|
582
|
+
* c15:dPt with c15:subTotal set; without these, Excel treats every
|
|
583
|
+
* point as a delta and the running cumulative is implicit.
|
|
584
|
+
*/
|
|
585
|
+
var buildC15WaterfallChartNode = function (_spec, seriesRefs, series, domainRef, axIds) {
|
|
586
|
+
var c15SeriesEntries = [];
|
|
587
|
+
seriesRefs.forEach(function (ref, index) {
|
|
588
|
+
var _a;
|
|
589
|
+
if (!ref)
|
|
590
|
+
return;
|
|
591
|
+
var seriesNode = {
|
|
592
|
+
"c15:idx": { a$: { val: String(index) } },
|
|
593
|
+
"c15:order": { a$: { val: String(index) } },
|
|
594
|
+
};
|
|
595
|
+
var dataLabel = (_a = series[index]) === null || _a === void 0 ? void 0 : _a.dataLabel;
|
|
596
|
+
if (dataLabel && !dataLabel.startsWith("=")) {
|
|
597
|
+
seriesNode["c15:tx"] = { "c15:v": dataLabel };
|
|
598
|
+
}
|
|
599
|
+
if (domainRef) {
|
|
600
|
+
seriesNode["c15:cat"] = {
|
|
601
|
+
"c15:strRef": { "c15:f": domainRef },
|
|
602
|
+
};
|
|
603
|
+
}
|
|
604
|
+
seriesNode["c15:val"] = {
|
|
605
|
+
"c15:numRef": { "c15:f": ref },
|
|
606
|
+
};
|
|
607
|
+
c15SeriesEntries.push(seriesNode);
|
|
608
|
+
});
|
|
609
|
+
return {
|
|
610
|
+
"c15:varyColors": { a$: { val: "0" } },
|
|
611
|
+
"c15:ser": c15SeriesEntries.length === 1 ? c15SeriesEntries[0] : c15SeriesEntries,
|
|
612
|
+
"c15:axId": [
|
|
613
|
+
{ a$: { val: axIds.catAxId } },
|
|
614
|
+
{ a$: { val: axIds.valAxId } },
|
|
615
|
+
],
|
|
616
|
+
};
|
|
617
|
+
};
|
|
618
|
+
/**
|
|
619
|
+
* Phase 5.5b — c15:funnelChart body. Categories label each funnel
|
|
620
|
+
* stage; values size the stages. No subtotals, no quartile config.
|
|
621
|
+
*/
|
|
622
|
+
var buildC15FunnelChartNode = function (_spec, seriesRefs, series, domainRef, axIds) {
|
|
623
|
+
var c15SeriesEntries = [];
|
|
624
|
+
seriesRefs.forEach(function (ref, index) {
|
|
625
|
+
var _a;
|
|
626
|
+
if (!ref)
|
|
627
|
+
return;
|
|
628
|
+
var seriesNode = {
|
|
629
|
+
"c15:idx": { a$: { val: String(index) } },
|
|
630
|
+
"c15:order": { a$: { val: String(index) } },
|
|
631
|
+
};
|
|
632
|
+
var dataLabel = (_a = series[index]) === null || _a === void 0 ? void 0 : _a.dataLabel;
|
|
633
|
+
if (dataLabel && !dataLabel.startsWith("=")) {
|
|
634
|
+
seriesNode["c15:tx"] = { "c15:v": dataLabel };
|
|
635
|
+
}
|
|
636
|
+
if (domainRef) {
|
|
637
|
+
seriesNode["c15:cat"] = {
|
|
638
|
+
"c15:strRef": { "c15:f": domainRef },
|
|
639
|
+
};
|
|
640
|
+
}
|
|
641
|
+
seriesNode["c15:val"] = {
|
|
642
|
+
"c15:numRef": { "c15:f": ref },
|
|
643
|
+
};
|
|
644
|
+
c15SeriesEntries.push(seriesNode);
|
|
645
|
+
});
|
|
646
|
+
return {
|
|
647
|
+
"c15:varyColors": { a$: { val: "0" } },
|
|
648
|
+
"c15:ser": c15SeriesEntries.length === 1 ? c15SeriesEntries[0] : c15SeriesEntries,
|
|
649
|
+
"c15:axId": [
|
|
650
|
+
{ a$: { val: axIds.catAxId } },
|
|
651
|
+
{ a$: { val: axIds.valAxId } },
|
|
652
|
+
],
|
|
653
|
+
};
|
|
654
|
+
};
|
|
655
|
+
/**
|
|
656
|
+
* Phase 5.5b — wrap a c15 chart body in `mc:AlternateContent` so Excel
|
|
657
|
+
* 2016+ uses the c15 chart and older Excel falls back to the bar chart.
|
|
658
|
+
* Returns the AlternateContent node ready to splice into c:plotArea.
|
|
659
|
+
*/
|
|
660
|
+
var buildC15AlternateContent = function (chartType, c15ChartBody, fallbackBarChart) {
|
|
661
|
+
var _a;
|
|
662
|
+
var choiceElementName = C15_ELEMENT_NAMES[chartType];
|
|
663
|
+
return {
|
|
664
|
+
a$: { "xmlns:mc": MC_NS },
|
|
665
|
+
"mc:Choice": (_a = {
|
|
666
|
+
a$: {
|
|
667
|
+
Requires: "c15",
|
|
668
|
+
"xmlns:c15": C15_NS,
|
|
669
|
+
}
|
|
670
|
+
},
|
|
671
|
+
_a[choiceElementName] = c15ChartBody,
|
|
672
|
+
_a),
|
|
673
|
+
"mc:Fallback": {
|
|
674
|
+
"c:barChart": fallbackBarChart,
|
|
675
|
+
},
|
|
676
|
+
};
|
|
677
|
+
};
|
|
678
|
+
/**
|
|
679
|
+
* Group series by their effective chart type for combo chart support.
|
|
680
|
+
* Returns a map of chart type to array of {index, ref, seriesData}.
|
|
681
|
+
*/
|
|
682
|
+
var groupSeriesByChartType = function (series, seriesRefs, defaultChartType) {
|
|
683
|
+
var groups = new Map();
|
|
684
|
+
seriesRefs.forEach(function (ref, index) {
|
|
685
|
+
var _a;
|
|
686
|
+
if (!ref)
|
|
687
|
+
return;
|
|
688
|
+
var seriesData = series[index];
|
|
689
|
+
var effectiveType = ((_a = seriesData === null || seriesData === void 0 ? void 0 : seriesData.seriesChartType) !== null && _a !== void 0 ? _a : defaultChartType);
|
|
690
|
+
if (!groups.has(effectiveType)) {
|
|
691
|
+
groups.set(effectiveType, []);
|
|
692
|
+
}
|
|
693
|
+
groups.get(effectiveType).push({ index: index, ref: ref, data: seriesData });
|
|
694
|
+
});
|
|
695
|
+
return groups;
|
|
696
|
+
};
|
|
697
|
+
/**
|
|
698
|
+
* Check if a chart has multiple series types (combo chart).
|
|
699
|
+
*/
|
|
700
|
+
var isComboChart = function (series, defaultChartType) {
|
|
701
|
+
var e_1, _a;
|
|
702
|
+
var _b;
|
|
703
|
+
var types = new Set();
|
|
704
|
+
try {
|
|
705
|
+
for (var series_1 = __values(series), series_1_1 = series_1.next(); !series_1_1.done; series_1_1 = series_1.next()) {
|
|
706
|
+
var s = series_1_1.value;
|
|
707
|
+
types.add((_b = s.seriesChartType) !== null && _b !== void 0 ? _b : defaultChartType);
|
|
708
|
+
}
|
|
709
|
+
}
|
|
710
|
+
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
711
|
+
finally {
|
|
712
|
+
try {
|
|
713
|
+
if (series_1_1 && !series_1_1.done && (_a = series_1.return)) _a.call(series_1);
|
|
714
|
+
}
|
|
715
|
+
finally { if (e_1) throw e_1.error; }
|
|
716
|
+
}
|
|
717
|
+
return types.size > 1;
|
|
718
|
+
};
|
|
719
|
+
/**
|
|
720
|
+
* Build a bar/column series node.
|
|
721
|
+
*/
|
|
722
|
+
var buildBarSeriesNode = function (index, ref, seriesData, domainRef, sheetName, isFirstInGroup) {
|
|
723
|
+
var _a;
|
|
724
|
+
var seriesNode = cloneTemplate(column_series);
|
|
725
|
+
seriesNode["c:idx"] = { a$: { val: index.toString() } };
|
|
726
|
+
seriesNode["c:order"] = { a$: { val: index.toString() } };
|
|
727
|
+
var seriesColor = seriesData === null || seriesData === void 0 ? void 0 : seriesData.color;
|
|
728
|
+
var anyData = seriesData;
|
|
729
|
+
// noFill takes precedence over any other fill — Gantt-style
|
|
730
|
+
// invisible offset series. Must run BEFORE solidFill/gradient so it
|
|
731
|
+
// can wipe the template's default fill.
|
|
732
|
+
if (anyData === null || anyData === void 0 ? void 0 : anyData.noFill) {
|
|
733
|
+
applyNoFillToSeriesSpPr(seriesNode);
|
|
734
|
+
}
|
|
735
|
+
else if (applySeriesGradient(seriesNode, seriesData === null || seriesData === void 0 ? void 0 : seriesData.gradient)) {
|
|
736
|
+
// Gradient wins — solid/scheme already cleared.
|
|
737
|
+
}
|
|
738
|
+
else if (seriesColor) {
|
|
739
|
+
seriesNode["c:spPr"]["a:solidFill"] =
|
|
740
|
+
buildColorNode(seriesColor)["a:solidFill"];
|
|
741
|
+
}
|
|
742
|
+
else if (index < 6) {
|
|
743
|
+
seriesNode["c:spPr"]["a:solidFill"]["a:schemeClr"].a$.val = "accent".concat(index + 1);
|
|
744
|
+
}
|
|
745
|
+
// Per-data-point colors — emit `<c:dPt>` array after the series-
|
|
746
|
+
// level fill. Each entry overrides the fill for one category index.
|
|
747
|
+
var dPtNodes = buildDataPointNodes(anyData === null || anyData === void 0 ? void 0 : anyData.dataPointColors);
|
|
748
|
+
if (dPtNodes) {
|
|
749
|
+
seriesNode["c:dPt"] = dPtNodes;
|
|
750
|
+
}
|
|
751
|
+
// Handle invertIfNegative for negative bar coloring
|
|
752
|
+
var invertIfNegative = seriesData === null || seriesData === void 0 ? void 0 : seriesData.invertIfNegative;
|
|
753
|
+
var negativeColor = seriesData === null || seriesData === void 0 ? void 0 : seriesData.negativeColor;
|
|
754
|
+
if (invertIfNegative) {
|
|
755
|
+
seriesNode["c:invertIfNegative"] = { a$: { val: "1" } };
|
|
756
|
+
var uniqueId = "{".concat(crypto.randomUUID().toUpperCase(), "}");
|
|
757
|
+
seriesNode["c:extLst"] = buildSeriesExtLst(negativeColor !== null && negativeColor !== void 0 ? negativeColor : undefined, uniqueId);
|
|
758
|
+
}
|
|
759
|
+
// Excel writes the category reference on every series, not just the first
|
|
760
|
+
// in a group — readers treat a cat-less series as having no categories.
|
|
761
|
+
if (domainRef) {
|
|
762
|
+
seriesNode["c:cat"] = {
|
|
763
|
+
"c:strRef": {
|
|
764
|
+
"c:f": domainRef,
|
|
765
|
+
},
|
|
766
|
+
};
|
|
767
|
+
}
|
|
768
|
+
else if (seriesData === null || seriesData === void 0 ? void 0 : seriesData.inlineDomainValues) {
|
|
769
|
+
// Inline category labels (`<c:strLit>`) — used when categories are
|
|
770
|
+
// embedded in the chart XML rather than from a sheet range.
|
|
771
|
+
seriesNode["c:cat"] = buildInlineStrLit(seriesData.inlineDomainValues);
|
|
772
|
+
}
|
|
773
|
+
seriesNode["c:val"]["c:numRef"]["c:f"] = ref;
|
|
774
|
+
// Inline series values (`<c:numLit>`) — when the series carries its
|
|
775
|
+
// own values rather than a cell-range. Rare for bars but valid.
|
|
776
|
+
var inlineValues = anyData === null || anyData === void 0 ? void 0 : anyData.inlineValues;
|
|
777
|
+
if (!ref && Array.isArray(inlineValues) && inlineValues.length) {
|
|
778
|
+
removeProp(seriesNode, "c:val");
|
|
779
|
+
seriesNode["c:val"] = buildInlineNumLit(inlineValues);
|
|
780
|
+
}
|
|
781
|
+
var labelNode = buildSeriesLabel((_a = seriesData === null || seriesData === void 0 ? void 0 : seriesData.dataLabel) !== null && _a !== void 0 ? _a : undefined, sheetName, seriesData === null || seriesData === void 0 ? void 0 : seriesData.dataLabelRef);
|
|
782
|
+
if (labelNode) {
|
|
783
|
+
seriesNode["c:tx"] = labelNode["c:tx"];
|
|
784
|
+
}
|
|
785
|
+
// Per-series marker — typically scatter/bubble but bar/line/area
|
|
786
|
+
// charts can carry one too via `<c:marker>`.
|
|
787
|
+
var markerNode = buildMarkerNode(anyData === null || anyData === void 0 ? void 0 : anyData.marker);
|
|
788
|
+
if (markerNode) {
|
|
789
|
+
seriesNode["c:marker"] = markerNode;
|
|
790
|
+
}
|
|
791
|
+
return seriesNode;
|
|
792
|
+
};
|
|
793
|
+
/**
|
|
794
|
+
* Build a line series node.
|
|
795
|
+
*/
|
|
796
|
+
var buildLineSeriesNode = function (index, ref, seriesData, domainRef, sheetName, smooth) {
|
|
797
|
+
var _a, _b;
|
|
798
|
+
var seriesNode = cloneTemplate(line_series);
|
|
799
|
+
seriesNode["c:idx"] = { a$: { val: index.toString() } };
|
|
800
|
+
seriesNode["c:order"] = { a$: { val: index.toString() } };
|
|
801
|
+
var seriesColor = seriesData === null || seriesData === void 0 ? void 0 : seriesData.color;
|
|
802
|
+
// Line series carry the stroke fill on `c:spPr/a:ln`. A gradient on
|
|
803
|
+
// a line stroke is unusual (Excel renders a flat-color stroke even
|
|
804
|
+
// when the underlying spec carries a gradient on `a:ln`), so we
|
|
805
|
+
// prefer a solid stroke and only apply the gradient to the bg-style
|
|
806
|
+
// `c:spPr/a:solidFill` slot when present. If the caller explicitly
|
|
807
|
+
// requested a gradient, we replace the stroke's solid color with
|
|
808
|
+
// the first stop's hex — best-effort fallback.
|
|
809
|
+
if ((seriesData === null || seriesData === void 0 ? void 0 : seriesData.gradient) && ((_a = seriesData.gradient.stops) === null || _a === void 0 ? void 0 : _a.length)) {
|
|
810
|
+
var first = seriesData.gradient.stops[0].color;
|
|
811
|
+
seriesNode["c:spPr"]["a:ln"]["a:solidFill"] =
|
|
812
|
+
buildColorNode(first)["a:solidFill"];
|
|
813
|
+
}
|
|
814
|
+
else if (seriesColor) {
|
|
815
|
+
seriesNode["c:spPr"]["a:ln"]["a:solidFill"] =
|
|
816
|
+
buildColorNode(seriesColor)["a:solidFill"];
|
|
817
|
+
}
|
|
818
|
+
else if (index < 6) {
|
|
819
|
+
seriesNode["c:spPr"]["a:ln"]["a:solidFill"]["a:schemeClr"].a$.val = "accent".concat(index + 1);
|
|
820
|
+
}
|
|
821
|
+
if (domainRef) {
|
|
822
|
+
seriesNode["c:cat"]["c:strRef"]["c:f"] = domainRef;
|
|
823
|
+
}
|
|
824
|
+
else {
|
|
825
|
+
removeProp(seriesNode, "c:cat");
|
|
826
|
+
}
|
|
827
|
+
seriesNode["c:val"]["c:numRef"]["c:f"] = ref;
|
|
828
|
+
if (smooth) {
|
|
829
|
+
seriesNode["c:smooth"].a$.val = "1";
|
|
830
|
+
}
|
|
831
|
+
var labelNode = buildSeriesLabel((_b = seriesData === null || seriesData === void 0 ? void 0 : seriesData.dataLabel) !== null && _b !== void 0 ? _b : undefined, sheetName, seriesData === null || seriesData === void 0 ? void 0 : seriesData.dataLabelRef);
|
|
832
|
+
if (labelNode) {
|
|
833
|
+
seriesNode["c:tx"] = labelNode["c:tx"];
|
|
834
|
+
}
|
|
835
|
+
return seriesNode;
|
|
836
|
+
};
|
|
837
|
+
/**
|
|
838
|
+
* Build an area series node.
|
|
839
|
+
*/
|
|
840
|
+
var buildAreaSeriesNode = function (index, ref, seriesData, domainRef, sheetName) {
|
|
841
|
+
var _a, _b, _c;
|
|
842
|
+
var seriesNode = cloneTemplate(area_series);
|
|
843
|
+
seriesNode["c:idx"] = { a$: { val: index.toString() } };
|
|
844
|
+
seriesNode["c:order"] = { a$: { val: index.toString() } };
|
|
845
|
+
var seriesColor = seriesData === null || seriesData === void 0 ? void 0 : seriesData.color;
|
|
846
|
+
if (applySeriesGradient(seriesNode, seriesData === null || seriesData === void 0 ? void 0 : seriesData.gradient)) {
|
|
847
|
+
// Gradient applied to the fill area. Stroke stays solid using
|
|
848
|
+
// the first stop's color so the outline is visible.
|
|
849
|
+
if ((_b = (_a = seriesData === null || seriesData === void 0 ? void 0 : seriesData.gradient) === null || _a === void 0 ? void 0 : _a.stops) === null || _b === void 0 ? void 0 : _b.length) {
|
|
850
|
+
seriesNode["c:spPr"]["a:ln"]["a:solidFill"] =
|
|
851
|
+
buildColorNode(seriesData.gradient.stops[0].color)["a:solidFill"];
|
|
852
|
+
}
|
|
853
|
+
}
|
|
854
|
+
else if (seriesColor) {
|
|
855
|
+
seriesNode["c:spPr"]["a:solidFill"] =
|
|
856
|
+
buildColorNode(seriesColor)["a:solidFill"];
|
|
857
|
+
seriesNode["c:spPr"]["a:ln"]["a:solidFill"] =
|
|
858
|
+
buildColorNode(seriesColor)["a:solidFill"];
|
|
859
|
+
}
|
|
860
|
+
else if (index < 6) {
|
|
861
|
+
seriesNode["c:spPr"]["a:solidFill"]["a:schemeClr"].a$.val = "accent".concat(index + 1);
|
|
862
|
+
seriesNode["c:spPr"]["a:ln"]["a:solidFill"]["a:schemeClr"].a$.val = "accent".concat(index + 1);
|
|
863
|
+
}
|
|
864
|
+
if (domainRef) {
|
|
865
|
+
seriesNode["c:cat"]["c:strRef"]["c:f"] = domainRef;
|
|
866
|
+
}
|
|
867
|
+
else {
|
|
868
|
+
removeProp(seriesNode, "c:cat");
|
|
869
|
+
}
|
|
870
|
+
seriesNode["c:val"]["c:numRef"]["c:f"] = ref;
|
|
871
|
+
var labelNode = buildSeriesLabel((_c = seriesData === null || seriesData === void 0 ? void 0 : seriesData.dataLabel) !== null && _c !== void 0 ? _c : undefined, sheetName, seriesData === null || seriesData === void 0 ? void 0 : seriesData.dataLabelRef);
|
|
872
|
+
if (labelNode) {
|
|
873
|
+
seriesNode["c:tx"] = labelNode["c:tx"];
|
|
874
|
+
}
|
|
875
|
+
return seriesNode;
|
|
876
|
+
};
|
|
877
|
+
/**
|
|
878
|
+
* Pie/doughnut templates carry exactly one `c:ser`; a source chart with
|
|
879
|
+
* several series (e.g. seven single-cell slices) silently lost all but the
|
|
880
|
+
* first. Convert the template's ser into an array and append one node per
|
|
881
|
+
* remaining series, each with its own idx/order, name, category and value
|
|
882
|
+
* reference.
|
|
883
|
+
*/
|
|
884
|
+
var appendExtraCircularSeries = function (chartNode, groupKey, seriesRefs, seriesCatRefs, domainRef, series, sheetName) {
|
|
885
|
+
var e_2, _a;
|
|
886
|
+
var _b, _c, _d, _e, _f, _g, _h;
|
|
887
|
+
var group = (_b = chartNode["c:plotArea"]) === null || _b === void 0 ? void 0 : _b[groupKey];
|
|
888
|
+
if (!group)
|
|
889
|
+
return;
|
|
890
|
+
var extra = seriesRefs
|
|
891
|
+
.map(function (ref, index) { return ({ ref: ref, index: index }); })
|
|
892
|
+
.filter(function (_a) {
|
|
893
|
+
var ref = _a.ref, index = _a.index;
|
|
894
|
+
return index > 0 && Boolean(ref);
|
|
895
|
+
});
|
|
896
|
+
if (!extra.length)
|
|
897
|
+
return;
|
|
898
|
+
var firstSer = group["c:ser"];
|
|
899
|
+
var sers = Array.isArray(firstSer) ? firstSer : [firstSer];
|
|
900
|
+
// The template's single ser is series 0; give it its per-series cat when
|
|
901
|
+
// one was captured.
|
|
902
|
+
var firstCat = seriesCatRefs[0];
|
|
903
|
+
if (firstCat && ((_d = (_c = sers[0]) === null || _c === void 0 ? void 0 : _c["c:cat"]) === null || _d === void 0 ? void 0 : _d["c:strRef"])) {
|
|
904
|
+
sers[0]["c:cat"]["c:strRef"]["c:f"] = firstCat;
|
|
905
|
+
}
|
|
906
|
+
try {
|
|
907
|
+
for (var extra_1 = __values(extra), extra_1_1 = extra_1.next(); !extra_1_1.done; extra_1_1 = extra_1.next()) {
|
|
908
|
+
var _j = extra_1_1.value, ref = _j.ref, index = _j.index;
|
|
909
|
+
var node = {
|
|
910
|
+
"c:idx": { a$: { val: String(index) } },
|
|
911
|
+
"c:order": { a$: { val: String(index) } },
|
|
912
|
+
};
|
|
913
|
+
var labelNode = buildSeriesLabel((_f = (_e = series[index]) === null || _e === void 0 ? void 0 : _e.dataLabel) !== null && _f !== void 0 ? _f : undefined, sheetName, (_g = series[index]) === null || _g === void 0 ? void 0 : _g.dataLabelRef);
|
|
914
|
+
if (labelNode) {
|
|
915
|
+
node["c:tx"] = labelNode["c:tx"];
|
|
916
|
+
}
|
|
917
|
+
var catRef = (_h = seriesCatRefs[index]) !== null && _h !== void 0 ? _h : domainRef;
|
|
918
|
+
if (catRef) {
|
|
919
|
+
node["c:cat"] = { "c:strRef": { "c:f": catRef } };
|
|
920
|
+
}
|
|
921
|
+
node["c:val"] = { "c:numRef": { "c:f": ref } };
|
|
922
|
+
sers.push(node);
|
|
923
|
+
}
|
|
924
|
+
}
|
|
925
|
+
catch (e_2_1) { e_2 = { error: e_2_1 }; }
|
|
926
|
+
finally {
|
|
927
|
+
try {
|
|
928
|
+
if (extra_1_1 && !extra_1_1.done && (_a = extra_1.return)) _a.call(extra_1);
|
|
929
|
+
}
|
|
930
|
+
finally { if (e_2) throw e_2.error; }
|
|
931
|
+
}
|
|
932
|
+
group["c:ser"] = sers;
|
|
933
|
+
};
|
|
934
|
+
var buildPieChart = function (domainRef, valueRef, title, subtitle) {
|
|
935
|
+
var pieChart = cloneTemplate(donut_json);
|
|
936
|
+
applyChartTitle(pieChart, title, undefined, subtitle);
|
|
937
|
+
var plotArea = pieChart["c:plotArea"];
|
|
938
|
+
var donut = plotArea["c:doughnutChart"];
|
|
939
|
+
removeProp(donut, "c:holeSize");
|
|
940
|
+
plotArea["c:pieChart"] = donut;
|
|
941
|
+
removeProp(plotArea, "c:doughnutChart");
|
|
942
|
+
var seriesNode = plotArea["c:pieChart"]["c:ser"];
|
|
943
|
+
if (domainRef) {
|
|
944
|
+
seriesNode["c:cat"]["c:strRef"]["c:f"] = domainRef;
|
|
945
|
+
}
|
|
946
|
+
if (valueRef) {
|
|
947
|
+
seriesNode["c:val"]["c:numRef"]["c:f"] = valueRef;
|
|
948
|
+
}
|
|
949
|
+
return pieChart;
|
|
950
|
+
};
|
|
951
|
+
/**
|
|
952
|
+
* Pie-of-pie / bar-of-pie (`<c:ofPieChart>`). Reuses the donut template
|
|
953
|
+
* like buildPieChart but rebuilds the chart-group node so the of-pie
|
|
954
|
+
* elements land in the CT_OfPieChart sequence order: ofPieType,
|
|
955
|
+
* varyColors, ser, dLbls, gapWidth, splitType, splitPos, secondPieSize,
|
|
956
|
+
* serLines. splitType maps the spec vocabulary back to the OOXML
|
|
957
|
+
* tokens (`pos`/`val`/`percent`); `<c:serLines/>` turns on Excel's
|
|
958
|
+
* connector lines between the two plots.
|
|
959
|
+
*/
|
|
960
|
+
var buildOfPieChart = function (domainRef, valueRef, title, spec, subtitle) {
|
|
961
|
+
var chartObj = cloneTemplate(donut_json);
|
|
962
|
+
applyChartTitle(chartObj, title, undefined, subtitle);
|
|
963
|
+
var plotArea = chartObj["c:plotArea"];
|
|
964
|
+
var donut = plotArea["c:doughnutChart"];
|
|
965
|
+
// holeSize and firstSliceAng are pie/doughnut-only — invalid inside
|
|
966
|
+
// <c:ofPieChart>.
|
|
967
|
+
removeProp(donut, "c:holeSize");
|
|
968
|
+
removeProp(donut, "c:firstSliceAng");
|
|
969
|
+
var splitTypeVal = (spec === null || spec === void 0 ? void 0 : spec.splitType) === "position"
|
|
970
|
+
? "pos"
|
|
971
|
+
: (spec === null || spec === void 0 ? void 0 : spec.splitType) === "value"
|
|
972
|
+
? "val"
|
|
973
|
+
: (spec === null || spec === void 0 ? void 0 : spec.splitType) === "percent"
|
|
974
|
+
? "percent"
|
|
975
|
+
: undefined;
|
|
976
|
+
var ofPieNode = __assign(__assign(__assign(__assign({ "c:ofPieType": { a$: { val: (spec === null || spec === void 0 ? void 0 : spec.ofPieType) === "bar" ? "bar" : "pie" } }, "c:varyColors": donut["c:varyColors"], "c:ser": donut["c:ser"], "c:dLbls": donut["c:dLbls"],
|
|
977
|
+
// Excel's default gap between the two plots.
|
|
978
|
+
"c:gapWidth": { a$: { val: "100" } } }, (splitTypeVal ? { "c:splitType": { a$: { val: splitTypeVal } } } : {})), (typeof (spec === null || spec === void 0 ? void 0 : spec.splitPos) === "number" && Number.isFinite(spec.splitPos)
|
|
979
|
+
? { "c:splitPos": { a$: { val: String(spec.splitPos) } } }
|
|
980
|
+
: {})), (typeof (spec === null || spec === void 0 ? void 0 : spec.secondPieSize) === "number" &&
|
|
981
|
+
Number.isFinite(spec.secondPieSize)
|
|
982
|
+
? { "c:secondPieSize": { a$: { val: String(Math.round(spec.secondPieSize)) } } }
|
|
983
|
+
: {})), { "c:serLines": {} });
|
|
984
|
+
plotArea["c:ofPieChart"] = ofPieNode;
|
|
985
|
+
removeProp(plotArea, "c:doughnutChart");
|
|
986
|
+
var seriesNode = ofPieNode["c:ser"];
|
|
987
|
+
if (domainRef) {
|
|
988
|
+
seriesNode["c:cat"]["c:strRef"]["c:f"] = domainRef;
|
|
989
|
+
}
|
|
990
|
+
if (valueRef) {
|
|
991
|
+
seriesNode["c:val"]["c:numRef"]["c:f"] = valueRef;
|
|
992
|
+
}
|
|
993
|
+
return chartObj;
|
|
994
|
+
};
|
|
995
|
+
/**
|
|
996
|
+
* Minimal builder for chart types that follow the line-style template
|
|
997
|
+
* (radar, stock, etc.) — single chart-type container with a flat series
|
|
998
|
+
* list. Reuses the column template and rewrites its barChart block to
|
|
999
|
+
* the target chart-type element. The renderer/Excel handles the rest.
|
|
1000
|
+
*/
|
|
1001
|
+
var buildRadarLikeChart = function (chartElementKey, domainRef, seriesRefs, title, radarStyle, subtitle) {
|
|
1002
|
+
var _a;
|
|
1003
|
+
var chartObj = cloneTemplate(column_json);
|
|
1004
|
+
applyChartTitle(chartObj, title, undefined, subtitle);
|
|
1005
|
+
var plotArea = chartObj["c:plotArea"];
|
|
1006
|
+
var barChart = plotArea["c:barChart"];
|
|
1007
|
+
var axisIds = (_a = barChart === null || barChart === void 0 ? void 0 : barChart["c:axId"]) !== null && _a !== void 0 ? _a : [];
|
|
1008
|
+
var containerNode = {
|
|
1009
|
+
"c:varyColors": { a$: { val: "0" } },
|
|
1010
|
+
"c:ser": [],
|
|
1011
|
+
"c:axId": axisIds,
|
|
1012
|
+
};
|
|
1013
|
+
if (chartElementKey === "c:radarChart") {
|
|
1014
|
+
containerNode["c:radarStyle"] = {
|
|
1015
|
+
a$: { val: radarStyle !== null && radarStyle !== void 0 ? radarStyle : "standard" },
|
|
1016
|
+
};
|
|
1017
|
+
}
|
|
1018
|
+
removeProp(plotArea, "c:barChart");
|
|
1019
|
+
plotArea[chartElementKey] = containerNode;
|
|
1020
|
+
var seriesContainer = containerNode["c:ser"];
|
|
1021
|
+
seriesRefs.forEach(function (ref, index) {
|
|
1022
|
+
if (!ref)
|
|
1023
|
+
return;
|
|
1024
|
+
var seriesNode = {
|
|
1025
|
+
"c:idx": { a$: { val: String(index) } },
|
|
1026
|
+
"c:order": { a$: { val: String(index) } },
|
|
1027
|
+
"c:cat": domainRef
|
|
1028
|
+
? { "c:strRef": { "c:f": domainRef } }
|
|
1029
|
+
: undefined,
|
|
1030
|
+
"c:val": { "c:numRef": { "c:f": ref } },
|
|
1031
|
+
};
|
|
1032
|
+
if (!domainRef)
|
|
1033
|
+
delete seriesNode["c:cat"];
|
|
1034
|
+
seriesContainer.push(seriesNode);
|
|
1035
|
+
});
|
|
1036
|
+
return chartObj;
|
|
1037
|
+
};
|
|
1038
|
+
var buildDoughnutChart = function (domainRef, valueRef, title, subtitle) {
|
|
1039
|
+
// Doughnut uses the same donut_json template as pie but keeps the
|
|
1040
|
+
// <c:doughnutChart> wrapper (and the holeSize, which we set later
|
|
1041
|
+
// via applyDoughnutHole when the spec carries one).
|
|
1042
|
+
var chartObj = cloneTemplate(donut_json);
|
|
1043
|
+
applyChartTitle(chartObj, title, undefined, subtitle);
|
|
1044
|
+
var plotArea = chartObj["c:plotArea"];
|
|
1045
|
+
var seriesNode = plotArea["c:doughnutChart"]["c:ser"];
|
|
1046
|
+
if (domainRef) {
|
|
1047
|
+
seriesNode["c:cat"]["c:strRef"]["c:f"] = domainRef;
|
|
1048
|
+
}
|
|
1049
|
+
if (valueRef) {
|
|
1050
|
+
seriesNode["c:val"]["c:numRef"]["c:f"] = valueRef;
|
|
1051
|
+
}
|
|
1052
|
+
return chartObj;
|
|
1053
|
+
};
|
|
1054
|
+
export var buildChartXml = function (chart, sheetNameById) {
|
|
1055
|
+
var e_3, _a, e_4, _b, e_5, _c;
|
|
1056
|
+
var _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10;
|
|
1057
|
+
var series = (_e = (_d = chart.spec) === null || _d === void 0 ? void 0 : _d.series) !== null && _e !== void 0 ? _e : [];
|
|
1058
|
+
if (!series.length)
|
|
1059
|
+
return undefined;
|
|
1060
|
+
var domainRef = formatSourcesRef((_g = (_f = chart.spec.domains) === null || _f === void 0 ? void 0 : _f[0]) === null || _g === void 0 ? void 0 : _g.sources, sheetNameById);
|
|
1061
|
+
var seriesRefs = series.map(function (entry) {
|
|
1062
|
+
return formatSourcesRef(entry === null || entry === void 0 ? void 0 : entry.sources, sheetNameById);
|
|
1063
|
+
});
|
|
1064
|
+
var seriesCatRefs = series.map(function (entry) {
|
|
1065
|
+
return seriesCategoryRef(entry, sheetNameById);
|
|
1066
|
+
});
|
|
1067
|
+
if (!seriesRefs.some(Boolean))
|
|
1068
|
+
return undefined;
|
|
1069
|
+
var chartType = chart.spec.chartType;
|
|
1070
|
+
var chartTitle = (_h = chart.spec.title) !== null && _h !== void 0 ? _h : undefined;
|
|
1071
|
+
// Subtitle line rendered under the title (e.g. a "Total Value to
|
|
1072
|
+
// Paid-In" caption under "Net MOIC by Fund Vintage"). Emitted as a
|
|
1073
|
+
// second `<a:p>` in the title's rich block — see `applyChartTitle`.
|
|
1074
|
+
var chartSubtitle = (_j = chart.spec.subtitle) !== null && _j !== void 0 ? _j : undefined;
|
|
1075
|
+
// Authored title text formatting (color/font/bold) — round-tripped
|
|
1076
|
+
// back so Excel keeps the styled title we read on import.
|
|
1077
|
+
var chartTitleFmt = (_k = chart.spec.titleTextFormat) !== null && _k !== void 0 ? _k : undefined;
|
|
1078
|
+
var smooth = "smooth" in chart.spec ? chart.spec.smooth : undefined;
|
|
1079
|
+
var chartSpace = cloneTemplate(chart_template);
|
|
1080
|
+
var sheetName = sheetNameById.get(chart.position.sheetId);
|
|
1081
|
+
// Check for combo chart (multiple series chart types)
|
|
1082
|
+
if (isComboChart(series, chartType)) {
|
|
1083
|
+
var groups = groupSeriesByChartType(series, seriesRefs, chartType);
|
|
1084
|
+
// Build combo chart with multiple chart type containers
|
|
1085
|
+
var comboChart = cloneTemplate(column_json);
|
|
1086
|
+
applyChartTitle(comboChart, chartTitle, chartTitleFmt, chartSubtitle);
|
|
1087
|
+
var plotArea = comboChart["c:plotArea"];
|
|
1088
|
+
var baseBarChart = plotArea["c:barChart"];
|
|
1089
|
+
var axisIds = (_l = baseBarChart === null || baseBarChart === void 0 ? void 0 : baseBarChart["c:axId"]) !== null && _l !== void 0 ? _l : [];
|
|
1090
|
+
var dLbls = (_m = baseBarChart === null || baseBarChart === void 0 ? void 0 : baseBarChart["c:dLbls"]) !== null && _m !== void 0 ? _m : {};
|
|
1091
|
+
// Remove the default bar chart - we'll add specific chart types
|
|
1092
|
+
removeProp(plotArea, "c:barChart");
|
|
1093
|
+
try {
|
|
1094
|
+
// Add chart type containers for each group
|
|
1095
|
+
for (var groups_1 = __values(groups), groups_1_1 = groups_1.next(); !groups_1_1.done; groups_1_1 = groups_1.next()) {
|
|
1096
|
+
var _11 = __read(groups_1_1.value, 2), groupType = _11[0], groupSeries = _11[1];
|
|
1097
|
+
if (groupType === "bar" || groupType === "column") {
|
|
1098
|
+
var barChartNode = {
|
|
1099
|
+
"c:barDir": { a$: { val: groupType === "bar" ? "bar" : "col" } },
|
|
1100
|
+
"c:grouping": { a$: { val: "clustered" } },
|
|
1101
|
+
"c:varyColors": { a$: { val: "0" } },
|
|
1102
|
+
"c:ser": [],
|
|
1103
|
+
"c:dLbls": dLbls,
|
|
1104
|
+
"c:axId": axisIds,
|
|
1105
|
+
};
|
|
1106
|
+
for (var i = 0; i < groupSeries.length; i++) {
|
|
1107
|
+
var _12 = groupSeries[i], index = _12.index, ref = _12.ref, data = _12.data;
|
|
1108
|
+
var seriesNode = buildBarSeriesNode(index, ref, data, (_o = seriesCatRefs[index]) !== null && _o !== void 0 ? _o : domainRef, sheetName, i === 0);
|
|
1109
|
+
barChartNode["c:ser"].push(seriesNode);
|
|
1110
|
+
}
|
|
1111
|
+
plotArea["c:barChart"] = barChartNode;
|
|
1112
|
+
}
|
|
1113
|
+
else if (groupType === "line") {
|
|
1114
|
+
var lineChartNode = {
|
|
1115
|
+
"c:grouping": { a$: { val: "standard" } },
|
|
1116
|
+
"c:varyColors": { a$: { val: "0" } },
|
|
1117
|
+
"c:ser": [],
|
|
1118
|
+
"c:dLbls": dLbls,
|
|
1119
|
+
"c:axId": axisIds,
|
|
1120
|
+
};
|
|
1121
|
+
try {
|
|
1122
|
+
for (var groupSeries_1 = (e_4 = void 0, __values(groupSeries)), groupSeries_1_1 = groupSeries_1.next(); !groupSeries_1_1.done; groupSeries_1_1 = groupSeries_1.next()) {
|
|
1123
|
+
var _13 = groupSeries_1_1.value, index = _13.index, ref = _13.ref, data = _13.data;
|
|
1124
|
+
var seriesNode = buildLineSeriesNode(index, ref, data, (_p = seriesCatRefs[index]) !== null && _p !== void 0 ? _p : domainRef, sheetName, smooth);
|
|
1125
|
+
lineChartNode["c:ser"].push(seriesNode);
|
|
1126
|
+
}
|
|
1127
|
+
}
|
|
1128
|
+
catch (e_4_1) { e_4 = { error: e_4_1 }; }
|
|
1129
|
+
finally {
|
|
1130
|
+
try {
|
|
1131
|
+
if (groupSeries_1_1 && !groupSeries_1_1.done && (_b = groupSeries_1.return)) _b.call(groupSeries_1);
|
|
1132
|
+
}
|
|
1133
|
+
finally { if (e_4) throw e_4.error; }
|
|
1134
|
+
}
|
|
1135
|
+
plotArea["c:lineChart"] = lineChartNode;
|
|
1136
|
+
}
|
|
1137
|
+
else if (groupType === "area") {
|
|
1138
|
+
var areaChartNode = {
|
|
1139
|
+
"c:grouping": { a$: { val: "standard" } },
|
|
1140
|
+
"c:varyColors": { a$: { val: "0" } },
|
|
1141
|
+
"c:ser": [],
|
|
1142
|
+
"c:dLbls": dLbls,
|
|
1143
|
+
"c:axId": axisIds,
|
|
1144
|
+
};
|
|
1145
|
+
try {
|
|
1146
|
+
for (var groupSeries_2 = (e_5 = void 0, __values(groupSeries)), groupSeries_2_1 = groupSeries_2.next(); !groupSeries_2_1.done; groupSeries_2_1 = groupSeries_2.next()) {
|
|
1147
|
+
var _14 = groupSeries_2_1.value, index = _14.index, ref = _14.ref, data = _14.data;
|
|
1148
|
+
var seriesNode = buildAreaSeriesNode(index, ref, data, (_q = seriesCatRefs[index]) !== null && _q !== void 0 ? _q : domainRef, sheetName);
|
|
1149
|
+
areaChartNode["c:ser"].push(seriesNode);
|
|
1150
|
+
}
|
|
1151
|
+
}
|
|
1152
|
+
catch (e_5_1) { e_5 = { error: e_5_1 }; }
|
|
1153
|
+
finally {
|
|
1154
|
+
try {
|
|
1155
|
+
if (groupSeries_2_1 && !groupSeries_2_1.done && (_c = groupSeries_2.return)) _c.call(groupSeries_2);
|
|
1156
|
+
}
|
|
1157
|
+
finally { if (e_5) throw e_5.error; }
|
|
1158
|
+
}
|
|
1159
|
+
plotArea["c:areaChart"] = areaChartNode;
|
|
1160
|
+
}
|
|
1161
|
+
}
|
|
1162
|
+
}
|
|
1163
|
+
catch (e_3_1) { e_3 = { error: e_3_1 }; }
|
|
1164
|
+
finally {
|
|
1165
|
+
try {
|
|
1166
|
+
if (groups_1_1 && !groups_1_1.done && (_a = groups_1.return)) _a.call(groups_1);
|
|
1167
|
+
}
|
|
1168
|
+
finally { if (e_3) throw e_3.error; }
|
|
1169
|
+
}
|
|
1170
|
+
chartSpace["c:chartSpace"]["c:chart"] = comboChart;
|
|
1171
|
+
var xml_1 = chartBuilder.build(chartSpace);
|
|
1172
|
+
return "".concat(XML_DECLARATION).concat(xml_1);
|
|
1173
|
+
}
|
|
1174
|
+
// Handle non-combo charts (original logic)
|
|
1175
|
+
if (isC15ChartType(chartType)) {
|
|
1176
|
+
// Histogram / boxplot / waterfall / funnel emit as a barChart for
|
|
1177
|
+
// older Excel compatibility. For histogram (Phase 5.5b), the
|
|
1178
|
+
// barChart is wrapped in mc:AlternateContent with a c15:histogramChart
|
|
1179
|
+
// sibling in mc:Choice — Excel 2016+ uses the c15 chart, older
|
|
1180
|
+
// versions fall back to bar. For boxplot/waterfall/funnel we still
|
|
1181
|
+
// use the c15 extension marker (round-trips in our pipeline; opens
|
|
1182
|
+
// as bar chart in Excel) until those types get the same upgrade.
|
|
1183
|
+
var barChartDoc = cloneTemplate(column_json);
|
|
1184
|
+
applyChartTitle(barChartDoc, chartTitle, chartTitleFmt, chartSubtitle);
|
|
1185
|
+
var bar = barChartDoc["c:plotArea"]["c:barChart"];
|
|
1186
|
+
bar["c:barDir"].a$.val = "col";
|
|
1187
|
+
var seriesContainer_1 = bar["c:ser"];
|
|
1188
|
+
seriesRefs.forEach(function (ref, index) {
|
|
1189
|
+
var _a, _b, _c, _d, _e;
|
|
1190
|
+
if (!ref)
|
|
1191
|
+
return;
|
|
1192
|
+
var seriesNode = cloneTemplate(column_series);
|
|
1193
|
+
seriesNode["c:idx"] = { a$: { val: index.toString() } };
|
|
1194
|
+
seriesNode["c:order"] = { a$: { val: index.toString() } };
|
|
1195
|
+
var seriesColor = (_a = series[index]) === null || _a === void 0 ? void 0 : _a.color;
|
|
1196
|
+
if (applySeriesGradient(seriesNode, (_b = series[index]) === null || _b === void 0 ? void 0 : _b.gradient)) {
|
|
1197
|
+
// Gradient applied; nothing else.
|
|
1198
|
+
}
|
|
1199
|
+
else if (seriesColor) {
|
|
1200
|
+
seriesNode["c:spPr"]["a:solidFill"] =
|
|
1201
|
+
buildColorNode(seriesColor)["a:solidFill"];
|
|
1202
|
+
}
|
|
1203
|
+
else if (index < 6) {
|
|
1204
|
+
seriesNode["c:spPr"]["a:solidFill"]["a:schemeClr"].a$.val = "accent".concat(index + 1);
|
|
1205
|
+
}
|
|
1206
|
+
if (!index && domainRef) {
|
|
1207
|
+
seriesNode["c:cat"] = {
|
|
1208
|
+
"c:strRef": {
|
|
1209
|
+
"c:f": domainRef,
|
|
1210
|
+
},
|
|
1211
|
+
};
|
|
1212
|
+
}
|
|
1213
|
+
seriesNode["c:val"]["c:numRef"]["c:f"] = ref;
|
|
1214
|
+
var labelNode = buildSeriesLabel((_d = (_c = series[index]) === null || _c === void 0 ? void 0 : _c.dataLabel) !== null && _d !== void 0 ? _d : undefined, sheetNameById.get(chart.position.sheetId), (_e = series[index]) === null || _e === void 0 ? void 0 : _e.dataLabelRef);
|
|
1215
|
+
if (labelNode) {
|
|
1216
|
+
seriesNode["c:tx"] = labelNode["c:tx"];
|
|
1217
|
+
}
|
|
1218
|
+
seriesContainer_1.push(seriesNode);
|
|
1219
|
+
});
|
|
1220
|
+
// Phase 5.5b: wrap the bar chart in mc:AlternateContent and emit
|
|
1221
|
+
// a full c15:* chart in mc:Choice so Excel 2016+ renders natively.
|
|
1222
|
+
// c:catAx / c:valAx stay at c:plotArea level — both Choice and
|
|
1223
|
+
// Fallback reference them through matching axId values.
|
|
1224
|
+
var axIdNodes = bar["c:axId"];
|
|
1225
|
+
var catAxId = (_t = (_s = (_r = axIdNodes === null || axIdNodes === void 0 ? void 0 : axIdNodes[0]) === null || _r === void 0 ? void 0 : _r.a$) === null || _s === void 0 ? void 0 : _s.val) !== null && _t !== void 0 ? _t : "1";
|
|
1226
|
+
var valAxId = (_w = (_v = (_u = axIdNodes === null || axIdNodes === void 0 ? void 0 : axIdNodes[1]) === null || _u === void 0 ? void 0 : _u.a$) === null || _v === void 0 ? void 0 : _v.val) !== null && _w !== void 0 ? _w : "2";
|
|
1227
|
+
var c15Args = {
|
|
1228
|
+
seriesRefs: seriesRefs,
|
|
1229
|
+
series: series,
|
|
1230
|
+
domainRef: domainRef,
|
|
1231
|
+
axIds: { catAxId: catAxId, valAxId: valAxId },
|
|
1232
|
+
};
|
|
1233
|
+
var c15Chart = void 0;
|
|
1234
|
+
if (chartType === "histogram") {
|
|
1235
|
+
c15Chart = buildC15HistogramChartNode(chart.spec, c15Args.seriesRefs, c15Args.series, c15Args.domainRef, c15Args.axIds);
|
|
1236
|
+
}
|
|
1237
|
+
else if (chartType === "boxplot") {
|
|
1238
|
+
c15Chart = buildC15BoxplotChartNode(chart.spec, c15Args.seriesRefs, c15Args.series, c15Args.domainRef, c15Args.axIds);
|
|
1239
|
+
}
|
|
1240
|
+
else if (chartType === "waterfall") {
|
|
1241
|
+
c15Chart = buildC15WaterfallChartNode(chart.spec, c15Args.seriesRefs, c15Args.series, c15Args.domainRef, c15Args.axIds);
|
|
1242
|
+
}
|
|
1243
|
+
else {
|
|
1244
|
+
c15Chart = buildC15FunnelChartNode(chart.spec, c15Args.seriesRefs, c15Args.series, c15Args.domainRef, c15Args.axIds);
|
|
1245
|
+
}
|
|
1246
|
+
var altContent = buildC15AlternateContent(chartType, c15Chart, bar);
|
|
1247
|
+
removeProp(barChartDoc["c:plotArea"], "c:barChart");
|
|
1248
|
+
barChartDoc["c:plotArea"]["mc:AlternateContent"] = altContent;
|
|
1249
|
+
chartSpace["c:chartSpace"]["c:chart"] = barChartDoc;
|
|
1250
|
+
}
|
|
1251
|
+
else if (chartType === "bar" || chartType === "column") {
|
|
1252
|
+
var barChart = cloneTemplate(column_json);
|
|
1253
|
+
applyChartTitle(barChart, chartTitle, chartTitleFmt, chartSubtitle);
|
|
1254
|
+
var bar = barChart["c:plotArea"]["c:barChart"];
|
|
1255
|
+
bar["c:barDir"].a$.val = chartType === "bar" ? "bar" : "col";
|
|
1256
|
+
// Grouping / overlap / gapWidth — Excel's stacked / percent-stacked
|
|
1257
|
+
// bars need these set. Excel's defaults are `clustered` + overlap=0
|
|
1258
|
+
// + gapWidth=150; we only emit when the spec actually carries a
|
|
1259
|
+
// value to avoid bloating the file.
|
|
1260
|
+
var stackedType = chart.spec.stackedType;
|
|
1261
|
+
if (stackedType === "STACKED") {
|
|
1262
|
+
bar["c:grouping"] = { a$: { val: "stacked" } };
|
|
1263
|
+
}
|
|
1264
|
+
else if (stackedType === "PERCENT_STACKED") {
|
|
1265
|
+
bar["c:grouping"] = { a$: { val: "percentStacked" } };
|
|
1266
|
+
}
|
|
1267
|
+
else if (stackedType === "UNSTACKED") {
|
|
1268
|
+
bar["c:grouping"] = { a$: { val: "clustered" } };
|
|
1269
|
+
}
|
|
1270
|
+
var overlap = chart.spec.overlap;
|
|
1271
|
+
if (typeof overlap === "number") {
|
|
1272
|
+
bar["c:overlap"] = { a$: { val: String(Math.round(overlap)) } };
|
|
1273
|
+
}
|
|
1274
|
+
var gapWidth = chart.spec.gapWidth;
|
|
1275
|
+
if (typeof gapWidth === "number") {
|
|
1276
|
+
bar["c:gapWidth"] = { a$: { val: String(Math.round(gapWidth)) } };
|
|
1277
|
+
}
|
|
1278
|
+
var seriesContainer_2 = bar["c:ser"];
|
|
1279
|
+
// Inline categories — when no cell-range, use the first domain's
|
|
1280
|
+
// inlineValues directly on the first series' c:cat.
|
|
1281
|
+
var inlineDomainValues_1 = (_y = (_x = chart.spec.domains) === null || _x === void 0 ? void 0 : _x[0]) === null || _y === void 0 ? void 0 : _y.inlineValues;
|
|
1282
|
+
seriesRefs.forEach(function (ref, index) {
|
|
1283
|
+
var _a, _b;
|
|
1284
|
+
if (!ref && !((_a = series[index]) === null || _a === void 0 ? void 0 : _a.inlineValues))
|
|
1285
|
+
return;
|
|
1286
|
+
// Decorate the spec entry with the chart-level inline domain so
|
|
1287
|
+
// `buildBarSeriesNode` can emit `<c:strLit>` on the first series.
|
|
1288
|
+
var enrichedSeries = index === 0 && !domainRef && (inlineDomainValues_1 === null || inlineDomainValues_1 === void 0 ? void 0 : inlineDomainValues_1.length)
|
|
1289
|
+
? __assign(__assign({}, series[index]), { inlineDomainValues: inlineDomainValues_1 })
|
|
1290
|
+
: series[index];
|
|
1291
|
+
var seriesNode = buildBarSeriesNode(index, ref !== null && ref !== void 0 ? ref : "", enrichedSeries, (_b = seriesCatRefs[index]) !== null && _b !== void 0 ? _b : domainRef, sheetNameById.get(chart.position.sheetId), index === 0);
|
|
1292
|
+
seriesContainer_2.push(seriesNode);
|
|
1293
|
+
});
|
|
1294
|
+
chartSpace["c:chartSpace"]["c:chart"] = barChart;
|
|
1295
|
+
}
|
|
1296
|
+
else if (chartType === "pie") {
|
|
1297
|
+
var valueRef = seriesRefs.find(Boolean);
|
|
1298
|
+
var specAny = chart.spec;
|
|
1299
|
+
// Pie-of-pie / bar-of-pie round-trips as <c:ofPieChart> when the
|
|
1300
|
+
// spec carries the OF_PIE marker (or an explicit ofPieType).
|
|
1301
|
+
var isOfPie = String((_z = specAny === null || specAny === void 0 ? void 0 : specAny.sourceChartType) !== null && _z !== void 0 ? _z : "").toUpperCase() === "OF_PIE" ||
|
|
1302
|
+
(specAny === null || specAny === void 0 ? void 0 : specAny.ofPieType) === "pie" ||
|
|
1303
|
+
(specAny === null || specAny === void 0 ? void 0 : specAny.ofPieType) === "bar";
|
|
1304
|
+
var pieChart = isOfPie
|
|
1305
|
+
? buildOfPieChart(domainRef, valueRef, chartTitle, specAny, chartSubtitle)
|
|
1306
|
+
: buildPieChart(domainRef, valueRef, chartTitle, chartSubtitle);
|
|
1307
|
+
if (!isOfPie) {
|
|
1308
|
+
appendExtraCircularSeries(pieChart, "c:pieChart", seriesRefs, seriesCatRefs, domainRef, series, sheetNameById.get(chart.position.sheetId));
|
|
1309
|
+
}
|
|
1310
|
+
chartSpace["c:chartSpace"]["c:chart"] = pieChart;
|
|
1311
|
+
}
|
|
1312
|
+
else if (chartType === "doughnut") {
|
|
1313
|
+
var valueRef = seriesRefs.find(Boolean);
|
|
1314
|
+
var doughnutChart = buildDoughnutChart(domainRef, valueRef, chartTitle, chartSubtitle);
|
|
1315
|
+
appendExtraCircularSeries(doughnutChart, "c:doughnutChart", seriesRefs, seriesCatRefs, domainRef, series, sheetNameById.get(chart.position.sheetId));
|
|
1316
|
+
chartSpace["c:chartSpace"]["c:chart"] = doughnutChart;
|
|
1317
|
+
}
|
|
1318
|
+
else if (chartType === "radar") {
|
|
1319
|
+
var radarChart = buildRadarLikeChart("c:radarChart", domainRef, seriesRefs, chartTitle, (_0 = chart.spec.radarStyle) !== null && _0 !== void 0 ? _0 : "standard", chartSubtitle);
|
|
1320
|
+
chartSpace["c:chartSpace"]["c:chart"] = radarChart;
|
|
1321
|
+
}
|
|
1322
|
+
else if (chartType === "stock") {
|
|
1323
|
+
var stockChart = buildRadarLikeChart("c:stockChart", domainRef, seriesRefs, chartTitle, undefined, chartSubtitle);
|
|
1324
|
+
chartSpace["c:chartSpace"]["c:chart"] = stockChart;
|
|
1325
|
+
}
|
|
1326
|
+
else if (chartType === "line") {
|
|
1327
|
+
var lineChart = cloneTemplate(column_json);
|
|
1328
|
+
applyChartTitle(lineChart, chartTitle, chartTitleFmt, chartSubtitle);
|
|
1329
|
+
var plotArea = lineChart["c:plotArea"];
|
|
1330
|
+
var barChart = plotArea["c:barChart"];
|
|
1331
|
+
var lineChartNode = {
|
|
1332
|
+
"c:grouping": {
|
|
1333
|
+
a$: {
|
|
1334
|
+
val: "standard",
|
|
1335
|
+
},
|
|
1336
|
+
},
|
|
1337
|
+
"c:varyColors": {
|
|
1338
|
+
a$: {
|
|
1339
|
+
val: "0",
|
|
1340
|
+
},
|
|
1341
|
+
},
|
|
1342
|
+
"c:ser": [],
|
|
1343
|
+
"c:dLbls": (_1 = barChart === null || barChart === void 0 ? void 0 : barChart["c:dLbls"]) !== null && _1 !== void 0 ? _1 : {},
|
|
1344
|
+
"c:axId": (_2 = barChart === null || barChart === void 0 ? void 0 : barChart["c:axId"]) !== null && _2 !== void 0 ? _2 : [],
|
|
1345
|
+
};
|
|
1346
|
+
removeProp(plotArea, "c:barChart");
|
|
1347
|
+
plotArea["c:lineChart"] = lineChartNode;
|
|
1348
|
+
var seriesContainer_3 = lineChartNode["c:ser"];
|
|
1349
|
+
seriesRefs.forEach(function (ref, index) {
|
|
1350
|
+
var _a, _b, _c, _d, _e;
|
|
1351
|
+
if (!ref)
|
|
1352
|
+
return;
|
|
1353
|
+
var seriesNode = cloneTemplate(line_series);
|
|
1354
|
+
seriesNode["c:idx"] = { a$: { val: index.toString() } };
|
|
1355
|
+
seriesNode["c:order"] = { a$: { val: index.toString() } };
|
|
1356
|
+
var seriesColor = (_a = series[index]) === null || _a === void 0 ? void 0 : _a.color;
|
|
1357
|
+
if (seriesColor) {
|
|
1358
|
+
seriesNode["c:spPr"]["a:ln"]["a:solidFill"] =
|
|
1359
|
+
buildColorNode(seriesColor)["a:solidFill"];
|
|
1360
|
+
}
|
|
1361
|
+
else if (index < 6) {
|
|
1362
|
+
seriesNode["c:spPr"]["a:ln"]["a:solidFill"]["a:schemeClr"].a$.val = "accent".concat(index + 1);
|
|
1363
|
+
}
|
|
1364
|
+
// Category axis is optional - Excel will use numeric indices if not provided
|
|
1365
|
+
var catRef = (_b = seriesCatRefs[index]) !== null && _b !== void 0 ? _b : domainRef;
|
|
1366
|
+
if (catRef) {
|
|
1367
|
+
seriesNode["c:cat"]["c:strRef"]["c:f"] = catRef;
|
|
1368
|
+
}
|
|
1369
|
+
else {
|
|
1370
|
+
// Remove the category reference if no domain
|
|
1371
|
+
removeProp(seriesNode, "c:cat");
|
|
1372
|
+
}
|
|
1373
|
+
seriesNode["c:val"]["c:numRef"]["c:f"] = ref;
|
|
1374
|
+
if (smooth) {
|
|
1375
|
+
seriesNode["c:smooth"].a$.val = "1";
|
|
1376
|
+
}
|
|
1377
|
+
var labelNode = buildSeriesLabel((_d = (_c = series[index]) === null || _c === void 0 ? void 0 : _c.dataLabel) !== null && _d !== void 0 ? _d : undefined, sheetNameById.get(chart.position.sheetId), (_e = series[index]) === null || _e === void 0 ? void 0 : _e.dataLabelRef);
|
|
1378
|
+
if (labelNode) {
|
|
1379
|
+
seriesNode["c:tx"] = labelNode["c:tx"];
|
|
1380
|
+
}
|
|
1381
|
+
seriesContainer_3.push(seriesNode);
|
|
1382
|
+
});
|
|
1383
|
+
chartSpace["c:chartSpace"]["c:chart"] = lineChart;
|
|
1384
|
+
}
|
|
1385
|
+
else if (chartType === "area") {
|
|
1386
|
+
var areaChart = cloneTemplate(column_json);
|
|
1387
|
+
applyChartTitle(areaChart, chartTitle, chartTitleFmt, chartSubtitle);
|
|
1388
|
+
var plotArea = areaChart["c:plotArea"];
|
|
1389
|
+
var barChart = plotArea["c:barChart"];
|
|
1390
|
+
var areaChartNode = {
|
|
1391
|
+
"c:grouping": {
|
|
1392
|
+
a$: {
|
|
1393
|
+
val: "standard",
|
|
1394
|
+
},
|
|
1395
|
+
},
|
|
1396
|
+
"c:varyColors": {
|
|
1397
|
+
a$: {
|
|
1398
|
+
val: "0",
|
|
1399
|
+
},
|
|
1400
|
+
},
|
|
1401
|
+
"c:ser": [],
|
|
1402
|
+
"c:dLbls": (_3 = barChart === null || barChart === void 0 ? void 0 : barChart["c:dLbls"]) !== null && _3 !== void 0 ? _3 : {},
|
|
1403
|
+
"c:axId": (_4 = barChart === null || barChart === void 0 ? void 0 : barChart["c:axId"]) !== null && _4 !== void 0 ? _4 : [],
|
|
1404
|
+
};
|
|
1405
|
+
removeProp(plotArea, "c:barChart");
|
|
1406
|
+
plotArea["c:areaChart"] = areaChartNode;
|
|
1407
|
+
var seriesContainer_4 = areaChartNode["c:ser"];
|
|
1408
|
+
seriesRefs.forEach(function (ref, index) {
|
|
1409
|
+
var _a, _b, _c, _d, _e;
|
|
1410
|
+
if (!ref)
|
|
1411
|
+
return;
|
|
1412
|
+
var seriesNode = cloneTemplate(area_series);
|
|
1413
|
+
seriesNode["c:idx"] = { a$: { val: index.toString() } };
|
|
1414
|
+
seriesNode["c:order"] = { a$: { val: index.toString() } };
|
|
1415
|
+
var seriesColor = (_a = series[index]) === null || _a === void 0 ? void 0 : _a.color;
|
|
1416
|
+
if (seriesColor) {
|
|
1417
|
+
seriesNode["c:spPr"]["a:solidFill"] =
|
|
1418
|
+
buildColorNode(seriesColor)["a:solidFill"];
|
|
1419
|
+
seriesNode["c:spPr"]["a:ln"]["a:solidFill"] =
|
|
1420
|
+
buildColorNode(seriesColor)["a:solidFill"];
|
|
1421
|
+
}
|
|
1422
|
+
else if (index < 6) {
|
|
1423
|
+
seriesNode["c:spPr"]["a:solidFill"]["a:schemeClr"].a$.val = "accent".concat(index + 1);
|
|
1424
|
+
seriesNode["c:spPr"]["a:ln"]["a:solidFill"]["a:schemeClr"].a$.val = "accent".concat(index + 1);
|
|
1425
|
+
}
|
|
1426
|
+
// Category axis is optional - Excel will use numeric indices if not provided
|
|
1427
|
+
var catRef = (_b = seriesCatRefs[index]) !== null && _b !== void 0 ? _b : domainRef;
|
|
1428
|
+
if (catRef) {
|
|
1429
|
+
seriesNode["c:cat"]["c:strRef"]["c:f"] = catRef;
|
|
1430
|
+
}
|
|
1431
|
+
else {
|
|
1432
|
+
removeProp(seriesNode, "c:cat");
|
|
1433
|
+
}
|
|
1434
|
+
seriesNode["c:val"]["c:numRef"]["c:f"] = ref;
|
|
1435
|
+
var labelNode = buildSeriesLabel((_d = (_c = series[index]) === null || _c === void 0 ? void 0 : _c.dataLabel) !== null && _d !== void 0 ? _d : undefined, sheetNameById.get(chart.position.sheetId), (_e = series[index]) === null || _e === void 0 ? void 0 : _e.dataLabelRef);
|
|
1436
|
+
if (labelNode) {
|
|
1437
|
+
seriesNode["c:tx"] = labelNode["c:tx"];
|
|
1438
|
+
}
|
|
1439
|
+
seriesContainer_4.push(seriesNode);
|
|
1440
|
+
});
|
|
1441
|
+
chartSpace["c:chartSpace"]["c:chart"] = areaChart;
|
|
1442
|
+
}
|
|
1443
|
+
else if (chartType === "scatter" || chartType === "bubble") {
|
|
1444
|
+
var bubbleSpec = chart.spec;
|
|
1445
|
+
var domainEntries_1 = (_5 = bubbleSpec.domains) !== null && _5 !== void 0 ? _5 : [];
|
|
1446
|
+
var seriesEntries = (_6 = bubbleSpec.series) !== null && _6 !== void 0 ? _6 : [];
|
|
1447
|
+
var bubbleSizeEntries_1 = (_7 = bubbleSpec.bubbleSizes) !== null && _7 !== void 0 ? _7 : [];
|
|
1448
|
+
var bubbleLabelEntries_1 = (_8 = bubbleSpec.bubbleLabels) !== null && _8 !== void 0 ? _8 : [];
|
|
1449
|
+
var seriesContainer_5 = [];
|
|
1450
|
+
var seriesTemplate_1 = chartType === "bubble" ? bubble_series : scatter_series;
|
|
1451
|
+
seriesEntries.forEach(function (entry, index) {
|
|
1452
|
+
var _a, _b, _c, _d, _e, _f;
|
|
1453
|
+
var domainRef = formatRangeRef((_a = getPrimarySource(domainEntries_1[index])) !== null && _a !== void 0 ? _a : getPrimarySource(domainEntries_1[0]), sheetNameById);
|
|
1454
|
+
var valueRef = formatRangeRef(getPrimarySource(entry), sheetNameById);
|
|
1455
|
+
if (!domainRef || !valueRef)
|
|
1456
|
+
return;
|
|
1457
|
+
var seriesNode = cloneTemplate(seriesTemplate_1);
|
|
1458
|
+
seriesNode["c:idx"] = { a$: { val: index.toString() } };
|
|
1459
|
+
seriesNode["c:order"] = { a$: { val: index.toString() } };
|
|
1460
|
+
var seriesColor = entry === null || entry === void 0 ? void 0 : entry.color;
|
|
1461
|
+
if (seriesColor) {
|
|
1462
|
+
if (chartType === "bubble") {
|
|
1463
|
+
seriesNode["c:spPr"]["a:solidFill"] =
|
|
1464
|
+
buildColorNode(seriesColor)["a:solidFill"];
|
|
1465
|
+
}
|
|
1466
|
+
else {
|
|
1467
|
+
seriesNode["c:spPr"]["a:ln"]["a:solidFill"] =
|
|
1468
|
+
buildColorNode(seriesColor)["a:solidFill"];
|
|
1469
|
+
}
|
|
1470
|
+
}
|
|
1471
|
+
else if (index < 6) {
|
|
1472
|
+
var colorNode = chartType === "bubble"
|
|
1473
|
+
? seriesNode["c:spPr"]["a:solidFill"]["a:schemeClr"]
|
|
1474
|
+
: seriesNode["c:spPr"]["a:ln"]["a:solidFill"]["a:schemeClr"];
|
|
1475
|
+
colorNode.a$.val = "accent".concat(index + 1);
|
|
1476
|
+
}
|
|
1477
|
+
seriesNode["c:xVal"]["c:numRef"]["c:f"] = domainRef;
|
|
1478
|
+
seriesNode["c:yVal"]["c:numRef"]["c:f"] = valueRef;
|
|
1479
|
+
if (chartType === "bubble") {
|
|
1480
|
+
var sizeRef = formatRangeRef((_c = (_b = getPrimarySource(bubbleSizeEntries_1[index])) !== null && _b !== void 0 ? _b : getPrimarySource(bubbleSizeEntries_1[0])) !== null && _c !== void 0 ? _c : getPrimarySource(entry), sheetNameById);
|
|
1481
|
+
if (sizeRef) {
|
|
1482
|
+
seriesNode["c:bubbleSize"]["c:numRef"]["c:f"] = sizeRef;
|
|
1483
|
+
}
|
|
1484
|
+
}
|
|
1485
|
+
else if (smooth) {
|
|
1486
|
+
seriesNode["c:smooth"].a$.val = "1";
|
|
1487
|
+
}
|
|
1488
|
+
var labelNode = buildSeriesLabel((_f = (_d = entry === null || entry === void 0 ? void 0 : entry.dataLabel) !== null && _d !== void 0 ? _d : (_e = bubbleLabelEntries_1[index]) === null || _e === void 0 ? void 0 : _e.dataLabel) !== null && _f !== void 0 ? _f : undefined, sheetNameById.get(chart.position.sheetId), entry === null || entry === void 0 ? void 0 : entry.dataLabelRef);
|
|
1489
|
+
if (labelNode) {
|
|
1490
|
+
seriesNode["c:tx"] = labelNode["c:tx"];
|
|
1491
|
+
}
|
|
1492
|
+
seriesContainer_5.push(seriesNode);
|
|
1493
|
+
});
|
|
1494
|
+
if (!seriesContainer_5.length)
|
|
1495
|
+
return undefined;
|
|
1496
|
+
var chartDoc = cloneTemplate(scatter_json);
|
|
1497
|
+
applyChartTitle(chartDoc, chartTitle, chartTitleFmt, chartSubtitle);
|
|
1498
|
+
var plotArea = chartDoc["c:plotArea"];
|
|
1499
|
+
var scatterChart = plotArea["c:scatterChart"];
|
|
1500
|
+
if (chartType === "bubble") {
|
|
1501
|
+
removeProp(plotArea, "c:scatterChart");
|
|
1502
|
+
removeProp(scatterChart, "c:scatterStyle");
|
|
1503
|
+
scatterChart["c:bubbleScale"] = { a$: { val: "100" } };
|
|
1504
|
+
scatterChart["c:showNegBubbles"] = { a$: { val: "0" } };
|
|
1505
|
+
scatterChart["c:sizeRepresents"] = { a$: { val: "area" } };
|
|
1506
|
+
plotArea["c:bubbleChart"] = scatterChart;
|
|
1507
|
+
}
|
|
1508
|
+
else {
|
|
1509
|
+
// <c:scatterStyle> — Excel default is "lineMarker". Round-trip
|
|
1510
|
+
// whatever the spec carries so the connecting line / marker mix
|
|
1511
|
+
// survives re-saving.
|
|
1512
|
+
var scatterStyle = chart.spec.scatterStyle;
|
|
1513
|
+
if (scatterStyle && typeof scatterStyle === "string") {
|
|
1514
|
+
scatterChart["c:scatterStyle"] = { a$: { val: scatterStyle } };
|
|
1515
|
+
}
|
|
1516
|
+
}
|
|
1517
|
+
// Per-series marker — append to each series node that doesn't yet
|
|
1518
|
+
// carry one (scatter/bubble series templates already include a
|
|
1519
|
+
// marker block in many cases; only add when authored).
|
|
1520
|
+
seriesContainer_5.forEach(function (node, i) {
|
|
1521
|
+
var _a, _b;
|
|
1522
|
+
var markerSpec = (_b = (_a = chart.spec.series) === null || _a === void 0 ? void 0 : _a[i]) === null || _b === void 0 ? void 0 : _b.marker;
|
|
1523
|
+
var m = buildMarkerNode(markerSpec);
|
|
1524
|
+
if (m) {
|
|
1525
|
+
node["c:marker"] = m;
|
|
1526
|
+
}
|
|
1527
|
+
});
|
|
1528
|
+
var targetChart = chartType === "bubble" ? plotArea["c:bubbleChart"] : scatterChart;
|
|
1529
|
+
targetChart["c:ser"] = seriesContainer_5;
|
|
1530
|
+
chartSpace["c:chartSpace"]["c:chart"] = chartDoc;
|
|
1531
|
+
}
|
|
1532
|
+
else if (chartType === "treemap" || chartType === "sunburst") {
|
|
1533
|
+
var treeSpec = chart.spec;
|
|
1534
|
+
var labelRef = formatRangeRef(getPrimarySource((_9 = treeSpec.labels) === null || _9 === void 0 ? void 0 : _9[0]), sheetNameById);
|
|
1535
|
+
var sizeRef = formatRangeRef(getPrimarySource((_10 = treeSpec.sizeData) === null || _10 === void 0 ? void 0 : _10[0]), sheetNameById);
|
|
1536
|
+
if (!labelRef || !sizeRef)
|
|
1537
|
+
return undefined;
|
|
1538
|
+
if (chartType === "sunburst") {
|
|
1539
|
+
var pieChart = buildPieChart(labelRef, sizeRef, chartTitle, chartSubtitle);
|
|
1540
|
+
chartSpace["c:chartSpace"]["c:chart"] = pieChart;
|
|
1541
|
+
}
|
|
1542
|
+
else {
|
|
1543
|
+
var columnChart = cloneTemplate(column_json);
|
|
1544
|
+
applyChartTitle(columnChart, chartTitle, chartTitleFmt, chartSubtitle);
|
|
1545
|
+
var bar = columnChart["c:plotArea"]["c:barChart"];
|
|
1546
|
+
var seriesContainer = bar["c:ser"];
|
|
1547
|
+
var seriesNode = cloneTemplate(column_series);
|
|
1548
|
+
seriesNode["c:idx"] = { a$: { val: "0" } };
|
|
1549
|
+
seriesNode["c:order"] = { a$: { val: "0" } };
|
|
1550
|
+
seriesNode["c:cat"] = {
|
|
1551
|
+
"c:strRef": {
|
|
1552
|
+
"c:f": labelRef,
|
|
1553
|
+
},
|
|
1554
|
+
};
|
|
1555
|
+
seriesNode["c:val"]["c:numRef"]["c:f"] = sizeRef;
|
|
1556
|
+
seriesContainer.push(seriesNode);
|
|
1557
|
+
chartSpace["c:chartSpace"]["c:chart"] = columnChart;
|
|
1558
|
+
}
|
|
1559
|
+
}
|
|
1560
|
+
else {
|
|
1561
|
+
return undefined;
|
|
1562
|
+
}
|
|
1563
|
+
// Apply Phase 5.1 formatting (legend, data labels, axis options) to the
|
|
1564
|
+
// assembled chart. These mutate the chart node in place — they're
|
|
1565
|
+
// chartType-agnostic and intentionally run last so per-type branches
|
|
1566
|
+
// don't have to know about them.
|
|
1567
|
+
applyChartFormatting(chartSpace, chart.spec, sheetNameById);
|
|
1568
|
+
// `<c:roundedCorners val="1"/>` lives at the chartSpace root (sibling
|
|
1569
|
+
// of `<c:chart>`). Default per OOXML §21.2.2.183 is `false`; only
|
|
1570
|
+
// emit when the spec opted in so files imported without the element
|
|
1571
|
+
// round-trip cleanly without gaining a spurious one.
|
|
1572
|
+
if (chart.spec.roundedCorners) {
|
|
1573
|
+
chartSpace["c:chartSpace"]["c:roundedCorners"] = { a$: { val: "1" } };
|
|
1574
|
+
}
|
|
1575
|
+
var xml = chartBuilder.build(chartSpace);
|
|
1576
|
+
return "".concat(XML_DECLARATION).concat(xml);
|
|
1577
|
+
};
|
|
1578
|
+
// -------------------------- Phase 5 helpers --------------------------
|
|
1579
|
+
var LEGEND_POS = {
|
|
1580
|
+
top: "t",
|
|
1581
|
+
bottom: "b",
|
|
1582
|
+
left: "l",
|
|
1583
|
+
right: "r",
|
|
1584
|
+
topRight: "tr",
|
|
1585
|
+
};
|
|
1586
|
+
var DLBL_POS = {
|
|
1587
|
+
center: "ctr",
|
|
1588
|
+
inside: "inBase",
|
|
1589
|
+
outside: "outEnd",
|
|
1590
|
+
insideEnd: "inEnd",
|
|
1591
|
+
outsideEnd: "outEnd",
|
|
1592
|
+
bestFit: "bestFit",
|
|
1593
|
+
};
|
|
1594
|
+
var applyChartFormatting = function (chartSpace, spec, sheetNameById) {
|
|
1595
|
+
var _a;
|
|
1596
|
+
var chartNode = (_a = chartSpace === null || chartSpace === void 0 ? void 0 : chartSpace["c:chartSpace"]) === null || _a === void 0 ? void 0 : _a["c:chart"];
|
|
1597
|
+
if (!chartNode)
|
|
1598
|
+
return;
|
|
1599
|
+
applyLegend(chartNode, spec === null || spec === void 0 ? void 0 : spec.legend);
|
|
1600
|
+
var plotArea = chartNode["c:plotArea"];
|
|
1601
|
+
if (!plotArea)
|
|
1602
|
+
return;
|
|
1603
|
+
applyDataLabels(plotArea, spec === null || spec === void 0 ? void 0 : spec.dataLabels);
|
|
1604
|
+
applyAxisOptions(plotArea, spec === null || spec === void 0 ? void 0 : spec.valueAxisOptions, "value");
|
|
1605
|
+
applyAxisOptions(plotArea, spec === null || spec === void 0 ? void 0 : spec.categoryAxisOptions, "category");
|
|
1606
|
+
applyDoughnutHole(plotArea, spec === null || spec === void 0 ? void 0 : spec.doughnutHoleSize);
|
|
1607
|
+
applySeriesOverlays(plotArea, spec === null || spec === void 0 ? void 0 : spec.series, sheetNameById);
|
|
1608
|
+
applySecondaryAxis(plotArea, spec === null || spec === void 0 ? void 0 : spec.secondaryValueAxisOptions);
|
|
1609
|
+
};
|
|
1610
|
+
var SERIES_CONTAINER_KEYS = [
|
|
1611
|
+
"c:barChart",
|
|
1612
|
+
"c:lineChart",
|
|
1613
|
+
"c:pieChart",
|
|
1614
|
+
"c:doughnutChart",
|
|
1615
|
+
"c:areaChart",
|
|
1616
|
+
"c:scatterChart",
|
|
1617
|
+
"c:bubbleChart",
|
|
1618
|
+
];
|
|
1619
|
+
/**
|
|
1620
|
+
* Walk the per-chart-type containers in plotArea and apply trendlines
|
|
1621
|
+
* / errBars to each emitted `<c:ser>`. The series order in spec.series
|
|
1622
|
+
* matches the order emitted by the builder, so we index by position.
|
|
1623
|
+
*/
|
|
1624
|
+
var applySeriesOverlays = function (plotArea, series, sheetNameById) {
|
|
1625
|
+
var e_6, _a, e_7, _b;
|
|
1626
|
+
if (!Array.isArray(series) || !series.length)
|
|
1627
|
+
return;
|
|
1628
|
+
var seriesIndex = 0;
|
|
1629
|
+
try {
|
|
1630
|
+
for (var SERIES_CONTAINER_KEYS_1 = __values(SERIES_CONTAINER_KEYS), SERIES_CONTAINER_KEYS_1_1 = SERIES_CONTAINER_KEYS_1.next(); !SERIES_CONTAINER_KEYS_1_1.done; SERIES_CONTAINER_KEYS_1_1 = SERIES_CONTAINER_KEYS_1.next()) {
|
|
1631
|
+
var key = SERIES_CONTAINER_KEYS_1_1.value;
|
|
1632
|
+
var container = plotArea[key];
|
|
1633
|
+
if (!container)
|
|
1634
|
+
continue;
|
|
1635
|
+
var ser = container["c:ser"];
|
|
1636
|
+
if (!ser)
|
|
1637
|
+
continue;
|
|
1638
|
+
var list = Array.isArray(ser) ? ser : [ser];
|
|
1639
|
+
try {
|
|
1640
|
+
for (var list_1 = (e_7 = void 0, __values(list)), list_1_1 = list_1.next(); !list_1_1.done; list_1_1 = list_1.next()) {
|
|
1641
|
+
var node = list_1_1.value;
|
|
1642
|
+
var data = series[seriesIndex++];
|
|
1643
|
+
if (!data)
|
|
1644
|
+
continue;
|
|
1645
|
+
if (Array.isArray(data.trendlines) && data.trendlines.length) {
|
|
1646
|
+
var built = data.trendlines
|
|
1647
|
+
.map(buildTrendlineNode)
|
|
1648
|
+
.filter(Boolean);
|
|
1649
|
+
// OOXML allows multiple <c:trendline> on a series; preserve the
|
|
1650
|
+
// order from the spec.
|
|
1651
|
+
node["c:trendline"] = built.length === 1 ? built[0] : built;
|
|
1652
|
+
}
|
|
1653
|
+
if (data.errorBars) {
|
|
1654
|
+
var built = buildErrorBarsNode(data.errorBars, sheetNameById);
|
|
1655
|
+
if (built)
|
|
1656
|
+
node["c:errBars"] = built;
|
|
1657
|
+
}
|
|
1658
|
+
}
|
|
1659
|
+
}
|
|
1660
|
+
catch (e_7_1) { e_7 = { error: e_7_1 }; }
|
|
1661
|
+
finally {
|
|
1662
|
+
try {
|
|
1663
|
+
if (list_1_1 && !list_1_1.done && (_b = list_1.return)) _b.call(list_1);
|
|
1664
|
+
}
|
|
1665
|
+
finally { if (e_7) throw e_7.error; }
|
|
1666
|
+
}
|
|
1667
|
+
}
|
|
1668
|
+
}
|
|
1669
|
+
catch (e_6_1) { e_6 = { error: e_6_1 }; }
|
|
1670
|
+
finally {
|
|
1671
|
+
try {
|
|
1672
|
+
if (SERIES_CONTAINER_KEYS_1_1 && !SERIES_CONTAINER_KEYS_1_1.done && (_a = SERIES_CONTAINER_KEYS_1.return)) _a.call(SERIES_CONTAINER_KEYS_1);
|
|
1673
|
+
}
|
|
1674
|
+
finally { if (e_6) throw e_6.error; }
|
|
1675
|
+
}
|
|
1676
|
+
};
|
|
1677
|
+
var buildTrendlineNode = function (t) {
|
|
1678
|
+
var _a;
|
|
1679
|
+
if (!t)
|
|
1680
|
+
return undefined;
|
|
1681
|
+
var node = {};
|
|
1682
|
+
if (t.name) {
|
|
1683
|
+
node["c:name"] = { t$: String(t.name) };
|
|
1684
|
+
}
|
|
1685
|
+
// <c:trendlineType val="linear|exp|log|poly|power|movingAvg"/>
|
|
1686
|
+
node["c:trendlineType"] = {
|
|
1687
|
+
a$: { val: (_a = t.type) !== null && _a !== void 0 ? _a : "linear" },
|
|
1688
|
+
};
|
|
1689
|
+
if (t.type === "poly" && typeof t.order === "number") {
|
|
1690
|
+
node["c:order"] = { a$: { val: String(t.order) } };
|
|
1691
|
+
}
|
|
1692
|
+
if (t.type === "movingAvg" && typeof t.period === "number") {
|
|
1693
|
+
node["c:period"] = { a$: { val: String(t.period) } };
|
|
1694
|
+
}
|
|
1695
|
+
if (typeof t.forecastForward === "number") {
|
|
1696
|
+
node["c:forward"] = { a$: { val: String(t.forecastForward) } };
|
|
1697
|
+
}
|
|
1698
|
+
if (typeof t.forecastBackward === "number") {
|
|
1699
|
+
node["c:backward"] = { a$: { val: String(t.forecastBackward) } };
|
|
1700
|
+
}
|
|
1701
|
+
if (t.showEquation) {
|
|
1702
|
+
node["c:dispEq"] = { a$: { val: "1" } };
|
|
1703
|
+
}
|
|
1704
|
+
if (t.showRSquared) {
|
|
1705
|
+
node["c:dispRSqr"] = { a$: { val: "1" } };
|
|
1706
|
+
}
|
|
1707
|
+
return node;
|
|
1708
|
+
};
|
|
1709
|
+
var buildErrorBarsNode = function (eb, sheetNameById) {
|
|
1710
|
+
var _a, _b, _c;
|
|
1711
|
+
if (!eb)
|
|
1712
|
+
return undefined;
|
|
1713
|
+
var node = {};
|
|
1714
|
+
if (eb.direction === "x" || eb.direction === "y") {
|
|
1715
|
+
node["c:errDir"] = { a$: { val: eb.direction } };
|
|
1716
|
+
}
|
|
1717
|
+
node["c:errBarType"] = { a$: { val: (_a = eb.barType) !== null && _a !== void 0 ? _a : "both" } };
|
|
1718
|
+
var valueType = eb.valueType === "custom" ? "cust" : eb.valueType;
|
|
1719
|
+
node["c:errValType"] = { a$: { val: valueType !== null && valueType !== void 0 ? valueType : "fixedVal" } };
|
|
1720
|
+
if (eb.noEndCap) {
|
|
1721
|
+
node["c:noEndCap"] = { a$: { val: "1" } };
|
|
1722
|
+
}
|
|
1723
|
+
// Custom error bars — per-point magnitudes come from worksheet
|
|
1724
|
+
// ranges emitted as `<c:plus>/<c:minus>` numRefs. Schema order puts
|
|
1725
|
+
// them after noEndCap and before `<c:val>`.
|
|
1726
|
+
if (valueType === "cust") {
|
|
1727
|
+
var plusRef = formatRangeRef((_b = eb.plusRange) !== null && _b !== void 0 ? _b : undefined, sheetNameById);
|
|
1728
|
+
var minusRef = formatRangeRef((_c = eb.minusRange) !== null && _c !== void 0 ? _c : undefined, sheetNameById);
|
|
1729
|
+
if (plusRef) {
|
|
1730
|
+
node["c:plus"] = { "c:numRef": { "c:f": plusRef } };
|
|
1731
|
+
}
|
|
1732
|
+
if (minusRef) {
|
|
1733
|
+
node["c:minus"] = { "c:numRef": { "c:f": minusRef } };
|
|
1734
|
+
}
|
|
1735
|
+
}
|
|
1736
|
+
if (typeof eb.value === "number") {
|
|
1737
|
+
node["c:val"] = { a$: { val: String(eb.value) } };
|
|
1738
|
+
}
|
|
1739
|
+
return node;
|
|
1740
|
+
};
|
|
1741
|
+
/**
|
|
1742
|
+
* Add a secondary `<c:valAx>` next to the primary one when the spec
|
|
1743
|
+
* carries `secondaryValueAxisOptions`. We give it a distinct axId
|
|
1744
|
+
* (existing primary axId + 100) — series-level routing to the new axis
|
|
1745
|
+
* is intentionally not wired up here (most consumers of "secondary
|
|
1746
|
+
* axis" only care about the data round-trip; full charting fidelity
|
|
1747
|
+
* lands in a follow-up).
|
|
1748
|
+
*/
|
|
1749
|
+
var applySecondaryAxis = function (plotArea, opts) {
|
|
1750
|
+
var _a, _b, _c;
|
|
1751
|
+
if (!opts)
|
|
1752
|
+
return;
|
|
1753
|
+
var existing = plotArea["c:valAx"];
|
|
1754
|
+
if (!existing)
|
|
1755
|
+
return;
|
|
1756
|
+
var existingArr = Array.isArray(existing) ? existing : [existing];
|
|
1757
|
+
if (existingArr.length >= 2)
|
|
1758
|
+
return; // already has secondary
|
|
1759
|
+
var primary = existingArr[0];
|
|
1760
|
+
var primaryAxId = parseInt(((_c = (_b = (_a = primary === null || primary === void 0 ? void 0 : primary["c:axId"]) === null || _a === void 0 ? void 0 : _a.a$) === null || _b === void 0 ? void 0 : _b.val) !== null && _c !== void 0 ? _c : "1000"), 10);
|
|
1761
|
+
var secondary = {
|
|
1762
|
+
"c:axId": { a$: { val: String(primaryAxId + 100) } },
|
|
1763
|
+
"c:scaling": { "c:orientation": { a$: { val: "minMax" } } },
|
|
1764
|
+
"c:delete": { a$: { val: "0" } },
|
|
1765
|
+
"c:axPos": { a$: { val: "r" } },
|
|
1766
|
+
"c:crossAx": { a$: { val: String(primaryAxId) } },
|
|
1767
|
+
};
|
|
1768
|
+
// Apply the same logarithmic / reverse / min / max / gridlines etc.
|
|
1769
|
+
applyAxisOptions({ "c:valAx": secondary }, opts, "value");
|
|
1770
|
+
plotArea["c:valAx"] = __spreadArray(__spreadArray([], __read(existingArr), false), [secondary], false);
|
|
1771
|
+
};
|
|
1772
|
+
var applyLegend = function (chartNode, legend) {
|
|
1773
|
+
var _a;
|
|
1774
|
+
if (!legend)
|
|
1775
|
+
return;
|
|
1776
|
+
if (legend.position === "none") {
|
|
1777
|
+
// Excel omits <c:legend> entirely when hidden; some readers expect
|
|
1778
|
+
// an explicit <c:legend><c:delete val="1"/> instead. Use the
|
|
1779
|
+
// explicit form so the suppression survives ANY reader.
|
|
1780
|
+
chartNode["c:legend"] = {
|
|
1781
|
+
"c:delete": { a$: { val: "1" } },
|
|
1782
|
+
};
|
|
1783
|
+
return;
|
|
1784
|
+
}
|
|
1785
|
+
var posCode = LEGEND_POS[legend.position];
|
|
1786
|
+
var txPr = buildTxPrNode(legend.textFormat);
|
|
1787
|
+
if (!posCode) {
|
|
1788
|
+
// No explicit position — just ensure the legend element exists,
|
|
1789
|
+
// attach text formatting if authored.
|
|
1790
|
+
var existing = (_a = chartNode["c:legend"]) !== null && _a !== void 0 ? _a : {};
|
|
1791
|
+
if (txPr)
|
|
1792
|
+
existing["c:txPr"] = txPr;
|
|
1793
|
+
chartNode["c:legend"] = existing;
|
|
1794
|
+
return;
|
|
1795
|
+
}
|
|
1796
|
+
chartNode["c:legend"] = __assign({ "c:legendPos": { a$: { val: posCode } }, "c:overlay": { a$: { val: "0" } } }, (txPr ? { "c:txPr": txPr } : {}));
|
|
1797
|
+
};
|
|
1798
|
+
var applyDataLabels = function (plotArea, dataLabels) {
|
|
1799
|
+
if (!(dataLabels === null || dataLabels === void 0 ? void 0 : dataLabels.show))
|
|
1800
|
+
return;
|
|
1801
|
+
// Find the chart-type container inside <c:plotArea>. We attach <c:dLbls>
|
|
1802
|
+
// to whichever exists.
|
|
1803
|
+
var containerKey = [
|
|
1804
|
+
"c:barChart",
|
|
1805
|
+
"c:lineChart",
|
|
1806
|
+
"c:pieChart",
|
|
1807
|
+
"c:doughnutChart",
|
|
1808
|
+
"c:areaChart",
|
|
1809
|
+
].find(function (k) { return plotArea[k]; });
|
|
1810
|
+
if (!containerKey)
|
|
1811
|
+
return;
|
|
1812
|
+
var container = plotArea[containerKey];
|
|
1813
|
+
var posCode = dataLabels.position && DLBL_POS[dataLabels.position];
|
|
1814
|
+
var dLbls = {};
|
|
1815
|
+
if (posCode)
|
|
1816
|
+
dLbls["c:dLblPos"] = { a$: { val: posCode } };
|
|
1817
|
+
// <c:numFmt> — emit before the show* flags. Excel reads this to
|
|
1818
|
+
// format the label value (e.g. `"$"#,##0` → "$1,831").
|
|
1819
|
+
if (dataLabels.numberFormatPattern) {
|
|
1820
|
+
dLbls["c:numFmt"] = {
|
|
1821
|
+
a$: {
|
|
1822
|
+
formatCode: dataLabels.numberFormatPattern,
|
|
1823
|
+
sourceLinked: "0",
|
|
1824
|
+
},
|
|
1825
|
+
};
|
|
1826
|
+
}
|
|
1827
|
+
// <c:txPr> — authored color / font / bold for the label text.
|
|
1828
|
+
var txPr = buildTxPrNode(dataLabels.textFormat);
|
|
1829
|
+
if (txPr)
|
|
1830
|
+
dLbls["c:txPr"] = txPr;
|
|
1831
|
+
// OOXML requires explicit boolean flags. When none of show* are set,
|
|
1832
|
+
// default to showVal=1 since that's Excel's default for "Show Labels".
|
|
1833
|
+
var showValue = dataLabels.showValue === undefined
|
|
1834
|
+
? !dataLabels.showCategoryName &&
|
|
1835
|
+
!dataLabels.showPercent &&
|
|
1836
|
+
!dataLabels.showSeriesName
|
|
1837
|
+
: !!dataLabels.showValue;
|
|
1838
|
+
dLbls["c:showLegendKey"] = { a$: { val: "0" } };
|
|
1839
|
+
dLbls["c:showVal"] = { a$: { val: showValue ? "1" : "0" } };
|
|
1840
|
+
dLbls["c:showCatName"] = {
|
|
1841
|
+
a$: { val: dataLabels.showCategoryName ? "1" : "0" },
|
|
1842
|
+
};
|
|
1843
|
+
dLbls["c:showSerName"] = {
|
|
1844
|
+
a$: { val: dataLabels.showSeriesName ? "1" : "0" },
|
|
1845
|
+
};
|
|
1846
|
+
dLbls["c:showPercent"] = {
|
|
1847
|
+
a$: { val: dataLabels.showPercent ? "1" : "0" },
|
|
1848
|
+
};
|
|
1849
|
+
dLbls["c:showBubbleSize"] = { a$: { val: "0" } };
|
|
1850
|
+
container["c:dLbls"] = dLbls;
|
|
1851
|
+
};
|
|
1852
|
+
var applyAxisOptions = function (plotArea, options, kind) {
|
|
1853
|
+
var _a;
|
|
1854
|
+
if (!options)
|
|
1855
|
+
return;
|
|
1856
|
+
var axisKey = kind === "value" ? "c:valAx" : "c:catAx";
|
|
1857
|
+
var ax = plotArea[axisKey];
|
|
1858
|
+
if (!ax)
|
|
1859
|
+
return;
|
|
1860
|
+
// OOXML can carry multiple axes (e.g. primary + secondary). Target the
|
|
1861
|
+
// first one for now — secondary axes ship in Phase 5.2.
|
|
1862
|
+
var node = Array.isArray(ax) ? ax[0] : ax;
|
|
1863
|
+
var scaling = (node["c:scaling"] = (_a = node["c:scaling"]) !== null && _a !== void 0 ? _a : {});
|
|
1864
|
+
if (options.logarithmic) {
|
|
1865
|
+
scaling["c:logBase"] = { a$: { val: "10" } };
|
|
1866
|
+
}
|
|
1867
|
+
if (options.reverse) {
|
|
1868
|
+
scaling["c:orientation"] = { a$: { val: "maxMin" } };
|
|
1869
|
+
}
|
|
1870
|
+
if (typeof options.min === "number") {
|
|
1871
|
+
scaling["c:min"] = { a$: { val: String(options.min) } };
|
|
1872
|
+
}
|
|
1873
|
+
if (typeof options.max === "number") {
|
|
1874
|
+
scaling["c:max"] = { a$: { val: String(options.max) } };
|
|
1875
|
+
}
|
|
1876
|
+
if (options.visible === false) {
|
|
1877
|
+
node["c:delete"] = { a$: { val: "1" } };
|
|
1878
|
+
}
|
|
1879
|
+
if (options.showMajorGridlines === true && !node["c:majorGridlines"]) {
|
|
1880
|
+
node["c:majorGridlines"] = {};
|
|
1881
|
+
}
|
|
1882
|
+
if (options.showMajorGridlines === false && node["c:majorGridlines"]) {
|
|
1883
|
+
delete node["c:majorGridlines"];
|
|
1884
|
+
}
|
|
1885
|
+
// <c:txPr> — axis tick-label color/font. Without this, exported
|
|
1886
|
+
// axes would render with the default theme color instead of the
|
|
1887
|
+
// authored one (BEP.xlsx axis colors #14325A / #F0621C).
|
|
1888
|
+
var txPr = buildTxPrNode(options.textFormat);
|
|
1889
|
+
if (txPr)
|
|
1890
|
+
node["c:txPr"] = txPr;
|
|
1891
|
+
};
|
|
1892
|
+
var applyDoughnutHole = function (plotArea, holeSize) {
|
|
1893
|
+
if (typeof holeSize !== "number")
|
|
1894
|
+
return;
|
|
1895
|
+
var doughnut = plotArea["c:doughnutChart"];
|
|
1896
|
+
if (!doughnut)
|
|
1897
|
+
return;
|
|
1898
|
+
// Convert 0-1 fraction back to OOXML's 0-90 percentage.
|
|
1899
|
+
var pct = Math.round(Math.max(0, Math.min(0.9, holeSize)) * 100);
|
|
1900
|
+
doughnut["c:holeSize"] = { a$: { val: String(pct) } };
|
|
1901
|
+
};
|