ooxml-core 1.12.2 → 1.14.0
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/dist/PptxHandler-5YP75BPO.cjs +12 -0
- package/dist/PptxHandler-GT5Q66TG.mjs +3 -0
- package/dist/{PptxHandler-FIN6XDTI.mjs → PptxHandler-KNBFECUE.mjs} +3 -3
- package/dist/PresentationBuilder-5DCCFHWJ.mjs +7 -0
- package/dist/PresentationBuilder-CVM6LJ7L.mjs +3 -0
- package/dist/PresentationBuilder-II7C4A3R.cjs +20 -0
- package/dist/automation/docx.d.ts +18 -0
- package/dist/automation/docx.d.ts.map +1 -1
- package/dist/automation/index.cjs +22549 -8585
- package/dist/automation/index.d.ts +1 -0
- package/dist/automation/index.d.ts.map +1 -1
- package/dist/automation/index.mjs +22546 -8586
- package/dist/automation/node.cjs +66 -6
- package/dist/automation/node.d.ts +10 -0
- package/dist/automation/node.d.ts.map +1 -1
- package/dist/automation/node.mjs +67 -7
- package/dist/automation/outline.d.ts +29 -0
- package/dist/automation/outline.d.ts.map +1 -0
- package/dist/automation/xlsx.d.ts +21 -0
- package/dist/automation/xlsx.d.ts.map +1 -1
- package/dist/chart/auto-title.d.ts +31 -0
- package/dist/chart/auto-title.d.ts.map +1 -0
- package/dist/chart/axis-format.d.ts +13 -0
- package/dist/chart/axis-format.d.ts.map +1 -0
- package/dist/chart/bubble-radius.d.ts +30 -0
- package/dist/chart/bubble-radius.d.ts.map +1 -0
- package/dist/chart/error-bar-amount.d.ts +22 -0
- package/dist/chart/error-bar-amount.d.ts.map +1 -0
- package/dist/chart/hierarchy.d.ts +69 -0
- package/dist/chart/hierarchy.d.ts.map +1 -0
- package/dist/chart/index.cjs +2377 -527
- package/dist/chart/index.d.ts +12 -0
- package/dist/chart/index.d.ts.map +1 -1
- package/dist/chart/index.mjs +2338 -528
- package/dist/chart/model-analysis.d.ts +66 -0
- package/dist/chart/model-analysis.d.ts.map +1 -0
- package/dist/chart/model-series.d.ts +5 -0
- package/dist/chart/model-series.d.ts.map +1 -1
- package/dist/chart/number-format-pattern.d.ts +35 -0
- package/dist/chart/number-format-pattern.d.ts.map +1 -0
- package/dist/chart/number-format.d.ts +21 -0
- package/dist/chart/number-format.d.ts.map +1 -0
- package/dist/chart/parse-analysis.d.ts +13 -0
- package/dist/chart/parse-analysis.d.ts.map +1 -0
- package/dist/chart/parse-series.d.ts +1 -1
- package/dist/chart/parse-series.d.ts.map +1 -1
- package/dist/chart/parse-util.d.ts +2 -0
- package/dist/chart/parse-util.d.ts.map +1 -1
- package/dist/chart/render/chart-svg-analysis.d.ts +7 -0
- package/dist/chart/render/chart-svg-analysis.d.ts.map +1 -0
- package/dist/chart/render/chart-svg-bars.d.ts +5 -0
- package/dist/chart/render/chart-svg-bars.d.ts.map +1 -1
- package/dist/chart/render/chart-svg-cartesian.d.ts +7 -2
- package/dist/chart/render/chart-svg-cartesian.d.ts.map +1 -1
- package/dist/chart/render/chart-svg-hierarchy.d.ts +5 -0
- package/dist/chart/render/chart-svg-hierarchy.d.ts.map +1 -0
- package/dist/chart/render/chart-svg-plots.d.ts +5 -0
- package/dist/chart/render/chart-svg-plots.d.ts.map +1 -0
- package/dist/chart/render/chart-svg-stock.d.ts +4 -0
- package/dist/chart/render/chart-svg-stock.d.ts.map +1 -0
- package/dist/chart/render/chart-svg-waterfall.d.ts +4 -0
- package/dist/chart/render/chart-svg-waterfall.d.ts.map +1 -0
- package/dist/chart/render/chart-svg-xy.d.ts +4 -0
- package/dist/chart/render/chart-svg-xy.d.ts.map +1 -0
- package/dist/chart/render/chart-svg.d.ts +1 -1
- package/dist/chart/render/chart-svg.d.ts.map +1 -1
- package/dist/chart/render/chart-value-axis.d.ts +6 -1
- package/dist/chart/render/chart-value-axis.d.ts.map +1 -1
- package/dist/chart/render/chart-view-analysis.d.ts +30 -0
- package/dist/chart/render/chart-view-analysis.d.ts.map +1 -0
- package/dist/chart/render/chart-view-ex.d.ts +24 -0
- package/dist/chart/render/chart-view-ex.d.ts.map +1 -0
- package/dist/chart/render/chart-view-families.d.ts +10 -0
- package/dist/chart/render/chart-view-families.d.ts.map +1 -0
- package/dist/chart/render/chart-view-series.d.ts +36 -0
- package/dist/chart/render/chart-view-series.d.ts.map +1 -0
- package/dist/chart/render/chart-view-stock.d.ts +23 -0
- package/dist/chart/render/chart-view-stock.d.ts.map +1 -0
- package/dist/chart/render/chart-view.d.ts +49 -18
- package/dist/chart/render/chart-view.d.ts.map +1 -1
- package/dist/chart/render/index.d.ts +2 -0
- package/dist/chart/render/index.d.ts.map +1 -1
- package/dist/chart/render/render-space.d.ts +6 -1
- package/dist/chart/render/render-space.d.ts.map +1 -1
- package/dist/chart/render/summary-analysis.d.ts +11 -0
- package/dist/chart/render/summary-analysis.d.ts.map +1 -0
- package/dist/chart/render/summary-from-chartex.d.ts +11 -0
- package/dist/chart/render/summary-from-chartex.d.ts.map +1 -0
- package/dist/chart/render/summary-from-space.d.ts.map +1 -1
- package/dist/chart/render/summary.d.ts +86 -3
- package/dist/chart/render/summary.d.ts.map +1 -1
- package/dist/chart/stock-candles.d.ts +72 -0
- package/dist/chart/stock-candles.d.ts.map +1 -0
- package/dist/chart/style-palette.d.ts +29 -0
- package/dist/chart/style-palette.d.ts.map +1 -0
- package/dist/chart/sunburst-arcs.d.ts +41 -0
- package/dist/chart/sunburst-arcs.d.ts.map +1 -0
- package/dist/chart/trendline-fit.d.ts +39 -0
- package/dist/chart/trendline-fit.d.ts.map +1 -0
- package/dist/chart/waterfall.d.ts +31 -0
- package/dist/chart/waterfall.d.ts.map +1 -0
- package/dist/chart/write-analysis.d.ts +12 -0
- package/dist/chart/write-analysis.d.ts.map +1 -0
- package/dist/chart/write-series.d.ts.map +1 -1
- package/dist/{chunk-G5PQKHCG.mjs → chunk-2D4IFQ5M.mjs} +1 -1
- package/dist/{chunk-UAY26XOI.mjs → chunk-2EBMHIGJ.mjs} +1303 -994
- package/dist/{chunk-TVE6UIJF.mjs → chunk-4WZLFUUA.mjs} +54 -13
- package/dist/{chunk-H2FRDUNV.mjs → chunk-54ASP65T.mjs} +868 -585
- package/dist/chunk-M4XLF4R7.mjs +387 -0
- package/dist/{chunk-O6NIA4NG.mjs → chunk-ORH32TO3.mjs} +5798 -5742
- package/dist/{chunk-B2JBBAEQ.mjs → chunk-TNNXOW2O.mjs} +1 -1
- package/dist/{chunk-IT3U6QD6.cjs → chunk-TQE7FFNT.cjs} +6754 -6695
- package/dist/{chunk-7QZGRB3T.cjs → chunk-X7MGZQ6C.cjs} +1321 -995
- package/dist/{chunk-6DELVMYB.mjs → chunk-XGXIS4PN.mjs} +12316 -12260
- package/dist/crypto/decrypt.d.ts +17 -3
- package/dist/crypto/decrypt.d.ts.map +1 -1
- package/dist/crypto/encryption-info.d.ts.map +1 -1
- package/dist/crypto/index.cjs +252 -78
- package/dist/crypto/index.d.ts +19 -4
- package/dist/crypto/index.d.ts.map +1 -1
- package/dist/crypto/index.mjs +252 -79
- package/dist/crypto/key-derivation.d.ts +2 -3
- package/dist/crypto/key-derivation.d.ts.map +1 -1
- package/dist/crypto/validate.d.ts +22 -0
- package/dist/crypto/validate.d.ts.map +1 -0
- package/dist/diagram/engine/layout-def-parse.d.ts.map +1 -1
- package/dist/diagram/engine/pres-tree.d.ts.map +1 -1
- package/dist/diagram/index.cjs +102 -52
- package/dist/diagram/index.mjs +102 -52
- package/dist/digest/index.cjs +23 -11
- package/dist/digest/index.d.ts +2 -1
- package/dist/digest/index.d.ts.map +1 -1
- package/dist/digest/index.mjs +21 -12
- package/dist/digest/password-hash.d.ts +19 -5
- package/dist/digest/password-hash.d.ts.map +1 -1
- package/dist/digest/timing-safe.d.ts +7 -0
- package/dist/digest/timing-safe.d.ts.map +1 -0
- package/dist/docx/block-parser.d.ts.map +1 -1
- package/dist/docx/chart-paint.d.ts.map +1 -1
- package/dist/docx/chart.d.ts +10 -2
- package/dist/docx/chart.d.ts.map +1 -1
- package/dist/docx/content-control-edit.d.ts +26 -0
- package/dist/docx/content-control-edit.d.ts.map +1 -0
- package/dist/docx/content-control-model.d.ts +51 -0
- package/dist/docx/content-control-model.d.ts.map +1 -0
- package/dist/docx/content-control.d.ts +9 -0
- package/dist/docx/content-control.d.ts.map +1 -0
- package/dist/docx/default-styles.d.ts.map +1 -1
- package/dist/docx/drawing.d.ts.map +1 -1
- package/dist/docx/embedded.cjs +9932 -935
- package/dist/docx/embedded.mjs +9932 -935
- package/dist/docx/equation.d.ts +7 -3
- package/dist/docx/equation.d.ts.map +1 -1
- package/dist/docx/index.cjs +14117 -1513
- package/dist/docx/index.d.ts +6 -0
- package/dist/docx/index.d.ts.map +1 -1
- package/dist/docx/index.mjs +14093 -1514
- package/dist/docx/inline-model.d.ts +3 -0
- package/dist/docx/inline-model.d.ts.map +1 -1
- package/dist/docx/layout/adapt-floats.d.ts +3 -3
- package/dist/docx/layout/adapt-floats.d.ts.map +1 -1
- package/dist/docx/layout/adapter.d.ts.map +1 -1
- package/dist/docx/layout/equation-object.d.ts +7 -0
- package/dist/docx/layout/equation-object.d.ts.map +1 -0
- package/dist/docx/layout/floats.d.ts +8 -0
- package/dist/docx/layout/floats.d.ts.map +1 -1
- package/dist/docx/layout/incremental-layout.d.ts +39 -0
- package/dist/docx/layout/incremental-layout.d.ts.map +1 -0
- package/dist/docx/layout/index.cjs +14177 -1707
- package/dist/docx/layout/index.d.ts +2 -2
- package/dist/docx/layout/index.d.ts.map +1 -1
- package/dist/docx/layout/index.mjs +14176 -1708
- package/dist/docx/layout/input.d.ts +4 -0
- package/dist/docx/layout/input.d.ts.map +1 -1
- package/dist/docx/layout/layout-session.d.ts +13 -2
- package/dist/docx/layout/layout-session.d.ts.map +1 -1
- package/dist/docx/layout/layout.d.ts +1 -1
- package/dist/docx/layout/layout.d.ts.map +1 -1
- package/dist/docx/layout/line-metrics.d.ts.map +1 -1
- package/dist/docx/layout/page-cursor.d.ts +1 -1
- package/dist/docx/layout/page-cursor.d.ts.map +1 -1
- package/dist/docx/layout/page-fields.d.ts +3 -1
- package/dist/docx/layout/page-fields.d.ts.map +1 -1
- package/dist/docx/layout/result.d.ts +14 -1
- package/dist/docx/layout/result.d.ts.map +1 -1
- package/dist/docx/layout/section-flow.d.ts +11 -1
- package/dist/docx/layout/section-flow.d.ts.map +1 -1
- package/dist/docx/ligatures.d.ts +2 -0
- package/dist/docx/ligatures.d.ts.map +1 -1
- package/dist/docx/load/index.cjs +12709 -3590
- package/dist/docx/load/index.mjs +12709 -3590
- package/dist/docx/model-paragraph.d.ts +3 -0
- package/dist/docx/model-paragraph.d.ts.map +1 -1
- package/dist/docx/model-run.d.ts +3 -0
- package/dist/docx/model-run.d.ts.map +1 -1
- package/dist/docx/model.d.ts +3 -0
- package/dist/docx/model.d.ts.map +1 -1
- package/dist/docx/numbering-parse.d.ts.map +1 -1
- package/dist/docx/numbering-text.d.ts.map +1 -1
- package/dist/docx/package-limits.d.ts +6 -0
- package/dist/docx/package-limits.d.ts.map +1 -0
- package/dist/docx/parse-content-control.d.ts +28 -0
- package/dist/docx/parse-content-control.d.ts.map +1 -0
- package/dist/docx/parse-table.d.ts.map +1 -1
- package/dist/docx/parse.d.ts.map +1 -1
- package/dist/docx/save.d.ts.map +1 -1
- package/dist/docx/shape-model.d.ts +31 -0
- package/dist/docx/shape-model.d.ts.map +1 -0
- package/dist/docx/shape-palette.d.ts +19 -0
- package/dist/docx/shape-palette.d.ts.map +1 -0
- package/dist/docx/shape-parse.d.ts +16 -0
- package/dist/docx/shape-parse.d.ts.map +1 -0
- package/dist/docx/shape-svg.d.ts +20 -0
- package/dist/docx/shape-svg.d.ts.map +1 -0
- package/dist/docx/table-model.d.ts +4 -0
- package/dist/docx/table-model.d.ts.map +1 -1
- package/dist/docx/ui/content-control-commands.d.ts +37 -0
- package/dist/docx/ui/content-control-commands.d.ts.map +1 -0
- package/dist/docx/ui/content-control-guard.d.ts +8 -0
- package/dist/docx/ui/content-control-guard.d.ts.map +1 -0
- package/dist/docx/ui/content-control-spans.d.ts +19 -0
- package/dist/docx/ui/content-control-spans.d.ts.map +1 -0
- package/dist/docx/ui/index.cjs +3132 -506
- package/dist/docx/ui/index.d.ts +3 -0
- package/dist/docx/ui/index.d.ts.map +1 -1
- package/dist/docx/ui/index.mjs +3117 -507
- package/dist/docx/ui/inline-content-schema.d.ts.map +1 -1
- package/dist/docx/ui/paragraph-attributes.d.ts.map +1 -1
- package/dist/docx/ui/ribbon-action-ids.d.ts +1 -1
- package/dist/docx/ui/ribbon-action-ids.d.ts.map +1 -1
- package/dist/docx/ui/run-adapter.d.ts.map +1 -1
- package/dist/docx/ui/run-compare.d.ts.map +1 -1
- package/dist/docx/ui/run-mark-properties.d.ts.map +1 -1
- package/dist/docx/ui/run-marks.d.ts.map +1 -1
- package/dist/docx/ui/schema-marks.d.ts +16 -1
- package/dist/docx/ui/schema-marks.d.ts.map +1 -1
- package/dist/docx/ui/table-structure-guard.d.ts.map +1 -1
- package/dist/docx/write-block-placement.d.ts +9 -0
- package/dist/docx/write-block-placement.d.ts.map +1 -0
- package/dist/docx/write-content-control.d.ts +12 -0
- package/dist/docx/write-content-control.d.ts.map +1 -0
- package/dist/docx/write-drawing.d.ts +2 -0
- package/dist/docx/write-drawing.d.ts.map +1 -1
- package/dist/docx/write-inline.d.ts.map +1 -1
- package/dist/docx/write-paragraph.d.ts.map +1 -1
- package/dist/docx/write-shape.d.ts +16 -0
- package/dist/docx/write-shape.d.ts.map +1 -0
- package/dist/docx/write-table.d.ts.map +1 -1
- package/dist/docx/write.d.ts.map +1 -1
- package/dist/drawingml/index.cjs +24 -0
- package/dist/drawingml/index.mjs +24 -0
- package/dist/geometry/index.cjs +63 -48
- package/dist/geometry/index.mjs +63 -48
- package/dist/geometry/preset-shape-definitions-table.d.ts.map +1 -1
- package/dist/i18n/index.cjs +266 -0
- package/dist/i18n/index.d.ts +1 -0
- package/dist/i18n/index.d.ts.map +1 -1
- package/dist/i18n/index.mjs +265 -1
- package/dist/i18n/option-strings.d.ts +17 -0
- package/dist/i18n/option-strings.d.ts.map +1 -0
- package/dist/index.cjs +4558 -1579
- package/dist/index.mjs +4558 -1579
- package/dist/math/equation-gallery.d.ts +10 -0
- package/dist/math/equation-gallery.d.ts.map +1 -0
- package/dist/math/index.cjs +777 -139
- package/dist/math/index.d.ts +3 -0
- package/dist/math/index.d.ts.map +1 -1
- package/dist/math/index.mjs +772 -140
- package/dist/math/latex-omml-siblings.d.ts.map +1 -1
- package/dist/math/latex-to-omml.d.ts.map +1 -1
- package/dist/math/omml-box-grouped.d.ts +9 -0
- package/dist/math/omml-box-grouped.d.ts.map +1 -0
- package/dist/math/omml-box-layout.d.ts +15 -0
- package/dist/math/omml-box-layout.d.ts.map +1 -0
- package/dist/math/omml-box-structures.d.ts +7 -0
- package/dist/math/omml-box-structures.d.ts.map +1 -0
- package/dist/math/omml-box.d.ts +85 -0
- package/dist/math/omml-box.d.ts.map +1 -0
- package/dist/math/omml-dom.d.ts.map +1 -1
- package/dist/math/omml-mathml-converters.d.ts.map +1 -1
- package/dist/math/omml-svg.d.ts +14 -0
- package/dist/math/omml-svg.d.ts.map +1 -0
- package/dist/math/omml-to-xml.d.ts +10 -0
- package/dist/math/omml-to-xml.d.ts.map +1 -0
- package/dist/opc/embedded-packages.d.ts.map +1 -1
- package/dist/opc/index.cjs +257 -22
- package/dist/opc/index.d.ts +1 -0
- package/dist/opc/index.d.ts.map +1 -1
- package/dist/opc/index.mjs +251 -23
- package/dist/opc/package.d.ts.map +1 -1
- package/dist/opc/signature/detection.d.ts +22 -6
- package/dist/opc/signature/detection.d.ts.map +1 -1
- package/dist/opc/signature/index.d.ts +1 -1
- package/dist/opc/signature/index.d.ts.map +1 -1
- package/dist/opc/signature/xml-utils.d.ts.map +1 -1
- package/dist/opc/zip-limits.d.ts +52 -0
- package/dist/opc/zip-limits.d.ts.map +1 -0
- package/dist/pptx/automation/index.cjs +1848 -1320
- package/dist/pptx/automation/index.d.ts +4 -4
- package/dist/pptx/automation/index.mjs +6 -6
- package/dist/pptx/chunks/{elements-DmbzOhFu.d.ts → elements-tK7xnWeS.d.ts} +20 -9
- package/dist/pptx/chunks/elements-tK7xnWeS.d.ts.map +1 -0
- package/dist/pptx/chunks/{index-Cija6Dih.d.ts → index-BSpNQuvz.d.ts} +30 -5
- package/dist/pptx/chunks/{index-Cija6Dih.d.ts.map → index-BSpNQuvz.d.ts.map} +1 -1
- package/dist/pptx/chunks/{index-BmvOxbsh.d.ts → index-DS9Y4Ne3.d.ts} +25 -9
- package/dist/pptx/chunks/index-DS9Y4Ne3.d.ts.map +1 -0
- package/dist/pptx/chunks/inspection-status-DjiWd_Aa.d.ts.map +1 -1
- package/dist/pptx/chunks/{text-operations-sXxhsKDd.d.ts → text-operations-BdD_UQ11.d.ts} +2 -2
- package/dist/pptx/chunks/{text-operations-sXxhsKDd.d.ts.map → text-operations-BdD_UQ11.d.ts.map} +1 -1
- package/dist/pptx/cli/index.cjs +1795 -1275
- package/dist/pptx/cli/index.d.ts +1 -1
- package/dist/pptx/cli/index.mjs +5 -5
- package/dist/pptx/converter/index.cjs +80 -54
- package/dist/pptx/converter/index.d.ts +1 -1
- package/dist/pptx/converter/index.mjs +3 -3
- package/dist/pptx/editor/render/find-replace.cjs +14 -14
- package/dist/pptx/editor/render/find-replace.d.ts +2 -2
- package/dist/pptx/editor/render/find-replace.mjs +1 -1
- package/dist/pptx/editor/render/slide-operations.cjs +8 -8
- package/dist/pptx/editor/render/slide-operations.mjs +2 -2
- package/dist/pptx/editor/render/text-runs-style-patch.d.ts +1 -1
- package/dist/pptx/editor/render/text-style-scope.d.ts +1 -1
- package/dist/pptx/index.cjs +1117 -351
- package/dist/pptx/index.d.ts +5 -5
- package/dist/pptx/index.mjs +6 -6
- package/dist/pptx/signature-node/index.cjs +342 -65
- package/dist/pptx/signature-node/index.d.ts +12 -1
- package/dist/pptx/signature-node/index.d.ts.map +1 -1
- package/dist/pptx/signature-node/index.mjs +112 -52
- package/dist/teams/activity-feed.d.ts +19 -0
- package/dist/teams/activity-feed.d.ts.map +1 -0
- package/dist/teams/activity-state.d.ts +12 -0
- package/dist/teams/activity-state.d.ts.map +1 -0
- package/dist/teams/activity.d.ts +52 -0
- package/dist/teams/activity.d.ts.map +1 -0
- package/dist/teams/calendar.d.ts +57 -0
- package/dist/teams/calendar.d.ts.map +1 -0
- package/dist/teams/chat-actions.d.ts +20 -0
- package/dist/teams/chat-actions.d.ts.map +1 -0
- package/dist/teams/chat-rooms.d.ts +42 -0
- package/dist/teams/chat-rooms.d.ts.map +1 -0
- package/dist/teams/chat-view.d.ts +56 -0
- package/dist/teams/chat-view.d.ts.map +1 -0
- package/dist/teams/chat.d.ts +25 -3
- package/dist/teams/chat.d.ts.map +1 -1
- package/dist/teams/chats.d.ts +52 -0
- package/dist/teams/chats.d.ts.map +1 -0
- package/dist/teams/ics-timezone.d.ts +17 -0
- package/dist/teams/ics-timezone.d.ts.map +1 -0
- package/dist/teams/ics.d.ts +20 -0
- package/dist/teams/ics.d.ts.map +1 -0
- package/dist/teams/index.cjs +12462 -7011
- package/dist/teams/index.d.ts +25 -0
- package/dist/teams/index.d.ts.map +1 -1
- package/dist/teams/index.mjs +12349 -7012
- package/dist/teams/meeting-actions.d.ts +31 -0
- package/dist/teams/meeting-actions.d.ts.map +1 -0
- package/dist/teams/meeting-exceptions.d.ts +28 -0
- package/dist/teams/meeting-exceptions.d.ts.map +1 -0
- package/dist/teams/meeting-reminders.d.ts +13 -0
- package/dist/teams/meeting-reminders.d.ts.map +1 -0
- package/dist/teams/meetings.d.ts +71 -0
- package/dist/teams/meetings.d.ts.map +1 -0
- package/dist/teams/mention-text.d.ts +11 -0
- package/dist/teams/mention-text.d.ts.map +1 -0
- package/dist/teams/mentions.d.ts +68 -0
- package/dist/teams/mentions.d.ts.map +1 -0
- package/dist/teams/model.d.ts +7 -0
- package/dist/teams/model.d.ts.map +1 -1
- package/dist/teams/notifications.d.ts +21 -0
- package/dist/teams/notifications.d.ts.map +1 -0
- package/dist/teams/pins.d.ts +22 -0
- package/dist/teams/pins.d.ts.map +1 -0
- package/dist/teams/presence-controller.d.ts +39 -0
- package/dist/teams/presence-controller.d.ts.map +1 -0
- package/dist/teams/presence.d.ts +55 -0
- package/dist/teams/presence.d.ts.map +1 -0
- package/dist/teams/recurrence.d.ts +18 -0
- package/dist/teams/recurrence.d.ts.map +1 -0
- package/dist/teams/roster.d.ts +12 -0
- package/dist/teams/roster.d.ts.map +1 -0
- package/dist/teams/server-config.d.ts +23 -2
- package/dist/teams/server-config.d.ts.map +1 -1
- package/dist/teams/server-session.d.ts +19 -0
- package/dist/teams/server-session.d.ts.map +1 -0
- package/dist/teams/shared-chat.d.ts +83 -0
- package/dist/teams/shared-chat.d.ts.map +1 -0
- package/dist/teams/store.d.ts +79 -5
- package/dist/teams/store.d.ts.map +1 -1
- package/dist/teams/sync-transport.d.ts +12 -0
- package/dist/teams/sync-transport.d.ts.map +1 -0
- package/dist/teams/time-zone.d.ts +32 -0
- package/dist/teams/time-zone.d.ts.map +1 -0
- package/dist/teams/view.d.ts +8 -0
- package/dist/teams/view.d.ts.map +1 -1
- package/dist/teams/workspace.d.ts +23 -4
- package/dist/teams/workspace.d.ts.map +1 -1
- package/dist/visio/edit-connector-follow.d.ts +15 -0
- package/dist/visio/edit-connector-follow.d.ts.map +1 -0
- package/dist/visio/edit-connector-obstacles.d.ts +9 -3
- package/dist/visio/edit-connector-obstacles.d.ts.map +1 -1
- package/dist/visio/edit-connector-reroute.d.ts.map +1 -1
- package/dist/visio/edit-connector.d.ts.map +1 -1
- package/dist/visio/edit-master-add.d.ts +37 -0
- package/dist/visio/edit-master-add.d.ts.map +1 -0
- package/dist/visio/edit-master-drop.d.ts +6 -0
- package/dist/visio/edit-master-drop.d.ts.map +1 -1
- package/dist/visio/edit-recalculate-index.d.ts +5 -0
- package/dist/visio/edit-recalculate-index.d.ts.map +1 -1
- package/dist/visio/edit-recalculate-values.d.ts.map +1 -1
- package/dist/visio/edit-stencil-connector-layout.d.ts +2 -0
- package/dist/visio/edit-stencil-connector-layout.d.ts.map +1 -1
- package/dist/visio/edit-stencil-connector.d.ts +1 -0
- package/dist/visio/edit-stencil-connector.d.ts.map +1 -1
- package/dist/visio/edit-stencil-import.d.ts +10 -0
- package/dist/visio/edit-stencil-import.d.ts.map +1 -0
- package/dist/visio/edit-stencil-line.d.ts +29 -0
- package/dist/visio/edit-stencil-line.d.ts.map +1 -0
- package/dist/visio/edit-stencil-master.d.ts +3 -8
- package/dist/visio/edit-stencil-master.d.ts.map +1 -1
- package/dist/visio/edit.d.ts.map +1 -1
- package/dist/visio/formula-evaluate.d.ts.map +1 -1
- package/dist/visio/formula-math-functions.d.ts +11 -0
- package/dist/visio/formula-math-functions.d.ts.map +1 -0
- package/dist/visio/formula-text-functions.d.ts +23 -0
- package/dist/visio/formula-text-functions.d.ts.map +1 -0
- package/dist/visio/formula.d.ts.map +1 -1
- package/dist/visio/index.cjs +2552 -1833
- package/dist/visio/index.d.ts +1 -0
- package/dist/visio/index.d.ts.map +1 -1
- package/dist/visio/index.mjs +2552 -1834
- package/dist/visio/parser.d.ts +6 -0
- package/dist/visio/parser.d.ts.map +1 -1
- package/dist/visio/stencil-file.d.ts +14 -0
- package/dist/visio/stencil-file.d.ts.map +1 -0
- package/dist/visio/ui/index.cjs +2398 -1679
- package/dist/visio/ui/index.mjs +2398 -1680
- package/dist/visio/ui/master-drop.d.ts +10 -0
- package/dist/visio/ui/master-drop.d.ts.map +1 -1
- package/dist/xlsx/edit/cell-values.d.ts.map +1 -1
- package/dist/xlsx/edit/clipboard-html-parse.d.ts +4 -0
- package/dist/xlsx/edit/clipboard-html-parse.d.ts.map +1 -1
- package/dist/xlsx/edit/data-table.d.ts +38 -0
- package/dist/xlsx/edit/data-table.d.ts.map +1 -0
- package/dist/xlsx/edit/drawings.d.ts.map +1 -1
- package/dist/xlsx/edit/goal-seek.d.ts +30 -0
- package/dist/xlsx/edit/goal-seek.d.ts.map +1 -0
- package/dist/xlsx/edit/goal-solver.d.ts +20 -0
- package/dist/xlsx/edit/goal-solver.d.ts.map +1 -0
- package/dist/xlsx/edit/history.d.ts +1 -1
- package/dist/xlsx/edit/history.d.ts.map +1 -1
- package/dist/xlsx/edit/index.d.ts +5 -0
- package/dist/xlsx/edit/index.d.ts.map +1 -1
- package/dist/xlsx/edit/input-text.d.ts.map +1 -1
- package/dist/xlsx/edit/pivots.d.ts +2 -1
- package/dist/xlsx/edit/pivots.d.ts.map +1 -1
- package/dist/xlsx/edit/scenarios.d.ts +41 -0
- package/dist/xlsx/edit/scenarios.d.ts.map +1 -0
- package/dist/xlsx/edit/session.d.ts.map +1 -1
- package/dist/xlsx/edit/slicers.d.ts +34 -0
- package/dist/xlsx/edit/slicers.d.ts.map +1 -0
- package/dist/xlsx/edit/table-edits.d.ts.map +1 -1
- package/dist/xlsx/edit/timelines.d.ts +26 -0
- package/dist/xlsx/edit/timelines.d.ts.map +1 -0
- package/dist/xlsx/edit/types.d.ts +39 -0
- package/dist/xlsx/edit/types.d.ts.map +1 -1
- package/dist/xlsx/formula/context.d.ts +13 -0
- package/dist/xlsx/formula/context.d.ts.map +1 -1
- package/dist/xlsx/formula/engine.d.ts.map +1 -1
- package/dist/xlsx/formula/evaluator.d.ts.map +1 -1
- package/dist/xlsx/formula/functions/amordegrc.d.ts +6 -0
- package/dist/xlsx/formula/functions/amordegrc.d.ts.map +1 -0
- package/dist/xlsx/formula/functions/bahttext.d.ts +4 -0
- package/dist/xlsx/formula/functions/bahttext.d.ts.map +1 -0
- package/dist/xlsx/formula/functions/bessel.d.ts +7 -0
- package/dist/xlsx/formula/functions/bessel.d.ts.map +1 -0
- package/dist/xlsx/formula/functions/bonds.d.ts +3 -0
- package/dist/xlsx/formula/functions/bonds.d.ts.map +1 -1
- package/dist/xlsx/formula/functions/engineering.d.ts.map +1 -1
- package/dist/xlsx/formula/functions/financial.d.ts.map +1 -1
- package/dist/xlsx/formula/functions/getpivotdata.d.ts +2 -0
- package/dist/xlsx/formula/functions/getpivotdata.d.ts.map +1 -0
- package/dist/xlsx/formula/functions/groupby.d.ts +3 -0
- package/dist/xlsx/formula/functions/groupby.d.ts.map +1 -0
- package/dist/xlsx/formula/functions/helpers.d.ts +3 -2
- package/dist/xlsx/formula/functions/helpers.d.ts.map +1 -1
- package/dist/xlsx/formula/functions/logical.d.ts.map +1 -1
- package/dist/xlsx/formula/functions/modern.d.ts +3 -0
- package/dist/xlsx/formula/functions/modern.d.ts.map +1 -0
- package/dist/xlsx/formula/functions/odd-securities.d.ts +3 -0
- package/dist/xlsx/formula/functions/odd-securities.d.ts.map +1 -0
- package/dist/xlsx/formula/functions/registry.d.ts.map +1 -1
- package/dist/xlsx/formula/functions/text-regex.d.ts +8 -0
- package/dist/xlsx/formula/functions/text-regex.d.ts.map +1 -1
- package/dist/xlsx/formula/functions/text.d.ts.map +1 -1
- package/dist/xlsx/formula/functions/wildcard.d.ts +8 -0
- package/dist/xlsx/formula/functions/wildcard.d.ts.map +1 -0
- package/dist/xlsx/formula/values.d.ts +11 -0
- package/dist/xlsx/formula/values.d.ts.map +1 -1
- package/dist/xlsx/index.cjs +11696 -4994
- package/dist/xlsx/index.d.ts +1 -0
- package/dist/xlsx/index.d.ts.map +1 -1
- package/dist/xlsx/index.mjs +11612 -4994
- package/dist/xlsx/layout/chart-view.d.ts.map +1 -1
- package/dist/xlsx/layout/header-footer-edit.d.ts +16 -0
- package/dist/xlsx/layout/header-footer-edit.d.ts.map +1 -0
- package/dist/xlsx/layout/index.d.ts +3 -0
- package/dist/xlsx/layout/index.d.ts.map +1 -1
- package/dist/xlsx/layout/page-break-view.d.ts +39 -0
- package/dist/xlsx/layout/page-break-view.d.ts.map +1 -0
- package/dist/xlsx/layout/page-view.d.ts +69 -0
- package/dist/xlsx/layout/page-view.d.ts.map +1 -0
- package/dist/xlsx/layout/ref-evaluator.d.ts.map +1 -1
- package/dist/xlsx/load/index.cjs +5718 -2191
- package/dist/xlsx/load/index.mjs +5717 -2190
- package/dist/xlsx/model-pivots.d.ts +88 -2
- package/dist/xlsx/model-pivots.d.ts.map +1 -1
- package/dist/xlsx/model-slicers.d.ts +146 -0
- package/dist/xlsx/model-slicers.d.ts.map +1 -0
- package/dist/xlsx/model-whatif.d.ts +51 -0
- package/dist/xlsx/model-whatif.d.ts.map +1 -0
- package/dist/xlsx/model.d.ts +26 -1
- package/dist/xlsx/model.d.ts.map +1 -1
- package/dist/xlsx/pivot/admission.d.ts.map +1 -1
- package/dist/xlsx/pivot/aggregate.d.ts +15 -6
- package/dist/xlsx/pivot/aggregate.d.ts.map +1 -1
- package/dist/xlsx/pivot/axes.d.ts +6 -0
- package/dist/xlsx/pivot/axes.d.ts.map +1 -0
- package/dist/xlsx/pivot/cache-xml.d.ts.map +1 -1
- package/dist/xlsx/pivot/columns.d.ts +48 -0
- package/dist/xlsx/pivot/columns.d.ts.map +1 -0
- package/dist/xlsx/pivot/data.d.ts +9 -3
- package/dist/xlsx/pivot/data.d.ts.map +1 -1
- package/dist/xlsx/pivot/date-axes.d.ts +12 -0
- package/dist/xlsx/pivot/date-axes.d.ts.map +1 -0
- package/dist/xlsx/pivot/date-group-read.d.ts +11 -0
- package/dist/xlsx/pivot/date-group-read.d.ts.map +1 -0
- package/dist/xlsx/pivot/date-groups.d.ts +60 -0
- package/dist/xlsx/pivot/date-groups.d.ts.map +1 -0
- package/dist/xlsx/pivot/date-read.d.ts +10 -0
- package/dist/xlsx/pivot/date-read.d.ts.map +1 -0
- package/dist/xlsx/pivot/dates.d.ts +17 -0
- package/dist/xlsx/pivot/dates.d.ts.map +1 -0
- package/dist/xlsx/pivot/group-read.d.ts +9 -0
- package/dist/xlsx/pivot/group-read.d.ts.map +1 -0
- package/dist/xlsx/pivot/groups.d.ts +31 -0
- package/dist/xlsx/pivot/groups.d.ts.map +1 -0
- package/dist/xlsx/pivot/hierarchy.d.ts +4 -1
- package/dist/xlsx/pivot/hierarchy.d.ts.map +1 -1
- package/dist/xlsx/pivot/index.d.ts +7 -0
- package/dist/xlsx/pivot/index.d.ts.map +1 -1
- package/dist/xlsx/pivot/item-filters-read.d.ts +7 -0
- package/dist/xlsx/pivot/item-filters-read.d.ts.map +1 -0
- package/dist/xlsx/pivot/item-filters.d.ts +23 -0
- package/dist/xlsx/pivot/item-filters.d.ts.map +1 -0
- package/dist/xlsx/pivot/measures.d.ts +6 -4
- package/dist/xlsx/pivot/measures.d.ts.map +1 -1
- package/dist/xlsx/pivot/nested.d.ts +8 -0
- package/dist/xlsx/pivot/nested.d.ts.map +1 -0
- package/dist/xlsx/pivot/page-filter-admission.d.ts.map +1 -1
- package/dist/xlsx/pivot/page-filter.d.ts.map +1 -1
- package/dist/xlsx/pivot/read.d.ts +2 -1
- package/dist/xlsx/pivot/read.d.ts.map +1 -1
- package/dist/xlsx/pivot/subtotal-read.d.ts +9 -0
- package/dist/xlsx/pivot/subtotal-read.d.ts.map +1 -0
- package/dist/xlsx/pivot/subtotals.d.ts +23 -0
- package/dist/xlsx/pivot/subtotals.d.ts.map +1 -0
- package/dist/xlsx/pivot/table-xml.d.ts +1 -1
- package/dist/xlsx/pivot/table-xml.d.ts.map +1 -1
- package/dist/xlsx/pivot/values-axis.d.ts +2 -2
- package/dist/xlsx/pivot/values-axis.d.ts.map +1 -1
- package/dist/xlsx/read/chart-ex.d.ts +9 -0
- package/dist/xlsx/read/chart-ex.d.ts.map +1 -0
- package/dist/xlsx/read/chart.d.ts.map +1 -1
- package/dist/xlsx/read/drawing.d.ts.map +1 -1
- package/dist/xlsx/read/load.d.ts.map +1 -1
- package/dist/xlsx/read/package.d.ts +2 -1
- package/dist/xlsx/read/package.d.ts.map +1 -1
- package/dist/xlsx/read/scenarios.d.ts +4 -0
- package/dist/xlsx/read/scenarios.d.ts.map +1 -0
- package/dist/xlsx/read/sheet-data.d.ts.map +1 -1
- package/dist/xlsx/read/sheet-props.d.ts.map +1 -1
- package/dist/xlsx/read/tables.d.ts +3 -0
- package/dist/xlsx/read/tables.d.ts.map +1 -1
- package/dist/xlsx/read/worksheet.d.ts.map +1 -1
- package/dist/xlsx/slicer/book.d.ts +16 -0
- package/dist/xlsx/slicer/book.d.ts.map +1 -0
- package/dist/xlsx/slicer/frame.d.ts +14 -0
- package/dist/xlsx/slicer/frame.d.ts.map +1 -0
- package/dist/xlsx/slicer/index.d.ts +10 -0
- package/dist/xlsx/slicer/index.d.ts.map +1 -0
- package/dist/xlsx/slicer/items.d.ts +30 -0
- package/dist/xlsx/slicer/items.d.ts.map +1 -0
- package/dist/xlsx/slicer/layout.d.ts +67 -0
- package/dist/xlsx/slicer/layout.d.ts.map +1 -0
- package/dist/xlsx/slicer/read-slicers.d.ts +11 -0
- package/dist/xlsx/slicer/read-slicers.d.ts.map +1 -0
- package/dist/xlsx/slicer/read-timelines.d.ts +5 -0
- package/dist/xlsx/slicer/read-timelines.d.ts.map +1 -0
- package/dist/xlsx/slicer/read.d.ts +26 -0
- package/dist/xlsx/slicer/read.d.ts.map +1 -0
- package/dist/xlsx/slicer/select.d.ts +10 -0
- package/dist/xlsx/slicer/select.d.ts.map +1 -0
- package/dist/xlsx/slicer/styles.d.ts +36 -0
- package/dist/xlsx/slicer/styles.d.ts.map +1 -0
- package/dist/xlsx/slicer/table-filter.d.ts +28 -0
- package/dist/xlsx/slicer/table-filter.d.ts.map +1 -0
- package/dist/xlsx/slicer/timeline-periods.d.ts +35 -0
- package/dist/xlsx/slicer/timeline-periods.d.ts.map +1 -0
- package/dist/xlsx/slicer/timeline-view.d.ts +60 -0
- package/dist/xlsx/slicer/timeline-view.d.ts.map +1 -0
- package/dist/xlsx/slicer/write-plan.d.ts +31 -0
- package/dist/xlsx/slicer/write-plan.d.ts.map +1 -0
- package/dist/xlsx/slicer/write-timeline.d.ts +7 -0
- package/dist/xlsx/slicer/write-timeline.d.ts.map +1 -0
- package/dist/xlsx/slicer/write-xml.d.ts +17 -0
- package/dist/xlsx/slicer/write-xml.d.ts.map +1 -0
- package/dist/xlsx/ui/commands/i18n/index.d.ts.map +1 -1
- package/dist/xlsx/ui/commands/i18n/pivots.d.ts.map +1 -1
- package/dist/xlsx/ui/commands/i18n/print-layout.d.ts.map +1 -1
- package/dist/xlsx/ui/commands/i18n/slicers.d.ts +3 -0
- package/dist/xlsx/ui/commands/i18n/slicers.d.ts.map +1 -0
- package/dist/xlsx/ui/commands/i18n/what-if.d.ts +3 -0
- package/dist/xlsx/ui/commands/i18n/what-if.d.ts.map +1 -0
- package/dist/xlsx/ui/commands/icons.d.ts.map +1 -1
- package/dist/xlsx/ui/commands/slicers.d.ts +37 -0
- package/dist/xlsx/ui/commands/slicers.d.ts.map +1 -0
- package/dist/xlsx/ui/commands/what-if.d.ts +4 -0
- package/dist/xlsx/ui/commands/what-if.d.ts.map +1 -0
- package/dist/xlsx/ui/commands.d.ts +2 -0
- package/dist/xlsx/ui/commands.d.ts.map +1 -1
- package/dist/xlsx/ui/index.cjs +6999 -3052
- package/dist/xlsx/ui/index.d.ts +2 -0
- package/dist/xlsx/ui/index.d.ts.map +1 -1
- package/dist/xlsx/ui/index.mjs +6994 -3053
- package/dist/xlsx/ui/locales/de/index.d.ts.map +1 -1
- package/dist/xlsx/ui/locales/de/options.d.ts +2 -0
- package/dist/xlsx/ui/locales/de/options.d.ts.map +1 -0
- package/dist/xlsx/ui/locales/de/shell.d.ts.map +1 -1
- package/dist/xlsx/ui/locales/en/index.d.ts.map +1 -1
- package/dist/xlsx/ui/locales/en/options.d.ts +2 -0
- package/dist/xlsx/ui/locales/en/options.d.ts.map +1 -0
- package/dist/xlsx/ui/locales/en/shell.d.ts.map +1 -1
- package/dist/xlsx/ui/locales/es/index.d.ts.map +1 -1
- package/dist/xlsx/ui/locales/es/options.d.ts +2 -0
- package/dist/xlsx/ui/locales/es/options.d.ts.map +1 -0
- package/dist/xlsx/ui/locales/es/shell.d.ts.map +1 -1
- package/dist/xlsx/ui/locales/fr/index.d.ts.map +1 -1
- package/dist/xlsx/ui/locales/fr/options.d.ts +2 -0
- package/dist/xlsx/ui/locales/fr/options.d.ts.map +1 -0
- package/dist/xlsx/ui/locales/fr/shell.d.ts.map +1 -1
- package/dist/xlsx/ui/locales/zh-CN/index.d.ts.map +1 -1
- package/dist/xlsx/ui/locales/zh-CN/options.d.ts +2 -0
- package/dist/xlsx/ui/locales/zh-CN/options.d.ts.map +1 -0
- package/dist/xlsx/ui/locales/zh-CN/shell.d.ts.map +1 -1
- package/dist/xlsx/ui/ribbon/tabs/review-view.d.ts.map +1 -1
- package/dist/xlsx/write/carried-refs.d.ts.map +1 -1
- package/dist/xlsx/write/drawing.d.ts.map +1 -1
- package/dist/xlsx/write/package-writer.d.ts +2 -0
- package/dist/xlsx/write/package-writer.d.ts.map +1 -1
- package/dist/xlsx/write/save.d.ts.map +1 -1
- package/dist/xlsx/write/scenarios.d.ts +4 -0
- package/dist/xlsx/write/scenarios.d.ts.map +1 -0
- package/dist/xlsx/write/sheet-data.d.ts.map +1 -1
- package/dist/xlsx/write/sheet-parts.d.ts +1 -0
- package/dist/xlsx/write/sheet-parts.d.ts.map +1 -1
- package/dist/xlsx/write/sheet-props.d.ts.map +1 -1
- package/dist/xlsx/write/table-patch.d.ts.map +1 -1
- package/dist/xlsx/write/tables.d.ts.map +1 -1
- package/dist/xlsx/write/worksheet.d.ts.map +1 -1
- package/dist/xml/index.cjs +28 -0
- package/dist/xml/index.mjs +27 -1
- package/dist/xml/namespaces.d.ts +2 -0
- package/dist/xml/namespaces.d.ts.map +1 -1
- package/dist/xml/xml.d.ts +15 -0
- package/dist/xml/xml.d.ts.map +1 -1
- package/package.json +1 -1
- package/dist/PptxHandler-RWTOUCLC.mjs +0 -3
- package/dist/PptxHandler-UU4ZCT6H.cjs +0 -12
- package/dist/chunk-KBIJI6P5.mjs +0 -166
- package/dist/pptx/chunks/elements-DmbzOhFu.d.ts.map +0 -1
- package/dist/pptx/chunks/index-BmvOxbsh.d.ts.map +0 -1
package/dist/chart/index.cjs
CHANGED
|
@@ -290,6 +290,669 @@ function niceValueAxisBounds(dataMin, dataMax, targetIntervals = DEFAULT_TARGET_
|
|
|
290
290
|
return { min, max, majorUnit: unit };
|
|
291
291
|
}
|
|
292
292
|
|
|
293
|
+
// chart/number-format-pattern.ts
|
|
294
|
+
var NAMED_FORMAT_COLORS = {
|
|
295
|
+
black: "#000000",
|
|
296
|
+
blue: "#0000FF",
|
|
297
|
+
cyan: "#00FFFF",
|
|
298
|
+
green: "#00FF00",
|
|
299
|
+
magenta: "#FF00FF",
|
|
300
|
+
red: "#FF0000",
|
|
301
|
+
white: "#FFFFFF",
|
|
302
|
+
yellow: "#FFFF00"
|
|
303
|
+
};
|
|
304
|
+
var PLACEHOLDER = /[0#?]/u;
|
|
305
|
+
function parsePattern(code) {
|
|
306
|
+
let scale = 1;
|
|
307
|
+
let scientific = false;
|
|
308
|
+
let color;
|
|
309
|
+
const chars = [];
|
|
310
|
+
let inQuotes = false;
|
|
311
|
+
for (let i = 0; i < code.length; i += 1) {
|
|
312
|
+
const ch = code[i] ?? "";
|
|
313
|
+
if (ch === '"') {
|
|
314
|
+
inQuotes = !inQuotes;
|
|
315
|
+
continue;
|
|
316
|
+
}
|
|
317
|
+
if (inQuotes) {
|
|
318
|
+
chars.push({ ch, literal: true });
|
|
319
|
+
continue;
|
|
320
|
+
}
|
|
321
|
+
if (ch === "\\" || ch === "*" || ch === "_") {
|
|
322
|
+
const next = code[i + 1];
|
|
323
|
+
i += 1;
|
|
324
|
+
if (ch === "\\" && next !== void 0) {
|
|
325
|
+
chars.push({ ch: next, literal: true });
|
|
326
|
+
}
|
|
327
|
+
continue;
|
|
328
|
+
}
|
|
329
|
+
if (ch === "%") {
|
|
330
|
+
scale *= 100;
|
|
331
|
+
chars.push({ ch, literal: true });
|
|
332
|
+
continue;
|
|
333
|
+
}
|
|
334
|
+
if (ch === "E" && (code[i + 1] === "+" || code[i + 1] === "-")) {
|
|
335
|
+
scientific = true;
|
|
336
|
+
chars.push({ ch: "E", literal: false });
|
|
337
|
+
i += 1;
|
|
338
|
+
continue;
|
|
339
|
+
}
|
|
340
|
+
if (ch === "[") {
|
|
341
|
+
const close = code.indexOf("]", i);
|
|
342
|
+
const token = code.slice(i + 1, close === -1 ? code.length : close);
|
|
343
|
+
const named2 = NAMED_FORMAT_COLORS[token.trim().toLowerCase()];
|
|
344
|
+
if (named2 && color === void 0) {
|
|
345
|
+
color = named2;
|
|
346
|
+
}
|
|
347
|
+
i = close === -1 ? code.length : close;
|
|
348
|
+
continue;
|
|
349
|
+
}
|
|
350
|
+
chars.push({ ch, literal: false });
|
|
351
|
+
}
|
|
352
|
+
const firstDigit = chars.findIndex((c2) => !c2.literal && PLACEHOLDER.test(c2.ch));
|
|
353
|
+
if (firstDigit === -1) {
|
|
354
|
+
return void 0;
|
|
355
|
+
}
|
|
356
|
+
let lastDigit = firstDigit;
|
|
357
|
+
for (let i = chars.length - 1; i >= firstDigit; i -= 1) {
|
|
358
|
+
const c2 = chars[i];
|
|
359
|
+
if (c2 && !c2.literal && (PLACEHOLDER.test(c2.ch) || c2.ch === "." || c2.ch === "," || c2.ch === "E")) {
|
|
360
|
+
lastDigit = i;
|
|
361
|
+
break;
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
const numeric = chars.slice(firstDigit, lastDigit + 1);
|
|
365
|
+
const prefix = chars.slice(0, firstDigit).map((c2) => c2.ch).join("");
|
|
366
|
+
const suffix = chars.slice(lastDigit + 1).map((c2) => c2.ch).join("");
|
|
367
|
+
let grouped = false;
|
|
368
|
+
let intDigits = 0;
|
|
369
|
+
let required = 0;
|
|
370
|
+
let optional = 0;
|
|
371
|
+
let afterPoint = false;
|
|
372
|
+
let inExponent = false;
|
|
373
|
+
for (let i = 0; i < numeric.length; i += 1) {
|
|
374
|
+
const { ch, literal } = numeric[i] ?? { ch: "", literal: true };
|
|
375
|
+
if (literal) {
|
|
376
|
+
continue;
|
|
377
|
+
}
|
|
378
|
+
if (ch === "E") {
|
|
379
|
+
inExponent = true;
|
|
380
|
+
continue;
|
|
381
|
+
}
|
|
382
|
+
if (inExponent) {
|
|
383
|
+
continue;
|
|
384
|
+
}
|
|
385
|
+
if (ch === ".") {
|
|
386
|
+
afterPoint = true;
|
|
387
|
+
continue;
|
|
388
|
+
}
|
|
389
|
+
if (ch === ",") {
|
|
390
|
+
const next = numeric.slice(i + 1).find((c2) => !c2.literal);
|
|
391
|
+
if (!next || next.ch === "." || !PLACEHOLDER.test(next.ch)) {
|
|
392
|
+
scale /= 1e3;
|
|
393
|
+
} else {
|
|
394
|
+
grouped = true;
|
|
395
|
+
}
|
|
396
|
+
continue;
|
|
397
|
+
}
|
|
398
|
+
if (!PLACEHOLDER.test(ch)) {
|
|
399
|
+
continue;
|
|
400
|
+
}
|
|
401
|
+
if (afterPoint) {
|
|
402
|
+
if (ch === "0") {
|
|
403
|
+
required += 1;
|
|
404
|
+
} else {
|
|
405
|
+
optional += 1;
|
|
406
|
+
}
|
|
407
|
+
} else if (ch === "0") {
|
|
408
|
+
intDigits += 1;
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
return {
|
|
412
|
+
prefix,
|
|
413
|
+
suffix,
|
|
414
|
+
intDigits,
|
|
415
|
+
decimals: { required, optional },
|
|
416
|
+
grouped,
|
|
417
|
+
scale,
|
|
418
|
+
scientific,
|
|
419
|
+
color
|
|
420
|
+
};
|
|
421
|
+
}
|
|
422
|
+
function group(intPart) {
|
|
423
|
+
return intPart.replace(/\B(?=(\d{3})+(?!\d))/gu, ",");
|
|
424
|
+
}
|
|
425
|
+
function applyPattern(value, pattern, forcePositive) {
|
|
426
|
+
const scaled = value * pattern.scale;
|
|
427
|
+
const magnitude = forcePositive ? Math.abs(scaled) : scaled;
|
|
428
|
+
if (pattern.scientific) {
|
|
429
|
+
const digits = pattern.decimals.required + pattern.decimals.optional;
|
|
430
|
+
const exponential = magnitude.toExponential(digits);
|
|
431
|
+
const [mantissa = "", exponent = "0"] = exponential.split("e");
|
|
432
|
+
const sign = exponent.startsWith("-") ? "-" : "+";
|
|
433
|
+
const power = Math.abs(Number(exponent)).toString().padStart(2, "0");
|
|
434
|
+
return `${pattern.prefix}${mantissa}E${sign}${power}${pattern.suffix}`;
|
|
435
|
+
}
|
|
436
|
+
const maxDecimals = pattern.decimals.required + pattern.decimals.optional;
|
|
437
|
+
let body = magnitude.toFixed(maxDecimals);
|
|
438
|
+
if (pattern.decimals.optional > 0) {
|
|
439
|
+
body = body.replace(/(\.\d*?)0+$/u, "$1").replace(/\.$/u, "");
|
|
440
|
+
const [, frac = ""] = body.split(".");
|
|
441
|
+
if (frac.length < pattern.decimals.required) {
|
|
442
|
+
body = Number(body).toFixed(pattern.decimals.required);
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
const [rawIntPart = "", fracPart] = body.split(".");
|
|
446
|
+
let intPart = rawIntPart;
|
|
447
|
+
const hasMinusChar = intPart.startsWith("-");
|
|
448
|
+
const negative = hasMinusChar && Number(body) !== 0;
|
|
449
|
+
if (hasMinusChar) {
|
|
450
|
+
intPart = intPart.slice(1);
|
|
451
|
+
}
|
|
452
|
+
if (intPart.length < pattern.intDigits) {
|
|
453
|
+
intPart = intPart.padStart(pattern.intDigits, "0");
|
|
454
|
+
}
|
|
455
|
+
if (pattern.intDigits === 0 && intPart === "0" && fracPart !== void 0) {
|
|
456
|
+
intPart = "";
|
|
457
|
+
}
|
|
458
|
+
if (pattern.grouped) {
|
|
459
|
+
intPart = group(intPart);
|
|
460
|
+
}
|
|
461
|
+
const number = fracPart === void 0 ? intPart : `${intPart}.${fracPart}`;
|
|
462
|
+
return `${negative ? "-" : ""}${pattern.prefix}${number}${pattern.suffix}`;
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
// chart/number-format.ts
|
|
466
|
+
var GENERAL = /* @__PURE__ */ new Set(["", "general", "@"]);
|
|
467
|
+
function sections(code) {
|
|
468
|
+
const out = [];
|
|
469
|
+
let current = "";
|
|
470
|
+
let inQuotes = false;
|
|
471
|
+
for (let i = 0; i < code.length; i += 1) {
|
|
472
|
+
const ch = code[i];
|
|
473
|
+
if (ch === '"') {
|
|
474
|
+
inQuotes = !inQuotes;
|
|
475
|
+
current += ch;
|
|
476
|
+
continue;
|
|
477
|
+
}
|
|
478
|
+
if (ch === "\\") {
|
|
479
|
+
current += ch + (code[i + 1] ?? "");
|
|
480
|
+
i += 1;
|
|
481
|
+
continue;
|
|
482
|
+
}
|
|
483
|
+
if (ch === ";" && !inQuotes) {
|
|
484
|
+
out.push(current);
|
|
485
|
+
current = "";
|
|
486
|
+
continue;
|
|
487
|
+
}
|
|
488
|
+
current += ch;
|
|
489
|
+
}
|
|
490
|
+
out.push(current);
|
|
491
|
+
return out;
|
|
492
|
+
}
|
|
493
|
+
function sectionFor(value, parts) {
|
|
494
|
+
if (parts.length === 1) {
|
|
495
|
+
return { code: parts[0] ?? "", forcePositive: false };
|
|
496
|
+
}
|
|
497
|
+
if (value < 0 && parts[1] !== void 0) {
|
|
498
|
+
return { code: parts[1] ?? "", forcePositive: true };
|
|
499
|
+
}
|
|
500
|
+
if (value === 0 && parts[2] !== void 0) {
|
|
501
|
+
return { code: parts[2] ?? "", forcePositive: false };
|
|
502
|
+
}
|
|
503
|
+
return { code: parts[0] ?? "", forcePositive: false };
|
|
504
|
+
}
|
|
505
|
+
function formatChartNumberWithColor(value, formatCode) {
|
|
506
|
+
if (!Number.isFinite(value)) {
|
|
507
|
+
return void 0;
|
|
508
|
+
}
|
|
509
|
+
const code = (formatCode ?? "").trim();
|
|
510
|
+
if (GENERAL.has(code.toLowerCase())) {
|
|
511
|
+
return void 0;
|
|
512
|
+
}
|
|
513
|
+
if (/(?:^|[^\\"])(?:yy|mm?m|dd?|hh|ss)/iu.test(code) && !/[0#?]/u.test(code)) {
|
|
514
|
+
return void 0;
|
|
515
|
+
}
|
|
516
|
+
const { code: section, forcePositive } = sectionFor(value, sections(code));
|
|
517
|
+
const pattern = parsePattern(section);
|
|
518
|
+
if (!pattern) {
|
|
519
|
+
return void 0;
|
|
520
|
+
}
|
|
521
|
+
try {
|
|
522
|
+
return { text: applyPattern(value, pattern, forcePositive), color: pattern.color };
|
|
523
|
+
} catch {
|
|
524
|
+
return void 0;
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
function formatChartNumber(value, formatCode) {
|
|
528
|
+
return formatChartNumberWithColor(value, formatCode)?.text;
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
// chart/auto-title.ts
|
|
532
|
+
var CHART_AUTO_TITLE = "Chart Title";
|
|
533
|
+
var CHARTEX_ONLY_TYPES = /* @__PURE__ */ new Set([
|
|
534
|
+
"waterfall",
|
|
535
|
+
"funnel",
|
|
536
|
+
"treemap",
|
|
537
|
+
"sunburst",
|
|
538
|
+
"boxWhisker",
|
|
539
|
+
"histogram",
|
|
540
|
+
"regionMap"
|
|
541
|
+
]);
|
|
542
|
+
function isChartexOnlyType(chartType) {
|
|
543
|
+
return CHARTEX_ONLY_TYPES.has(chartType);
|
|
544
|
+
}
|
|
545
|
+
function impliesAutoTitle(input) {
|
|
546
|
+
return !(input.hasTitle !== void 0 || input.autoTitleDeleted === true || isChartexOnlyType(input.chartType) || input.seriesNames.length !== 1 || !input.seriesNames[0]);
|
|
547
|
+
}
|
|
548
|
+
function resolveAutoTitleText(input) {
|
|
549
|
+
if (!input.hasTitle) return void 0;
|
|
550
|
+
if (input.title) return input.title;
|
|
551
|
+
if (!isChartexOnlyType(input.chartType) && input.seriesNames.length === 1)
|
|
552
|
+
return input.seriesNames[0] || void 0;
|
|
553
|
+
return input.seriesNames.length > 0 ? CHART_AUTO_TITLE : void 0;
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
// chart/axis-format.ts
|
|
557
|
+
function formatCompactAxisValue(value, formatCode) {
|
|
558
|
+
const formatted = formatChartNumber(value, formatCode);
|
|
559
|
+
if (formatted !== void 0) return formatted;
|
|
560
|
+
if (Math.abs(value) >= 1e6) return `${(value / 1e6).toFixed(1)}M`;
|
|
561
|
+
if (Math.abs(value) >= 1e3) return `${(value / 1e3).toFixed(1)}K`;
|
|
562
|
+
if (Number.isInteger(value)) return String(value);
|
|
563
|
+
return value.toFixed(1);
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
// chart/bubble-radius.ts
|
|
567
|
+
function computeBubbleRadius(sizeVal, maxBubble, medianRadius, options) {
|
|
568
|
+
const scale = (options?.bubbleScale ?? 100) / 100;
|
|
569
|
+
if (sizeVal === void 0) return medianRadius * scale;
|
|
570
|
+
const denom = maxBubble > 0 ? maxBubble : 1;
|
|
571
|
+
const magnitude = Math.abs(sizeVal);
|
|
572
|
+
const ratio = (options?.sizeRepresents ?? "w") === "area" ? Math.sqrt(magnitude) / Math.sqrt(denom) : magnitude / denom;
|
|
573
|
+
return medianRadius * scale * 0.5 + ratio * medianRadius * scale * 1.5;
|
|
574
|
+
}
|
|
575
|
+
function maxBubbleSize(sizes) {
|
|
576
|
+
return sizes.length > 0 ? Math.max(1, ...sizes.map(Math.abs)) : 1;
|
|
577
|
+
}
|
|
578
|
+
function medianBubbleRadius(plotWidth, plotHeight) {
|
|
579
|
+
return Math.min(plotWidth, plotHeight) * 0.04;
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
// chart/stock-candles.ts
|
|
583
|
+
var STOCK_DEFAULT_UP_FILL = "#FFFFFF";
|
|
584
|
+
var STOCK_DEFAULT_DOWN_FILL = "#404040";
|
|
585
|
+
var STOCK_DEFAULT_WICK_COLOR = "#334155";
|
|
586
|
+
var STOCK_TICK_WIDTH = 1.5;
|
|
587
|
+
function stockSlots(count, closeLast = false) {
|
|
588
|
+
if (count < 3) return void 0;
|
|
589
|
+
const four = count >= 4;
|
|
590
|
+
return {
|
|
591
|
+
...four ? { open: 0 } : {},
|
|
592
|
+
high: four ? 1 : 0,
|
|
593
|
+
low: four ? 2 : 1,
|
|
594
|
+
close: closeLast ? count - 1 : four ? 3 : 2
|
|
595
|
+
};
|
|
596
|
+
}
|
|
597
|
+
var present = (v) => v !== null && v !== void 0;
|
|
598
|
+
function stockCandle(input) {
|
|
599
|
+
const { high, low, close, open, x, band, y } = input;
|
|
600
|
+
if (!present(high) || !present(low)) return void 0;
|
|
601
|
+
const candleWidth = band * (input.bodyShare ?? 0.5);
|
|
602
|
+
const candle = { wick: { x, y1: y(high), y2: y(low) } };
|
|
603
|
+
if (input.hasOpen && present(open) && present(close)) {
|
|
604
|
+
const openY = y(open);
|
|
605
|
+
const closeY = y(close);
|
|
606
|
+
candle.body = {
|
|
607
|
+
x: x - candleWidth / 2,
|
|
608
|
+
y: Math.min(openY, closeY),
|
|
609
|
+
w: candleWidth,
|
|
610
|
+
h: Math.max(Math.abs(openY - closeY), 1),
|
|
611
|
+
up: close >= open
|
|
612
|
+
};
|
|
613
|
+
} else if (present(close)) {
|
|
614
|
+
candle.tick = {
|
|
615
|
+
x1: x,
|
|
616
|
+
x2: x + Math.max(candleWidth * 0.4, 4),
|
|
617
|
+
y: y(close)
|
|
618
|
+
};
|
|
619
|
+
}
|
|
620
|
+
return candle;
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
// chart/treemap-squarify.ts
|
|
624
|
+
function worstAspectRatio(areas, side) {
|
|
625
|
+
const sum = areas.reduce((total, area) => total + area, 0);
|
|
626
|
+
const max = Math.max(...areas);
|
|
627
|
+
const min = Math.min(...areas);
|
|
628
|
+
const sideSq = side * side;
|
|
629
|
+
const sumSq = sum * sum;
|
|
630
|
+
return Math.max(sideSq * max / sumSq, sumSq / (sideSq * min));
|
|
631
|
+
}
|
|
632
|
+
function squarify(nodes, box) {
|
|
633
|
+
const sorted = [...nodes].sort((a2, b) => b.weight - a2.weight);
|
|
634
|
+
const total = sorted.reduce((sum, node) => sum + node.weight, 0);
|
|
635
|
+
const scale = total > 0 ? box.w * box.h / total : box.w * box.h / sorted.length;
|
|
636
|
+
const items = sorted.map((node) => ({ node, area: (total > 0 ? node.weight : 1) * scale }));
|
|
637
|
+
const result = [];
|
|
638
|
+
let rect2 = { ...box };
|
|
639
|
+
let remaining = items;
|
|
640
|
+
for (let first2 = remaining[0]; first2 !== void 0; first2 = remaining[0]) {
|
|
641
|
+
const side = Math.min(rect2.w, rect2.h);
|
|
642
|
+
let row = [first2];
|
|
643
|
+
let rowAreas = [first2.area];
|
|
644
|
+
let worst = worstAspectRatio(rowAreas, side);
|
|
645
|
+
let cursor = 1;
|
|
646
|
+
for (let next = remaining[cursor]; next !== void 0; next = remaining[cursor]) {
|
|
647
|
+
const candidateAreas = [...rowAreas, next.area];
|
|
648
|
+
const candidateWorst = worstAspectRatio(candidateAreas, side);
|
|
649
|
+
if (candidateWorst > worst) {
|
|
650
|
+
break;
|
|
651
|
+
}
|
|
652
|
+
row = [...row, next];
|
|
653
|
+
rowAreas = candidateAreas;
|
|
654
|
+
worst = candidateWorst;
|
|
655
|
+
cursor++;
|
|
656
|
+
}
|
|
657
|
+
const rowTotalArea = rowAreas.reduce((sum, area) => sum + area, 0);
|
|
658
|
+
const thickness = side > 0 ? rowTotalArea / side : 0;
|
|
659
|
+
const layoutVertically = rect2.w >= rect2.h;
|
|
660
|
+
let offset = layoutVertically ? rect2.y : rect2.x;
|
|
661
|
+
for (const item of row) {
|
|
662
|
+
const length = thickness > 0 ? item.area / thickness : 0;
|
|
663
|
+
if (layoutVertically) {
|
|
664
|
+
result.push([item.node, { x: rect2.x, y: offset, w: thickness, h: length }]);
|
|
665
|
+
} else {
|
|
666
|
+
result.push([item.node, { x: offset, y: rect2.y, w: length, h: thickness }]);
|
|
667
|
+
}
|
|
668
|
+
offset += length;
|
|
669
|
+
}
|
|
670
|
+
rect2 = layoutVertically ? { ...rect2, x: rect2.x + thickness, w: rect2.w - thickness } : { ...rect2, y: rect2.y + thickness, h: rect2.h - thickness };
|
|
671
|
+
remaining = remaining.slice(row.length);
|
|
672
|
+
}
|
|
673
|
+
return result;
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
// chart/hierarchy.ts
|
|
677
|
+
function normalizeLevels(levels, pointCount) {
|
|
678
|
+
return levels.map((level) => {
|
|
679
|
+
let previous = "";
|
|
680
|
+
return Array.from({ length: pointCount }, (_, index) => {
|
|
681
|
+
const label = level[index]?.trim() ?? "";
|
|
682
|
+
if (label) previous = label;
|
|
683
|
+
return label || previous;
|
|
684
|
+
});
|
|
685
|
+
});
|
|
686
|
+
}
|
|
687
|
+
function findOrAddParent(children2, label, colorIndex, parentLabelLayout) {
|
|
688
|
+
const existing = children2.find((child2) => child2.children && child2.label === label);
|
|
689
|
+
if (existing?.children) return existing;
|
|
690
|
+
const parent = { label, weight: 0, children: [], colorIndex, parentLabelLayout };
|
|
691
|
+
children2.push(parent);
|
|
692
|
+
return parent;
|
|
693
|
+
}
|
|
694
|
+
function buildSeriesHierarchy(series, seriesIndex, categoryLabels, categoryLevels2, colorStride) {
|
|
695
|
+
const pointCount = series.values.length;
|
|
696
|
+
const levels = normalizeLevels(categoryLevels2 ?? [], pointCount);
|
|
697
|
+
const layout = series.parentLabelLayout ?? "banner";
|
|
698
|
+
const roots = [];
|
|
699
|
+
for (let pointIndex = 0; pointIndex < pointCount; pointIndex++) {
|
|
700
|
+
let children2 = roots;
|
|
701
|
+
for (let levelIndex = levels.length - 1; levelIndex >= 1; levelIndex--) {
|
|
702
|
+
const label = levels[levelIndex]?.[pointIndex] || `Group ${levelIndex}`;
|
|
703
|
+
children2 = findOrAddParent(children2, label, pointIndex, layout).children;
|
|
704
|
+
}
|
|
705
|
+
children2.push({
|
|
706
|
+
label: levels[0]?.[pointIndex] || categoryLabels[pointIndex] || String(pointIndex + 1),
|
|
707
|
+
weight: Math.abs(series.values[pointIndex] ?? 0),
|
|
708
|
+
seriesIndex,
|
|
709
|
+
pointIndex,
|
|
710
|
+
colorIndex: seriesIndex * colorStride + pointIndex,
|
|
711
|
+
parentLabelLayout: layout
|
|
712
|
+
});
|
|
713
|
+
}
|
|
714
|
+
return roots;
|
|
715
|
+
}
|
|
716
|
+
function aggregate(node) {
|
|
717
|
+
if (node.children) node.weight = node.children.reduce((sum, child2) => sum + aggregate(child2), 0);
|
|
718
|
+
return node.weight;
|
|
719
|
+
}
|
|
720
|
+
function propagateColor(node, colorIndex) {
|
|
721
|
+
node.colorIndex = colorIndex;
|
|
722
|
+
for (const child2 of node.children ?? []) propagateColor(child2, colorIndex);
|
|
723
|
+
}
|
|
724
|
+
function buildHierarchyRoots(series, categoryLabels, categoryLevels2) {
|
|
725
|
+
const colorStride = Math.max(categoryLabels.length, ...series.map((s) => s.values.length), 1);
|
|
726
|
+
let roots = series.flatMap(
|
|
727
|
+
(s, index) => buildSeriesHierarchy(s, index, categoryLabels, categoryLevels2, colorStride)
|
|
728
|
+
);
|
|
729
|
+
if (series.length > 1)
|
|
730
|
+
roots = series.map((s, index) => ({
|
|
731
|
+
label: s.name,
|
|
732
|
+
weight: 0,
|
|
733
|
+
children: buildSeriesHierarchy(s, index, categoryLabels, categoryLevels2, colorStride),
|
|
734
|
+
colorIndex: index * colorStride,
|
|
735
|
+
parentLabelLayout: s.parentLabelLayout ?? "banner"
|
|
736
|
+
}));
|
|
737
|
+
for (const root of roots) aggregate(root);
|
|
738
|
+
roots.forEach((root, index) => propagateColor(root, index));
|
|
739
|
+
return roots;
|
|
740
|
+
}
|
|
741
|
+
function hierarchyBranchLabels(series, categoryLabels, categoryLevels2) {
|
|
742
|
+
if (series.length > 1) return series.map((s) => s.name);
|
|
743
|
+
if (categoryLevels2 && categoryLevels2.length > 1) {
|
|
744
|
+
const pointCount = series[0]?.values.length ?? categoryLabels.length;
|
|
745
|
+
const topLevel = normalizeLevels(categoryLevels2, pointCount).at(-1) ?? [];
|
|
746
|
+
const seen = [];
|
|
747
|
+
for (const label of topLevel) if (!seen.includes(label)) seen.push(label);
|
|
748
|
+
return seen;
|
|
749
|
+
}
|
|
750
|
+
return [...categoryLabels];
|
|
751
|
+
}
|
|
752
|
+
var BANNER_HEIGHT = 16;
|
|
753
|
+
function layoutTreemap(nodes, box) {
|
|
754
|
+
const cells = [];
|
|
755
|
+
for (const [node, allocation] of squarify(nodes, box)) {
|
|
756
|
+
const cell = {
|
|
757
|
+
x: allocation.x + 1,
|
|
758
|
+
y: allocation.y + 1,
|
|
759
|
+
w: Math.max(allocation.w - 2, 1),
|
|
760
|
+
h: Math.max(allocation.h - 2, 1)
|
|
761
|
+
};
|
|
762
|
+
if (node.children) {
|
|
763
|
+
const showParent = node.parentLabelLayout !== "none" && cell.w > 28 && cell.h > 16;
|
|
764
|
+
if (showParent)
|
|
765
|
+
cells.push({ kind: "parent", label: node.label, x: cell.x + 4, y: cell.y + 11 });
|
|
766
|
+
const banner = showParent && node.parentLabelLayout === "banner" ? BANNER_HEIGHT : 0;
|
|
767
|
+
cells.push(
|
|
768
|
+
...layoutTreemap(node.children, {
|
|
769
|
+
...cell,
|
|
770
|
+
y: cell.y + banner,
|
|
771
|
+
h: Math.max(cell.h - banner, 1)
|
|
772
|
+
})
|
|
773
|
+
);
|
|
774
|
+
continue;
|
|
775
|
+
}
|
|
776
|
+
cells.push({
|
|
777
|
+
kind: "leaf",
|
|
778
|
+
...cell,
|
|
779
|
+
label: node.label,
|
|
780
|
+
colorIndex: node.colorIndex,
|
|
781
|
+
seriesIndex: node.seriesIndex ?? 0,
|
|
782
|
+
pointIndex: node.pointIndex ?? 0,
|
|
783
|
+
labelFits: cell.w > 30 && cell.h > 14,
|
|
784
|
+
labelSize: Math.min(10, cell.h * 0.3)
|
|
785
|
+
});
|
|
786
|
+
}
|
|
787
|
+
return cells;
|
|
788
|
+
}
|
|
789
|
+
|
|
790
|
+
// chart/sunburst-arcs.ts
|
|
791
|
+
function arcLabelPlacement(cx2, cy, radius, startAngle, endAngle) {
|
|
792
|
+
const midAngle = (startAngle + endAngle) / 2;
|
|
793
|
+
let rotation = midAngle * 180 / Math.PI + 90;
|
|
794
|
+
if (rotation > 90 && rotation < 270) rotation -= 180;
|
|
795
|
+
return {
|
|
796
|
+
labelX: cx2 + radius * Math.cos(midAngle),
|
|
797
|
+
labelY: cy + radius * Math.sin(midAngle),
|
|
798
|
+
labelRotation: rotation
|
|
799
|
+
};
|
|
800
|
+
}
|
|
801
|
+
function sunburstArcPath(cx2, cy, innerRadius, outerRadius, startAngle, endAngle) {
|
|
802
|
+
const sweep = endAngle - startAngle;
|
|
803
|
+
const largeArc = sweep > Math.PI ? 1 : 0;
|
|
804
|
+
const x1 = cx2 + outerRadius * Math.cos(startAngle);
|
|
805
|
+
const y1 = cy + outerRadius * Math.sin(startAngle);
|
|
806
|
+
const x2 = cx2 + outerRadius * Math.cos(endAngle);
|
|
807
|
+
const y2 = cy + outerRadius * Math.sin(endAngle);
|
|
808
|
+
const x3 = cx2 + innerRadius * Math.cos(endAngle);
|
|
809
|
+
const y3 = cy + innerRadius * Math.sin(endAngle);
|
|
810
|
+
const x4 = cx2 + innerRadius * Math.cos(startAngle);
|
|
811
|
+
const y4 = cy + innerRadius * Math.sin(startAngle);
|
|
812
|
+
return `M ${x1} ${y1} A ${outerRadius} ${outerRadius} 0 ${largeArc} 1 ${x2} ${y2} L ${x3} ${y3} A ${innerRadius} ${innerRadius} 0 ${largeArc} 0 ${x4} ${y4} Z`;
|
|
813
|
+
}
|
|
814
|
+
function computeSunburstArcs(series, cx2, cy, maxR) {
|
|
815
|
+
const seriesCount = Math.max(series.length, 1);
|
|
816
|
+
const ringWidth = maxR / (seriesCount + 0.5);
|
|
817
|
+
const out = [];
|
|
818
|
+
series.forEach((s, si) => {
|
|
819
|
+
const values = s.values;
|
|
820
|
+
const innerRadius = ringWidth * (si + 0.5);
|
|
821
|
+
const outerRadius = ringWidth * (si + 1.5);
|
|
822
|
+
const total = values.reduce((acc, value) => acc + Math.abs(value), 0) || 1;
|
|
823
|
+
let startAngle = -Math.PI / 2;
|
|
824
|
+
for (let pointIndex = 0; pointIndex < values.length; pointIndex++) {
|
|
825
|
+
const endAngle = startAngle + Math.abs(values[pointIndex] ?? 0) / total * Math.PI * 2;
|
|
826
|
+
out.push({
|
|
827
|
+
d: sunburstArcPath(cx2, cy, innerRadius, outerRadius, startAngle, endAngle),
|
|
828
|
+
colorIndex: pointIndex,
|
|
829
|
+
opacity: Math.max(0.1, 0.9 - si * 0.1),
|
|
830
|
+
pointIndex,
|
|
831
|
+
level: si,
|
|
832
|
+
...arcLabelPlacement(cx2, cy, (innerRadius + outerRadius) / 2, startAngle, endAngle)
|
|
833
|
+
});
|
|
834
|
+
startAngle = endAngle;
|
|
835
|
+
}
|
|
836
|
+
});
|
|
837
|
+
return out;
|
|
838
|
+
}
|
|
839
|
+
function hierarchyKey(levels, level, index) {
|
|
840
|
+
return levels.slice(level).map((labels) => labels[index] ?? "").join("\0");
|
|
841
|
+
}
|
|
842
|
+
function computeHierarchicalSunburstArcs(categoryLevels2, values, cx2, cy, maxR) {
|
|
843
|
+
const levels = categoryLevels2.filter((level) => level.length > 0);
|
|
844
|
+
const leafCount = Math.max(values.length, ...levels.map((level) => level.length), 0);
|
|
845
|
+
if (levels.length === 0 || leafCount === 0) return [];
|
|
846
|
+
const rawWeights = Array.from({ length: leafCount }, (_, index) => Math.abs(values[index] ?? 0));
|
|
847
|
+
const weights = rawWeights.some((value) => value !== 0) ? rawWeights : rawWeights.map(() => 1);
|
|
848
|
+
const total = weights.reduce((sum, value) => sum + value, 0);
|
|
849
|
+
const prefix = [0];
|
|
850
|
+
for (const weight of weights) prefix.push((prefix[prefix.length - 1] ?? 0) + weight);
|
|
851
|
+
const ringWidth = maxR / (levels.length + 0.5);
|
|
852
|
+
const rootLabels = levels[levels.length - 1] ?? [];
|
|
853
|
+
const rootColors = /* @__PURE__ */ new Map();
|
|
854
|
+
const out = [];
|
|
855
|
+
for (let level = levels.length - 1; level >= 0; level--) {
|
|
856
|
+
const ringIndex = levels.length - 1 - level;
|
|
857
|
+
const innerRadius = ringWidth * (ringIndex + 0.5);
|
|
858
|
+
const outerRadius = ringWidth * (ringIndex + 1.5);
|
|
859
|
+
let start = 0;
|
|
860
|
+
while (start < leafCount) {
|
|
861
|
+
const key = hierarchyKey(levels, level, start);
|
|
862
|
+
let end = start + 1;
|
|
863
|
+
while (end < leafCount && hierarchyKey(levels, level, end) === key) end++;
|
|
864
|
+
const startAngle = -Math.PI / 2 + (prefix[start] ?? 0) / total * Math.PI * 2;
|
|
865
|
+
const endAngle = -Math.PI / 2 + (prefix[end] ?? 0) / total * Math.PI * 2;
|
|
866
|
+
const rootLabel = rootLabels[start] ?? "";
|
|
867
|
+
if (!rootColors.has(rootLabel)) rootColors.set(rootLabel, rootColors.size);
|
|
868
|
+
out.push({
|
|
869
|
+
d: sunburstArcPath(cx2, cy, innerRadius, outerRadius, startAngle, endAngle),
|
|
870
|
+
colorIndex: rootColors.get(rootLabel) ?? start,
|
|
871
|
+
opacity: Math.max(0.1, 0.9 - ringIndex * 0.1),
|
|
872
|
+
level: ringIndex,
|
|
873
|
+
label: levels[level]?.[start] ?? "",
|
|
874
|
+
...level === 0 && end === start + 1 ? { pointIndex: start } : {},
|
|
875
|
+
...arcLabelPlacement(cx2, cy, (innerRadius + outerRadius) / 2, startAngle, endAngle)
|
|
876
|
+
});
|
|
877
|
+
start = end;
|
|
878
|
+
}
|
|
879
|
+
}
|
|
880
|
+
return out;
|
|
881
|
+
}
|
|
882
|
+
|
|
883
|
+
// chart/style-palette.ts
|
|
884
|
+
function hexToRgb(hex) {
|
|
885
|
+
const h = hex.replace("#", "");
|
|
886
|
+
return [
|
|
887
|
+
parseInt(h.substring(0, 2), 16),
|
|
888
|
+
parseInt(h.substring(2, 4), 16),
|
|
889
|
+
parseInt(h.substring(4, 6), 16)
|
|
890
|
+
];
|
|
891
|
+
}
|
|
892
|
+
function rgbToHex(r, g, b) {
|
|
893
|
+
const clamp = (v) => Math.max(0, Math.min(255, Math.round(v)));
|
|
894
|
+
return `#${clamp(r).toString(16).padStart(2, "0")}${clamp(g).toString(16).padStart(2, "0")}${clamp(b).toString(16).padStart(2, "0")}`;
|
|
895
|
+
}
|
|
896
|
+
function tint(hex, amount) {
|
|
897
|
+
const [r, g, b] = hexToRgb(hex);
|
|
898
|
+
return rgbToHex(r + (255 - r) * amount, g + (255 - g) * amount, b + (255 - b) * amount);
|
|
899
|
+
}
|
|
900
|
+
function shade(hex, amount) {
|
|
901
|
+
const [r, g, b] = hexToRgb(hex);
|
|
902
|
+
return rgbToHex(r * (1 - amount), g * (1 - amount), b * (1 - amount));
|
|
903
|
+
}
|
|
904
|
+
var OFFICE_ACCENTS = [
|
|
905
|
+
"#4472C4",
|
|
906
|
+
"#ED7D31",
|
|
907
|
+
"#A5A5A5",
|
|
908
|
+
"#FFC000",
|
|
909
|
+
"#5B9BD5",
|
|
910
|
+
"#70AD47"
|
|
911
|
+
];
|
|
912
|
+
var DEFAULT_EXTRAS = ["#FF0000", "#00B0F0"];
|
|
913
|
+
var DEFAULT_CHART_PALETTE = [...OFFICE_ACCENTS, ...DEFAULT_EXTRAS];
|
|
914
|
+
function monochromaticRamp(base) {
|
|
915
|
+
return [
|
|
916
|
+
shade(base, 0.5),
|
|
917
|
+
shade(base, 0.35),
|
|
918
|
+
shade(base, 0.15),
|
|
919
|
+
base,
|
|
920
|
+
tint(base, 0.2),
|
|
921
|
+
tint(base, 0.4),
|
|
922
|
+
tint(base, 0.6),
|
|
923
|
+
tint(base, 0.8)
|
|
924
|
+
];
|
|
925
|
+
}
|
|
926
|
+
var GREY = "#7F7F7F";
|
|
927
|
+
function buildPalette(column, accents) {
|
|
928
|
+
if (column === 0) {
|
|
929
|
+
return monochromaticRamp(GREY);
|
|
930
|
+
}
|
|
931
|
+
if (column === 1) {
|
|
932
|
+
return [...accents, ...accents.map((accent) => shade(accent, 0.4))];
|
|
933
|
+
}
|
|
934
|
+
return monochromaticRamp(accents[column - 2]);
|
|
935
|
+
}
|
|
936
|
+
function usableAccents(accents) {
|
|
937
|
+
return accents?.length === 6 && accents.every((accent) => /^#[0-9a-f]{6}$/iu.test(accent)) ? accents : OFFICE_ACCENTS;
|
|
938
|
+
}
|
|
939
|
+
var paletteCache = /* @__PURE__ */ new Map();
|
|
940
|
+
function getChartStylePalette(styleId, themeAccents) {
|
|
941
|
+
const accents = usableAccents(themeAccents);
|
|
942
|
+
const valid = styleId !== void 0 && styleId >= 1 && styleId <= 48;
|
|
943
|
+
if (!valid && accents === OFFICE_ACCENTS) {
|
|
944
|
+
return DEFAULT_CHART_PALETTE;
|
|
945
|
+
}
|
|
946
|
+
const column = valid ? (Math.trunc(styleId) - 1) % 8 : -1;
|
|
947
|
+
const key = `${column}:${accents.join(",")}`;
|
|
948
|
+
let palette = paletteCache.get(key);
|
|
949
|
+
if (!palette) {
|
|
950
|
+
palette = column < 0 ? [...accents, ...DEFAULT_EXTRAS] : buildPalette(column, accents);
|
|
951
|
+
paletteCache.set(key, palette);
|
|
952
|
+
}
|
|
953
|
+
return palette;
|
|
954
|
+
}
|
|
955
|
+
|
|
293
956
|
// chart/histogram-binning.ts
|
|
294
957
|
function binLabel(lower, upper, closed, format) {
|
|
295
958
|
return closed === "r" ? `(${format(lower)}, ${format(upper)}]` : `[${format(lower)}, ${format(upper)})`;
|
|
@@ -382,57 +1045,38 @@ function aggregateByCategory(values, rawCategories) {
|
|
|
382
1045
|
});
|
|
383
1046
|
}
|
|
384
1047
|
|
|
385
|
-
// chart/
|
|
386
|
-
function
|
|
387
|
-
const
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
const
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
const candidateAreas = [...rowAreas, next.area];
|
|
410
|
-
const candidateWorst = worstAspectRatio(candidateAreas, side);
|
|
411
|
-
if (candidateWorst > worst) {
|
|
412
|
-
break;
|
|
413
|
-
}
|
|
414
|
-
row = [...row, next];
|
|
415
|
-
rowAreas = candidateAreas;
|
|
416
|
-
worst = candidateWorst;
|
|
417
|
-
cursor++;
|
|
418
|
-
}
|
|
419
|
-
const rowTotalArea = rowAreas.reduce((sum, area) => sum + area, 0);
|
|
420
|
-
const thickness = side > 0 ? rowTotalArea / side : 0;
|
|
421
|
-
const layoutVertically = rect2.w >= rect2.h;
|
|
422
|
-
let offset = layoutVertically ? rect2.y : rect2.x;
|
|
423
|
-
for (const item of row) {
|
|
424
|
-
const length = thickness > 0 ? item.area / thickness : 0;
|
|
425
|
-
if (layoutVertically) {
|
|
426
|
-
result.push([item.node, { x: rect2.x, y: offset, w: thickness, h: length }]);
|
|
427
|
-
} else {
|
|
428
|
-
result.push([item.node, { x: offset, y: rect2.y, w: length, h: thickness }]);
|
|
429
|
-
}
|
|
430
|
-
offset += length;
|
|
1048
|
+
// chart/waterfall.ts
|
|
1049
|
+
function buildWaterfallSteps(values, options) {
|
|
1050
|
+
const subtotalIndices = new Set(
|
|
1051
|
+
options?.subtotalIndices ?? (values.length > 0 ? [values.length - 1] : [])
|
|
1052
|
+
);
|
|
1053
|
+
const steps = [];
|
|
1054
|
+
let runningTotal = 0;
|
|
1055
|
+
for (let sourceIndex = 0; sourceIndex < values.length; sourceIndex++) {
|
|
1056
|
+
const value = values[sourceIndex] ?? 0;
|
|
1057
|
+
const isSubtotal = subtotalIndices.has(sourceIndex);
|
|
1058
|
+
const startValue = isSubtotal ? 0 : runningTotal;
|
|
1059
|
+
const endValue = isSubtotal ? value : runningTotal + value;
|
|
1060
|
+
steps.push({ sourceIndex, value, startValue, endValue, isSubtotal });
|
|
1061
|
+
runningTotal = endValue;
|
|
1062
|
+
}
|
|
1063
|
+
return steps;
|
|
1064
|
+
}
|
|
1065
|
+
function computeWaterfallRange(steps, plotHeightPx) {
|
|
1066
|
+
let dataMin = Number.POSITIVE_INFINITY;
|
|
1067
|
+
let dataMax = Number.NEGATIVE_INFINITY;
|
|
1068
|
+
for (const step of steps)
|
|
1069
|
+
for (const value of [step.startValue, step.endValue]) {
|
|
1070
|
+
if (value < dataMin) dataMin = value;
|
|
1071
|
+
if (value > dataMax) dataMax = value;
|
|
431
1072
|
}
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
1073
|
+
if (dataMin === Number.POSITIVE_INFINITY) return { min: 0, max: 1, span: 1 };
|
|
1074
|
+
const { min, max, majorUnit } = niceValueAxisBounds(
|
|
1075
|
+
dataMin,
|
|
1076
|
+
dataMax,
|
|
1077
|
+
plotHeightPx !== void 0 ? axisTargetIntervals(plotHeightPx) : void 0
|
|
1078
|
+
);
|
|
1079
|
+
return { min, max, span: Math.max(max - min, Number.EPSILON), majorUnit };
|
|
436
1080
|
}
|
|
437
1081
|
|
|
438
1082
|
// chart/trendline-equation.ts
|
|
@@ -461,16 +1105,147 @@ function formatLogarithmicEquation(slope, intercept) {
|
|
|
461
1105
|
function formatPowerEquation(a2, b) {
|
|
462
1106
|
return `y = ${formatTrendlineCoefficient(a2)}x^${formatTrendlineCoefficient(b)}`;
|
|
463
1107
|
}
|
|
464
|
-
function formatPolynomialEquation(coeffsAscending) {
|
|
465
|
-
const order = coeffsAscending.length - 1;
|
|
466
|
-
let out = "y = ";
|
|
467
|
-
for (let power = order; power >= 0; power--) {
|
|
468
|
-
const coeff = coeffsAscending[power] ?? 0;
|
|
469
|
-
const { sign, abs } = signedTerm(coeff);
|
|
470
|
-
const variable = power === 0 ? "" : power === 1 ? "x" : `x^${power}`;
|
|
471
|
-
out += power === order ? `${sign === "-" ? "-" : ""}${abs}${variable}` : ` ${sign} ${abs}${variable}`;
|
|
1108
|
+
function formatPolynomialEquation(coeffsAscending) {
|
|
1109
|
+
const order = coeffsAscending.length - 1;
|
|
1110
|
+
let out = "y = ";
|
|
1111
|
+
for (let power = order; power >= 0; power--) {
|
|
1112
|
+
const coeff = coeffsAscending[power] ?? 0;
|
|
1113
|
+
const { sign, abs } = signedTerm(coeff);
|
|
1114
|
+
const variable = power === 0 ? "" : power === 1 ? "x" : `x^${power}`;
|
|
1115
|
+
out += power === order ? `${sign === "-" ? "-" : ""}${abs}${variable}` : ` ${sign} ${abs}${variable}`;
|
|
1116
|
+
}
|
|
1117
|
+
return out;
|
|
1118
|
+
}
|
|
1119
|
+
|
|
1120
|
+
// chart/trendline-fit.ts
|
|
1121
|
+
var noFit = () => ({
|
|
1122
|
+
points: [],
|
|
1123
|
+
equation: "",
|
|
1124
|
+
rSquared: 0,
|
|
1125
|
+
coefficients: []
|
|
1126
|
+
});
|
|
1127
|
+
function fitModel(options, xVals, yVals) {
|
|
1128
|
+
const xs = [...xVals];
|
|
1129
|
+
const ys = [...yVals];
|
|
1130
|
+
switch (options.kind) {
|
|
1131
|
+
case "linear": {
|
|
1132
|
+
const reg = computeLinearRegression(xs, ys);
|
|
1133
|
+
const fixed = options.intercept;
|
|
1134
|
+
const slope = fixed !== void 0 ? ys.reduce((s, y, i) => s + (y - fixed) * xs[i], 0) / xs.reduce((s, x) => s + x * x, 0) : reg.slope;
|
|
1135
|
+
const b = fixed ?? reg.intercept;
|
|
1136
|
+
return {
|
|
1137
|
+
evaluate: (x) => slope * x + b,
|
|
1138
|
+
equation: formatLinearEquation(slope, b),
|
|
1139
|
+
rSquared: reg.rSquared,
|
|
1140
|
+
coefficients: [b, slope]
|
|
1141
|
+
};
|
|
1142
|
+
}
|
|
1143
|
+
case "exponential": {
|
|
1144
|
+
const logY = ys.filter((y) => y > 0).map((y) => Math.log(y));
|
|
1145
|
+
const posX = xs.filter((_x, i) => ys[i] > 0);
|
|
1146
|
+
if (logY.length < 2) return void 0;
|
|
1147
|
+
const reg = computeLinearRegression(posX, logY);
|
|
1148
|
+
const a2 = Math.exp(reg.intercept);
|
|
1149
|
+
const b = reg.slope;
|
|
1150
|
+
return {
|
|
1151
|
+
evaluate: (x) => a2 * Math.exp(b * x),
|
|
1152
|
+
equation: formatExponentialEquation(a2, b),
|
|
1153
|
+
rSquared: reg.rSquared,
|
|
1154
|
+
coefficients: [a2, b]
|
|
1155
|
+
};
|
|
1156
|
+
}
|
|
1157
|
+
case "logarithmic": {
|
|
1158
|
+
const lnX = xs.filter((x) => x > 0).map((x) => Math.log(x));
|
|
1159
|
+
const posY = ys.filter((_y, i) => xs[i] > 0);
|
|
1160
|
+
if (lnX.length < 2) return void 0;
|
|
1161
|
+
const reg = computeLinearRegression(lnX, posY);
|
|
1162
|
+
return {
|
|
1163
|
+
evaluate: (x) => x > 0 ? reg.slope * Math.log(x) + reg.intercept : 0,
|
|
1164
|
+
equation: formatLogarithmicEquation(reg.slope, reg.intercept),
|
|
1165
|
+
rSquared: reg.rSquared,
|
|
1166
|
+
coefficients: [reg.intercept, reg.slope]
|
|
1167
|
+
};
|
|
1168
|
+
}
|
|
1169
|
+
case "power": {
|
|
1170
|
+
const logX = xs.filter((x, i) => x > 0 && ys[i] > 0).map((x) => Math.log(x));
|
|
1171
|
+
const logY = ys.filter((y, i) => y > 0 && xs[i] > 0).map((y) => Math.log(y));
|
|
1172
|
+
if (logX.length < 2) return void 0;
|
|
1173
|
+
const reg = computeLinearRegression(logX, logY);
|
|
1174
|
+
const a2 = Math.exp(reg.intercept);
|
|
1175
|
+
return {
|
|
1176
|
+
evaluate: (x) => x > 0 ? a2 * x ** reg.slope : 0,
|
|
1177
|
+
equation: formatPowerEquation(a2, reg.slope),
|
|
1178
|
+
rSquared: reg.rSquared,
|
|
1179
|
+
coefficients: [a2, reg.slope]
|
|
1180
|
+
};
|
|
1181
|
+
}
|
|
1182
|
+
case "polynomial": {
|
|
1183
|
+
const order = Math.min(options.order ?? 2, 6);
|
|
1184
|
+
const coeffs = fitPolynomial(xs, ys, order);
|
|
1185
|
+
const evaluate = (x) => coeffs.reduce((s, c2, i) => s + c2 * x ** i, 0);
|
|
1186
|
+
return {
|
|
1187
|
+
evaluate,
|
|
1188
|
+
equation: formatPolynomialEquation(coeffs),
|
|
1189
|
+
rSquared: computeRSquared(xs, ys, evaluate),
|
|
1190
|
+
coefficients: coeffs
|
|
1191
|
+
};
|
|
1192
|
+
}
|
|
1193
|
+
default:
|
|
1194
|
+
return void 0;
|
|
1195
|
+
}
|
|
1196
|
+
}
|
|
1197
|
+
function fitChartTrendline(options, xVals, yVals) {
|
|
1198
|
+
const count = yVals.length;
|
|
1199
|
+
if (count < 2) return noFit();
|
|
1200
|
+
if (options.kind === "movingAvg") {
|
|
1201
|
+
const period = options.period ?? 2;
|
|
1202
|
+
const points2 = [];
|
|
1203
|
+
for (let i = period - 1; i < count; i++) {
|
|
1204
|
+
let sum = 0;
|
|
1205
|
+
for (let j = i - period + 1; j <= i; j++) sum += yVals[j];
|
|
1206
|
+
points2.push({ x: xVals[i], y: sum / period });
|
|
1207
|
+
}
|
|
1208
|
+
return { points: points2, equation: `${period}-period moving average`, rSquared: 0, coefficients: [] };
|
|
1209
|
+
}
|
|
1210
|
+
const model = fitModel(options, xVals, yVals);
|
|
1211
|
+
if (!model) return noFit();
|
|
1212
|
+
const startX = Math.min(...xVals) - (options.backward ?? 0);
|
|
1213
|
+
const endX = Math.max(...xVals) + (options.forward ?? 0);
|
|
1214
|
+
const steps = Math.max(Math.ceil((endX - startX) * 4), 20);
|
|
1215
|
+
const points = [];
|
|
1216
|
+
for (let step = 0; step <= steps; step++) {
|
|
1217
|
+
const x = startX + (endX - startX) * step / steps;
|
|
1218
|
+
const y = model.evaluate(x);
|
|
1219
|
+
if (Number.isFinite(y)) points.push({ x, y });
|
|
1220
|
+
}
|
|
1221
|
+
return {
|
|
1222
|
+
points,
|
|
1223
|
+
equation: model.equation,
|
|
1224
|
+
rSquared: model.rSquared,
|
|
1225
|
+
coefficients: model.coefficients
|
|
1226
|
+
};
|
|
1227
|
+
}
|
|
1228
|
+
|
|
1229
|
+
// chart/error-bar-amount.ts
|
|
1230
|
+
function chartSampleVariance(values) {
|
|
1231
|
+
const count = values.length;
|
|
1232
|
+
if (count === 0) return 0;
|
|
1233
|
+
const mean = values.reduce((sum, value) => sum + value, 0) / count;
|
|
1234
|
+
return values.reduce((sum, value) => sum + (value - mean) ** 2, 0) / Math.max(count - 1, 1);
|
|
1235
|
+
}
|
|
1236
|
+
function chartErrorBarAmount(options, values, displayIndex, sourceIndex, side) {
|
|
1237
|
+
switch (options.valueType) {
|
|
1238
|
+
case "fixedVal":
|
|
1239
|
+
return options.value ?? 0;
|
|
1240
|
+
case "percentage":
|
|
1241
|
+
return Math.abs(values[displayIndex] ?? 0) * ((options.value ?? 0) / 100);
|
|
1242
|
+
case "stdDev":
|
|
1243
|
+
return Math.sqrt(chartSampleVariance(values)) * (options.value ?? 1);
|
|
1244
|
+
case "stdErr":
|
|
1245
|
+
return Math.sqrt(chartSampleVariance(values) / Math.max(values.length, 1));
|
|
1246
|
+
case "cust":
|
|
1247
|
+
return side === "plus" ? options.customPlus?.[sourceIndex] ?? 0 : options.customMinus?.[sourceIndex] ?? 0;
|
|
472
1248
|
}
|
|
473
|
-
return out;
|
|
474
1249
|
}
|
|
475
1250
|
|
|
476
1251
|
// chart/radar-geometry.ts
|
|
@@ -478,18 +1253,18 @@ function radarAngle(index, catCount) {
|
|
|
478
1253
|
const n2 = Math.max(catCount, 1);
|
|
479
1254
|
return Math.PI * 2 * index / n2 - Math.PI / 2;
|
|
480
1255
|
}
|
|
481
|
-
function computeRadarPoints(values, maxVal, radius,
|
|
1256
|
+
function computeRadarPoints(values, maxVal, radius, cx2, cy, catCount) {
|
|
482
1257
|
const denom = maxVal > 0 ? maxVal : 1;
|
|
483
1258
|
return values.slice(0, Math.max(catCount, 1)).map((val, i) => {
|
|
484
1259
|
const angle = radarAngle(i, catCount), r = Math.abs(val) / denom * radius;
|
|
485
|
-
return { x:
|
|
1260
|
+
return { x: cx2 + r * Math.cos(angle), y: cy + r * Math.sin(angle) };
|
|
486
1261
|
});
|
|
487
1262
|
}
|
|
488
|
-
function radarRingPoints(
|
|
1263
|
+
function radarRingPoints(cx2, cy, rr, catCount) {
|
|
489
1264
|
const n2 = Math.max(catCount, 1);
|
|
490
1265
|
return Array.from({ length: n2 }, (_, i) => {
|
|
491
1266
|
const angle = radarAngle(i, n2);
|
|
492
|
-
return `${(
|
|
1267
|
+
return `${(cx2 + rr * Math.cos(angle)).toFixed(2)},${(cy + rr * Math.sin(angle)).toFixed(2)}`;
|
|
493
1268
|
}).join(" ");
|
|
494
1269
|
}
|
|
495
1270
|
|
|
@@ -623,13 +1398,13 @@ function hexToRgbChannels(color) {
|
|
|
623
1398
|
b: Number.parseInt(normalized.slice(4, 6), 16)
|
|
624
1399
|
};
|
|
625
1400
|
}
|
|
626
|
-
function percentDivisorFor(
|
|
627
|
-
return
|
|
1401
|
+
function percentDivisorFor(text3) {
|
|
1402
|
+
return text3.endsWith("%") ? 100 : 1e5;
|
|
628
1403
|
}
|
|
629
1404
|
function parseOoxmlPercent(value) {
|
|
630
|
-
const
|
|
631
|
-
const divisor = percentDivisorFor(
|
|
632
|
-
const magnitude = Number.parseFloat(divisor === 100 ?
|
|
1405
|
+
const text3 = String(value ?? "").trim();
|
|
1406
|
+
const divisor = percentDivisorFor(text3);
|
|
1407
|
+
const magnitude = Number.parseFloat(divisor === 100 ? text3.slice(0, -1) : text3);
|
|
633
1408
|
if (!Number.isFinite(magnitude)) {
|
|
634
1409
|
return void 0;
|
|
635
1410
|
}
|
|
@@ -1030,16 +1805,42 @@ var NS = {
|
|
|
1030
1805
|
a: "http://schemas.openxmlformats.org/drawingml/2006/main",
|
|
1031
1806
|
/** DrawingML chart. */
|
|
1032
1807
|
c: "http://schemas.openxmlformats.org/drawingml/2006/chart",
|
|
1808
|
+
/** Office 2016 extended charts (waterfall, histogram, funnel...; `cx:chartSpace`). */
|
|
1809
|
+
cx: "http://schemas.microsoft.com/office/drawing/2014/chartex",
|
|
1033
1810
|
/** Office 2010 chart extensions, including built-in modern chart styles. */
|
|
1034
1811
|
c14: "http://schemas.microsoft.com/office/drawing/2007/8/2/chart",
|
|
1035
1812
|
/** Relationships (`r:id`, `r:embed`). */
|
|
1036
1813
|
r: "http://schemas.openxmlformats.org/officeDocument/2006/relationships",
|
|
1037
1814
|
/** Markup compatibility (`mc:AlternateContent`). */
|
|
1038
1815
|
mc: "http://schemas.openxmlformats.org/markup-compatibility/2006"};
|
|
1816
|
+
var DEFAULT_XML_LIMITS = {
|
|
1817
|
+
maxDepth: 512,
|
|
1818
|
+
maxNodes: 5e6
|
|
1819
|
+
};
|
|
1820
|
+
var MARKUP_RE = /<!--[\s\S]*?-->|<!\[CDATA\[[\s\S]*?\]\]>|<\?[\s\S]*?\?>|<(\/?)([^\s\/>]+)(?:\s+[^\s=\/>]+\s*=\s*(?:"[^"]*"|'[^']*'))*\s*(\/?)>/g;
|
|
1821
|
+
function checkXmlLimits(xml, label, limits = {}) {
|
|
1822
|
+
const maxDepth = limits.maxDepth ?? DEFAULT_XML_LIMITS.maxDepth;
|
|
1823
|
+
const maxNodes = limits.maxNodes ?? DEFAULT_XML_LIMITS.maxNodes;
|
|
1824
|
+
let depth = 0;
|
|
1825
|
+
let nodes = 0;
|
|
1826
|
+
for (const match of xml.matchAll(MARKUP_RE)) {
|
|
1827
|
+
const [, closing, name, selfClosing] = match;
|
|
1828
|
+
if (name === void 0) continue;
|
|
1829
|
+
if (closing) {
|
|
1830
|
+
depth--;
|
|
1831
|
+
continue;
|
|
1832
|
+
}
|
|
1833
|
+
nodes++;
|
|
1834
|
+
if (nodes > maxNodes) throw new Error(`${label} XML exceeds the limit of ${maxNodes} elements`);
|
|
1835
|
+
if (!selfClosing && ++depth > maxDepth)
|
|
1836
|
+
throw new Error(`${label} XML exceeds the nesting depth limit of ${maxDepth}`);
|
|
1837
|
+
}
|
|
1838
|
+
}
|
|
1039
1839
|
function parseXml(xml, options = {}) {
|
|
1040
1840
|
const label = options.label ?? "OOXML";
|
|
1041
1841
|
if (/<!DOCTYPE|<!ENTITY/i.test(xml))
|
|
1042
1842
|
throw new Error(`${label} XML with DTD or entity declarations is not supported`);
|
|
1843
|
+
checkXmlLimits(xml, label, options.limits);
|
|
1043
1844
|
let parseError = "";
|
|
1044
1845
|
let parsed;
|
|
1045
1846
|
try {
|
|
@@ -1259,17 +2060,17 @@ function resolveDrawingColor(color, theme, options) {
|
|
|
1259
2060
|
}
|
|
1260
2061
|
if (has("inv")) [r, g, b] = [255 - r, 255 - g, 255 - b];
|
|
1261
2062
|
if (has("gray")) r = g = b = Math.round(0.299 * r + 0.587 * g + 0.114 * b);
|
|
1262
|
-
const
|
|
1263
|
-
if (
|
|
1264
|
-
r = linearToSrgb255(srgb255ToLinear(r) *
|
|
1265
|
-
g = linearToSrgb255(srgb255ToLinear(g) *
|
|
1266
|
-
b = linearToSrgb255(srgb255ToLinear(b) *
|
|
1267
|
-
}
|
|
1268
|
-
const
|
|
1269
|
-
if (
|
|
1270
|
-
r = linearToSrgb255(1 - (1 - srgb255ToLinear(r)) *
|
|
1271
|
-
g = linearToSrgb255(1 - (1 - srgb255ToLinear(g)) *
|
|
1272
|
-
b = linearToSrgb255(1 - (1 - srgb255ToLinear(b)) *
|
|
2063
|
+
const shade2 = parseDrawingPercent(find("shade"));
|
|
2064
|
+
if (shade2 !== void 0) {
|
|
2065
|
+
r = linearToSrgb255(srgb255ToLinear(r) * shade2);
|
|
2066
|
+
g = linearToSrgb255(srgb255ToLinear(g) * shade2);
|
|
2067
|
+
b = linearToSrgb255(srgb255ToLinear(b) * shade2);
|
|
2068
|
+
}
|
|
2069
|
+
const tint2 = parseDrawingPercent(find("tint"));
|
|
2070
|
+
if (tint2 !== void 0) {
|
|
2071
|
+
r = linearToSrgb255(1 - (1 - srgb255ToLinear(r)) * tint2);
|
|
2072
|
+
g = linearToSrgb255(1 - (1 - srgb255ToLinear(g)) * tint2);
|
|
2073
|
+
b = linearToSrgb255(1 - (1 - srgb255ToLinear(b)) * tint2);
|
|
1273
2074
|
}
|
|
1274
2075
|
if (["hue", "hueMod", "hueOff", "sat", "satMod", "satOff", "lum", "lumMod", "lumOff"].some(has)) {
|
|
1275
2076
|
const hsl = rgbToHsl(r, g, b);
|
|
@@ -1621,28 +2422,28 @@ function parseDrawingLine(ln) {
|
|
|
1621
2422
|
}
|
|
1622
2423
|
|
|
1623
2424
|
// chart/read-appearance.ts
|
|
1624
|
-
function readChartAppearance(
|
|
2425
|
+
function readChartAppearance(text3, properties2) {
|
|
1625
2426
|
const out = {};
|
|
1626
|
-
const size = Number(
|
|
2427
|
+
const size = Number(text3?.getAttribute("sz") ?? NaN);
|
|
1627
2428
|
if (Number.isFinite(size) && size > 0) out.fontSize = size / 100;
|
|
1628
2429
|
for (const [attribute2, key] of [
|
|
1629
2430
|
["b", "bold"],
|
|
1630
2431
|
["i", "italic"]
|
|
1631
2432
|
]) {
|
|
1632
|
-
const value =
|
|
2433
|
+
const value = text3?.getAttribute(attribute2);
|
|
1633
2434
|
if (value !== null && value !== void 0) out[key] = value === "1" || value === "true";
|
|
1634
2435
|
}
|
|
1635
|
-
const typeface2 = first(
|
|
1636
|
-
const underline =
|
|
2436
|
+
const typeface2 = first(text3, "latin", NS.a)?.getAttribute("typeface");
|
|
2437
|
+
const underline = text3?.getAttribute("u");
|
|
1637
2438
|
if (underline) out.underline = underline !== "none";
|
|
1638
2439
|
if (typeface2) out.typeface = typeface2;
|
|
1639
|
-
const color = parseDrawingColorIn(first(
|
|
2440
|
+
const color = parseDrawingColorIn(first(text3, "solidFill", NS.a));
|
|
1640
2441
|
if (color) out.textColor = color;
|
|
1641
2442
|
const fill = parseDrawingFill(properties2);
|
|
1642
2443
|
const line2 = parseDrawingLine(first(properties2, "ln", NS.a));
|
|
1643
2444
|
if (fill) out.fill = fill;
|
|
1644
2445
|
if (line2) out.line = line2;
|
|
1645
|
-
const effects = first(
|
|
2446
|
+
const effects = first(text3, "effectLst", NS.a);
|
|
1646
2447
|
if (effects) out.textEffectsXml = buildXml(effects);
|
|
1647
2448
|
return out;
|
|
1648
2449
|
}
|
|
@@ -2158,7 +2959,7 @@ function rectGradientFocus(id) {
|
|
|
2158
2959
|
if (!direction) throw new RangeError(`Unknown rectangular gradient direction ${id}`);
|
|
2159
2960
|
return { l: direction.x, t: direction.y, r: 1 - direction.x, b: 1 - direction.y };
|
|
2160
2961
|
}
|
|
2161
|
-
function
|
|
2962
|
+
function hexToRgb2(color) {
|
|
2162
2963
|
const parsed = hexToRgbChannels(color);
|
|
2163
2964
|
if (parsed) return parsed;
|
|
2164
2965
|
const hex = color.replace("#", "");
|
|
@@ -2172,8 +2973,8 @@ function toHexChannel(value) {
|
|
|
2172
2973
|
return toHex(value).toLowerCase();
|
|
2173
2974
|
}
|
|
2174
2975
|
function lerpStops(a2, b, t) {
|
|
2175
|
-
const ca =
|
|
2176
|
-
const cb =
|
|
2976
|
+
const ca = hexToRgb2(a2.color);
|
|
2977
|
+
const cb = hexToRgb2(b.color);
|
|
2177
2978
|
const oa = a2.opacity ?? 1;
|
|
2178
2979
|
const ob = b.opacity ?? 1;
|
|
2179
2980
|
return {
|
|
@@ -2252,8 +3053,8 @@ function buildRectPathGradientSvg(stops, focalPoint, fillToRect, options) {
|
|
|
2252
3053
|
);
|
|
2253
3054
|
}
|
|
2254
3055
|
}
|
|
2255
|
-
const
|
|
2256
|
-
return `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" preserveAspectRatio="none">${
|
|
3056
|
+
const paint2 = masked ? `<defs><mask id="alpha" maskUnits="userSpaceOnUse" x="0" y="0" width="100" height="100" mask-type="luminance" color-interpolation="sRGB">${alphaRects.join("")}</mask></defs><g mask="url(#alpha)">${rects.join("")}</g>` : rects.join("");
|
|
3057
|
+
return `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" preserveAspectRatio="none">${paint2}</svg>`;
|
|
2257
3058
|
}
|
|
2258
3059
|
|
|
2259
3060
|
// chart/gradient-definition.ts
|
|
@@ -2305,16 +3106,16 @@ function buildChartGradientDef(id, fill, bounds) {
|
|
|
2305
3106
|
};
|
|
2306
3107
|
}
|
|
2307
3108
|
if (fill.type === "radial") {
|
|
2308
|
-
const
|
|
3109
|
+
const cx2 = fill.focalPoint?.x ?? 0.5;
|
|
2309
3110
|
const cy = fill.focalPoint?.y ?? 0.5;
|
|
2310
3111
|
const aspect = fill.path === "circle" && bounds && Number.isFinite(bounds.width) && Number.isFinite(bounds.height) && bounds.width > 0 && bounds.height > 0 ? bounds.height / bounds.width : 1;
|
|
2311
3112
|
return {
|
|
2312
3113
|
kind: "radialGradient",
|
|
2313
3114
|
id,
|
|
2314
|
-
cx,
|
|
3115
|
+
cx: cx2,
|
|
2315
3116
|
cy,
|
|
2316
3117
|
r: Math.max(
|
|
2317
|
-
...[0, 1].flatMap((x) => [0, 1].map((y) => Math.hypot(x -
|
|
3118
|
+
...[0, 1].flatMap((x) => [0, 1].map((y) => Math.hypot(x - cx2, (y - cy) * aspect)))
|
|
2318
3119
|
),
|
|
2319
3120
|
...aspect === 1 ? {} : { gradientTransform: `matrix(1 0 0 ${1 / aspect} 0 ${cy * (1 - 1 / aspect)})` },
|
|
2320
3121
|
stops
|
|
@@ -2407,14 +3208,43 @@ function writeChartLayoutFormatting(root, formatting) {
|
|
|
2407
3208
|
return changed;
|
|
2408
3209
|
}
|
|
2409
3210
|
|
|
3211
|
+
// chart/model-analysis.ts
|
|
3212
|
+
var KIND_OF_TYPE = {
|
|
3213
|
+
linear: "linear",
|
|
3214
|
+
exp: "exponential",
|
|
3215
|
+
log: "logarithmic",
|
|
3216
|
+
poly: "polynomial",
|
|
3217
|
+
power: "power",
|
|
3218
|
+
movingAvg: "movingAvg"
|
|
3219
|
+
};
|
|
3220
|
+
var TYPE_OF_KIND = {
|
|
3221
|
+
linear: "linear",
|
|
3222
|
+
exponential: "exp",
|
|
3223
|
+
logarithmic: "log",
|
|
3224
|
+
polynomial: "poly",
|
|
3225
|
+
power: "power",
|
|
3226
|
+
movingAvg: "movingAvg"
|
|
3227
|
+
};
|
|
3228
|
+
var chartTrendlineKind = (type) => type !== void 0 && Object.hasOwn(KIND_OF_TYPE, type) ? KIND_OF_TYPE[type] : void 0;
|
|
3229
|
+
var chartTrendlineType = (kind) => TYPE_OF_KIND[kind];
|
|
3230
|
+
var CHART_ERROR_BAR_DIRECTIONS = ["x", "y"];
|
|
3231
|
+
var CHART_ERROR_BAR_TYPES = ["both", "minus", "plus"];
|
|
3232
|
+
var CHART_ERROR_VALUE_TYPES = [
|
|
3233
|
+
"cust",
|
|
3234
|
+
"fixedVal",
|
|
3235
|
+
"percentage",
|
|
3236
|
+
"stdDev",
|
|
3237
|
+
"stdErr"
|
|
3238
|
+
];
|
|
3239
|
+
|
|
2410
3240
|
// chart/data-cache.ts
|
|
2411
3241
|
function chartCacheValues(cache) {
|
|
2412
3242
|
if (!cache) return [];
|
|
2413
3243
|
const numeric = cache.type === "number";
|
|
2414
3244
|
const out = [];
|
|
2415
3245
|
for (const point of cache.points) {
|
|
2416
|
-
const
|
|
2417
|
-
out[point.index ?? out.length] = numeric &&
|
|
3246
|
+
const text3 = point.value;
|
|
3247
|
+
out[point.index ?? out.length] = numeric && text3.trim() !== "" && Number.isFinite(Number(text3)) ? Number(text3) : text3;
|
|
2418
3248
|
}
|
|
2419
3249
|
const size = Math.max(cache.pointCount ?? 0, out.length);
|
|
2420
3250
|
for (let index = 0; index < size; index++) if (out[index] === void 0) out[index] = "";
|
|
@@ -2472,6 +3302,14 @@ function cNumber(context, parent, local) {
|
|
|
2472
3302
|
malformed(context, element, raw2);
|
|
2473
3303
|
return void 0;
|
|
2474
3304
|
}
|
|
3305
|
+
function cEnum(context, parent, local, allowed) {
|
|
3306
|
+
const element = cChild(parent, local);
|
|
3307
|
+
const raw2 = attribute(element, "val");
|
|
3308
|
+
if (!element || raw2 === void 0) return void 0;
|
|
3309
|
+
if (allowed.includes(raw2)) return raw2;
|
|
3310
|
+
malformed(context, element, raw2);
|
|
3311
|
+
return void 0;
|
|
3312
|
+
}
|
|
2475
3313
|
function reportUnmodelled(context, element, handled) {
|
|
2476
3314
|
for (const child2 of elements(element)) {
|
|
2477
3315
|
if (handled.has(child2.localName)) continue;
|
|
@@ -2592,20 +3430,20 @@ function parseDataSource(element) {
|
|
|
2592
3430
|
}
|
|
2593
3431
|
function parseChartText(context, tx, allowValue) {
|
|
2594
3432
|
if (!tx) return void 0;
|
|
2595
|
-
const
|
|
3433
|
+
const text3 = {};
|
|
2596
3434
|
const rich = chartTextBody(cChild(tx, "rich"));
|
|
2597
|
-
if (rich)
|
|
3435
|
+
if (rich) text3.rich = rich;
|
|
2598
3436
|
if (cChild(tx, "strRef")) {
|
|
2599
3437
|
const reference2 = parseDataSource(tx);
|
|
2600
|
-
if (reference2)
|
|
3438
|
+
if (reference2) text3.reference = reference2;
|
|
2601
3439
|
}
|
|
2602
3440
|
const value = allowValue ? cChild(tx, "v")?.textContent : void 0;
|
|
2603
|
-
if (value !== void 0 && value !== null)
|
|
2604
|
-
const cached = chartCacheValues(
|
|
2605
|
-
const flat =
|
|
2606
|
-
if (flat !== void 0)
|
|
3441
|
+
if (value !== void 0 && value !== null) text3.value = value;
|
|
3442
|
+
const cached = chartCacheValues(text3.reference?.cache)[0];
|
|
3443
|
+
const flat = text3.value ?? (rich ? rich.text : cached === void 0 ? void 0 : String(cached));
|
|
3444
|
+
if (flat !== void 0) text3.text = flat;
|
|
2607
3445
|
reportUnmodelled(context, tx, new Set(allowValue ? ["strRef", "v"] : ["rich", "strRef"]));
|
|
2608
|
-
return
|
|
3446
|
+
return text3;
|
|
2609
3447
|
}
|
|
2610
3448
|
var TITLE = /* @__PURE__ */ new Set(["tx", "layout", "overlay", "spPr", "txPr", "extLst"]);
|
|
2611
3449
|
function parseTitle(context, element) {
|
|
@@ -2772,6 +3610,105 @@ function readDisplayNaAsBlank(chartExtLst) {
|
|
|
2772
3610
|
return void 0;
|
|
2773
3611
|
}
|
|
2774
3612
|
|
|
3613
|
+
// chart/parse-analysis.ts
|
|
3614
|
+
var TRENDLINE_TYPES = [
|
|
3615
|
+
"exp",
|
|
3616
|
+
"linear",
|
|
3617
|
+
"log",
|
|
3618
|
+
"movingAvg",
|
|
3619
|
+
"poly",
|
|
3620
|
+
"power"
|
|
3621
|
+
];
|
|
3622
|
+
var LABEL2 = /* @__PURE__ */ new Set(["layout", "tx", "numFmt", "spPr", "txPr", "extLst"]);
|
|
3623
|
+
function parseTrendlineLabel(context, element) {
|
|
3624
|
+
if (!element) return void 0;
|
|
3625
|
+
reportUnmodelled(context, element, LABEL2);
|
|
3626
|
+
return assignDefined(
|
|
3627
|
+
{},
|
|
3628
|
+
{
|
|
3629
|
+
layout: manualLayout(element),
|
|
3630
|
+
tx: parseChartText(context, cChild(element, "tx"), false),
|
|
3631
|
+
numberFormat: numberFormat(element),
|
|
3632
|
+
spPr: shapeProperties(element),
|
|
3633
|
+
txPr: textProperties(element),
|
|
3634
|
+
extLst: extensionList(element)
|
|
3635
|
+
}
|
|
3636
|
+
);
|
|
3637
|
+
}
|
|
3638
|
+
var TRENDLINE = /* @__PURE__ */ new Set([
|
|
3639
|
+
"name",
|
|
3640
|
+
"spPr",
|
|
3641
|
+
"trendlineType",
|
|
3642
|
+
"order",
|
|
3643
|
+
"period",
|
|
3644
|
+
"forward",
|
|
3645
|
+
"backward",
|
|
3646
|
+
"intercept",
|
|
3647
|
+
"dispRSqr",
|
|
3648
|
+
"dispEq",
|
|
3649
|
+
"trendlineLbl",
|
|
3650
|
+
"extLst"
|
|
3651
|
+
]);
|
|
3652
|
+
function parseTrendline(context, element) {
|
|
3653
|
+
reportUnmodelled(context, element, TRENDLINE);
|
|
3654
|
+
const name = cChild(element, "name");
|
|
3655
|
+
return assignDefined(
|
|
3656
|
+
{},
|
|
3657
|
+
{
|
|
3658
|
+
name: name ? name.textContent ?? "" : void 0,
|
|
3659
|
+
spPr: shapeProperties(element),
|
|
3660
|
+
trendlineType: cEnum(context, element, "trendlineType", TRENDLINE_TYPES),
|
|
3661
|
+
order: cNumber(context, element, "order"),
|
|
3662
|
+
period: cNumber(context, element, "period"),
|
|
3663
|
+
forward: cNumber(context, element, "forward"),
|
|
3664
|
+
backward: cNumber(context, element, "backward"),
|
|
3665
|
+
intercept: cNumber(context, element, "intercept"),
|
|
3666
|
+
displayRSquared: cBool(context, element, "dispRSqr"),
|
|
3667
|
+
displayEquation: cBool(context, element, "dispEq"),
|
|
3668
|
+
label: parseTrendlineLabel(context, cChild(element, "trendlineLbl")),
|
|
3669
|
+
extLst: extensionList(element)
|
|
3670
|
+
}
|
|
3671
|
+
);
|
|
3672
|
+
}
|
|
3673
|
+
var ERROR_BARS = /* @__PURE__ */ new Set([
|
|
3674
|
+
"errDir",
|
|
3675
|
+
"errBarType",
|
|
3676
|
+
"errValType",
|
|
3677
|
+
"noEndCap",
|
|
3678
|
+
"plus",
|
|
3679
|
+
"minus",
|
|
3680
|
+
"val",
|
|
3681
|
+
"spPr",
|
|
3682
|
+
"extLst"
|
|
3683
|
+
]);
|
|
3684
|
+
function parseErrorBars(context, element) {
|
|
3685
|
+
reportUnmodelled(context, element, ERROR_BARS);
|
|
3686
|
+
return assignDefined(
|
|
3687
|
+
{},
|
|
3688
|
+
{
|
|
3689
|
+
direction: cEnum(context, element, "errDir", CHART_ERROR_BAR_DIRECTIONS),
|
|
3690
|
+
barType: cEnum(context, element, "errBarType", CHART_ERROR_BAR_TYPES),
|
|
3691
|
+
valueType: cEnum(context, element, "errValType", CHART_ERROR_VALUE_TYPES),
|
|
3692
|
+
noEndCap: cBool(context, element, "noEndCap"),
|
|
3693
|
+
plus: parseDataSource(cChild(element, "plus")),
|
|
3694
|
+
minus: parseDataSource(cChild(element, "minus")),
|
|
3695
|
+
value: cNumber(context, element, "val"),
|
|
3696
|
+
spPr: shapeProperties(element),
|
|
3697
|
+
extLst: extensionList(element)
|
|
3698
|
+
}
|
|
3699
|
+
);
|
|
3700
|
+
}
|
|
3701
|
+
function parseSeriesAnalysis(context, series) {
|
|
3702
|
+
const trendlines2 = children(series, "trendline", NS.c).map(
|
|
3703
|
+
(node) => parseTrendline(context, node)
|
|
3704
|
+
);
|
|
3705
|
+
const errorBars = children(series, "errBars", NS.c).map((node) => parseErrorBars(context, node));
|
|
3706
|
+
return {
|
|
3707
|
+
...trendlines2.length ? { trendlines: trendlines2 } : {},
|
|
3708
|
+
...errorBars.length ? { errorBars } : {}
|
|
3709
|
+
};
|
|
3710
|
+
}
|
|
3711
|
+
|
|
2775
3712
|
// chart/parse-series.ts
|
|
2776
3713
|
var MARKER = /* @__PURE__ */ new Set(["symbol", "size", "spPr", "extLst"]);
|
|
2777
3714
|
function parseMarker(context, element) {
|
|
@@ -2820,6 +3757,8 @@ var SERIES = /* @__PURE__ */ new Set([
|
|
|
2820
3757
|
"invertIfNegative",
|
|
2821
3758
|
"dPt",
|
|
2822
3759
|
"dLbls",
|
|
3760
|
+
"trendline",
|
|
3761
|
+
"errBars",
|
|
2823
3762
|
"cat",
|
|
2824
3763
|
"val",
|
|
2825
3764
|
"xVal",
|
|
@@ -2835,7 +3774,10 @@ var SERIES = /* @__PURE__ */ new Set([
|
|
|
2835
3774
|
function parseSeries(context, element) {
|
|
2836
3775
|
reportUnmodelled(context, element, SERIES);
|
|
2837
3776
|
return assignDefined(
|
|
2838
|
-
{
|
|
3777
|
+
{
|
|
3778
|
+
dataPoints: children(element, "dPt", NS.c).map((point) => parseDataPoint(context, point)),
|
|
3779
|
+
...parseSeriesAnalysis(context, element)
|
|
3780
|
+
},
|
|
2839
3781
|
{
|
|
2840
3782
|
index: cNumber(context, element, "idx"),
|
|
2841
3783
|
order: cNumber(context, element, "order"),
|
|
@@ -2918,7 +3860,7 @@ function parseGroup(context, element) {
|
|
|
2918
3860
|
const number = (local) => cNumber(context, element, local);
|
|
2919
3861
|
const flag = (local) => cBool(context, element, local);
|
|
2920
3862
|
const barDir = cVal(element, "barDir");
|
|
2921
|
-
const
|
|
3863
|
+
const present2 = (local) => cChild(element, local) ? true : void 0;
|
|
2922
3864
|
const linesShape = (local) => chartLines(element, local)?.spPr;
|
|
2923
3865
|
const bars2 = cChild(element, "upDownBars");
|
|
2924
3866
|
return assignDefined(
|
|
@@ -2944,10 +3886,10 @@ function parseGroup(context, element) {
|
|
|
2944
3886
|
shape: cVal(element, "shape"),
|
|
2945
3887
|
marker: flag("marker"),
|
|
2946
3888
|
smooth: flag("smooth"),
|
|
2947
|
-
dropLines:
|
|
2948
|
-
hiLowLines:
|
|
2949
|
-
upDownBars:
|
|
2950
|
-
seriesLines:
|
|
3889
|
+
dropLines: present2("dropLines"),
|
|
3890
|
+
hiLowLines: present2("hiLowLines"),
|
|
3891
|
+
upDownBars: present2("upDownBars"),
|
|
3892
|
+
seriesLines: present2("serLines"),
|
|
2951
3893
|
dropLinesSpPr: linesShape("dropLines"),
|
|
2952
3894
|
hiLowLinesSpPr: linesShape("hiLowLines"),
|
|
2953
3895
|
seriesLinesSpPr: linesShape("serLines"),
|
|
@@ -3279,9 +4221,9 @@ var escapeText = (value) => value.replace(INVALID_XML, "").replace(/&/g, "&"
|
|
|
3279
4221
|
var escapeAttribute = (value) => escapeText(value).replace(/"/g, """).replace(/\r/g, " ").replace(/\n/g, " ").replace(/\t/g, "	");
|
|
3280
4222
|
function chartNumber(value) {
|
|
3281
4223
|
if (!Number.isFinite(value)) throw new Error(`Chart number ${value} is not finite`);
|
|
3282
|
-
const
|
|
3283
|
-
const match = /^(-?)(\d+)(?:\.(\d+))?e([+-]\d+)$/i.exec(
|
|
3284
|
-
if (!match) return
|
|
4224
|
+
const text3 = String(value);
|
|
4225
|
+
const match = /^(-?)(\d+)(?:\.(\d+))?e([+-]\d+)$/i.exec(text3);
|
|
4226
|
+
if (!match) return text3;
|
|
3285
4227
|
const [, sign = "", whole = "", fraction = "", exponent = "0"] = match;
|
|
3286
4228
|
const digits = whole + fraction;
|
|
3287
4229
|
const point = whole.length + Number(exponent);
|
|
@@ -3290,8 +4232,8 @@ function chartNumber(value) {
|
|
|
3290
4232
|
}
|
|
3291
4233
|
function valXml(local, value) {
|
|
3292
4234
|
if (value === void 0) return "";
|
|
3293
|
-
const
|
|
3294
|
-
return `<c:${local} val="${
|
|
4235
|
+
const text3 = typeof value === "boolean" ? value ? "1" : "0" : typeof value === "number" ? chartNumber(value) : escapeAttribute(value);
|
|
4236
|
+
return `<c:${local} val="${text3}"/>`;
|
|
3295
4237
|
}
|
|
3296
4238
|
var elementXml = (local, content, attributes = "") => content ? `<c:${local}${attributes}>${content}</c:${local}>` : `<c:${local}${attributes}/>`;
|
|
3297
4239
|
var raw = (context, xml) => xml ? stripDeclarations(xml, context.bindings) : "";
|
|
@@ -3323,11 +4265,11 @@ function spacing(local, value) {
|
|
|
3323
4265
|
return `<a:${local}>${inner}</a:${local}>`;
|
|
3324
4266
|
}
|
|
3325
4267
|
function run(value) {
|
|
3326
|
-
const { text:
|
|
4268
|
+
const { text: text3, ...properties2 } = value;
|
|
3327
4269
|
const hasProperties = Object.keys(properties2).length > 0;
|
|
3328
|
-
if (
|
|
4270
|
+
if (text3 === "\n")
|
|
3329
4271
|
return hasProperties ? `<a:br>${runProperties("rPr", properties2)}</a:br>` : "<a:br/>";
|
|
3330
|
-
return `<a:r>${hasProperties ? runProperties("rPr", properties2) : ""}<a:t>${escapeText(
|
|
4272
|
+
return `<a:r>${hasProperties ? runProperties("rPr", properties2) : ""}<a:t>${escapeText(text3)}</a:t></a:r>`;
|
|
3331
4273
|
}
|
|
3332
4274
|
function paragraph(value) {
|
|
3333
4275
|
const align = value.align ? ` algn="${escapeAttribute(value.align)}"` : "";
|
|
@@ -3438,8 +4380,8 @@ function layoutXml(context, value) {
|
|
|
3438
4380
|
const manual = LAYOUT_FIELDS.map(([local, key]) => {
|
|
3439
4381
|
const value2 = layout[key];
|
|
3440
4382
|
if (value2 === void 0) return "";
|
|
3441
|
-
const
|
|
3442
|
-
return `<c:${local} val="${
|
|
4383
|
+
const text3 = typeof value2 === "number" ? chartNumber(value2) : value2;
|
|
4384
|
+
return `<c:${local} val="${text3}"/>`;
|
|
3443
4385
|
}).join("");
|
|
3444
4386
|
return elementXml("layout", manual ? `<c:manualLayout>${manual}</c:manualLayout>` : "");
|
|
3445
4387
|
}
|
|
@@ -3485,16 +4427,16 @@ function dataSourceInner(source) {
|
|
|
3485
4427
|
}
|
|
3486
4428
|
}
|
|
3487
4429
|
var dataSourceXml = (local, source) => source ? elementXml(local, dataSourceInner(source)) : "";
|
|
3488
|
-
function chartTextXml(context,
|
|
3489
|
-
if (!
|
|
3490
|
-
if (
|
|
4430
|
+
function chartTextXml(context, text3, seriesName2) {
|
|
4431
|
+
if (!text3) return "";
|
|
4432
|
+
if (text3.reference) return elementXml("tx", dataSourceInner(text3.reference));
|
|
3491
4433
|
if (seriesName2) {
|
|
3492
|
-
const value =
|
|
4434
|
+
const value = text3.value ?? text3.text;
|
|
3493
4435
|
return elementXml("tx", value === void 0 ? "" : textElement("v", value));
|
|
3494
4436
|
}
|
|
3495
|
-
if (
|
|
3496
|
-
if (
|
|
3497
|
-
const paragraphs =
|
|
4437
|
+
if (text3.rich) return elementXml("tx", textBodyXml(context, text3.rich, "rich"));
|
|
4438
|
+
if (text3.text === void 0) return "<c:tx/>";
|
|
4439
|
+
const paragraphs = text3.text.split("\n").map((line2) => ({ runs: [{ text: line2 }] }));
|
|
3498
4440
|
return `<c:tx><c:rich>${writeTextBody({ paragraphs })}</c:rich></c:tx>`;
|
|
3499
4441
|
}
|
|
3500
4442
|
function titleXml(context, title) {
|
|
@@ -3557,7 +4499,7 @@ var AXIS_ELEMENTS2 = {
|
|
|
3557
4499
|
date: "dateAx",
|
|
3558
4500
|
ser: "serAx"
|
|
3559
4501
|
};
|
|
3560
|
-
var gridlinesXml = (context, local,
|
|
4502
|
+
var gridlinesXml = (context, local, present2, shape) => present2 ? elementXml(local, shapePropertiesXml(context, shape)) : "";
|
|
3561
4503
|
function axisXml(context, axis) {
|
|
3562
4504
|
const { scaling } = axis;
|
|
3563
4505
|
return elementXml(
|
|
@@ -3569,6 +4511,28 @@ function axisXml(context, axis) {
|
|
|
3569
4511
|
);
|
|
3570
4512
|
}
|
|
3571
4513
|
|
|
4514
|
+
// chart/write-analysis.ts
|
|
4515
|
+
function trendlineLabelXml(context, label) {
|
|
4516
|
+
if (!label) return "";
|
|
4517
|
+
return elementXml(
|
|
4518
|
+
"trendlineLbl",
|
|
4519
|
+
layoutXml(context, label.layout) + chartTextXml(context, label.tx, false) + numberFormatXml(label.numberFormat) + shapePropertiesXml(context, label.spPr) + textBodyXml(context, label.txPr) + raw(context, label.extLst)
|
|
4520
|
+
);
|
|
4521
|
+
}
|
|
4522
|
+
function trendlineXml(context, trendline) {
|
|
4523
|
+
return elementXml(
|
|
4524
|
+
"trendline",
|
|
4525
|
+
(trendline.name === void 0 ? "" : `<c:name>${escapeText(trendline.name)}</c:name>`) + shapePropertiesXml(context, trendline.spPr) + valXml("trendlineType", trendline.trendlineType ?? "linear") + valXml("order", trendline.order) + valXml("period", trendline.period) + valXml("forward", trendline.forward) + valXml("backward", trendline.backward) + valXml("intercept", trendline.intercept) + valXml("dispRSqr", trendline.displayRSquared) + valXml("dispEq", trendline.displayEquation) + trendlineLabelXml(context, trendline.label) + raw(context, trendline.extLst)
|
|
4526
|
+
);
|
|
4527
|
+
}
|
|
4528
|
+
function errorBarsXml(context, bars2) {
|
|
4529
|
+
return elementXml(
|
|
4530
|
+
"errBars",
|
|
4531
|
+
valXml("errDir", bars2.direction) + valXml("errBarType", bars2.barType ?? "both") + valXml("errValType", bars2.valueType ?? "fixedVal") + valXml("noEndCap", bars2.noEndCap) + dataSourceXml("plus", bars2.plus) + dataSourceXml("minus", bars2.minus) + valXml("val", bars2.value) + shapePropertiesXml(context, bars2.spPr) + raw(context, bars2.extLst)
|
|
4532
|
+
);
|
|
4533
|
+
}
|
|
4534
|
+
var seriesAnalysisXml = (context, series) => (series.trendlines ?? []).map((trendline) => trendlineXml(context, trendline)).join("") + (series.errorBars ?? []).map((bars2) => errorBarsXml(context, bars2)).join("");
|
|
4535
|
+
|
|
3572
4536
|
// chart/write-series.ts
|
|
3573
4537
|
function markerXml(context, marker) {
|
|
3574
4538
|
if (!marker) return "";
|
|
@@ -3586,38 +4550,38 @@ function dataPointXml(context, point) {
|
|
|
3586
4550
|
function seriesXml(context, series, position) {
|
|
3587
4551
|
return elementXml(
|
|
3588
4552
|
"ser",
|
|
3589
|
-
valXml("idx", series.index ?? position) + valXml("order", series.order ?? position) + chartTextXml(context, series.tx, true) + shapePropertiesXml(context, series.spPr) + valXml("invertIfNegative", series.invertIfNegative) + markerXml(context, series.marker) + valXml("explosion", series.explosion) + series.dataPoints.map((point) => dataPointXml(context, point)).join("") + dataLabelsXml(context, series.dataLabels) + dataSourceXml("cat", series.categories) + dataSourceXml("val", series.values) + dataSourceXml("xVal", series.xValues) + dataSourceXml("yVal", series.yValues) + dataSourceXml("bubbleSize", series.bubbleSizes) + valXml("smooth", series.smooth) + valXml("shape", series.shape) + valXml("bubble3D", series.bubble3D) + raw(context, series.extLst)
|
|
4553
|
+
valXml("idx", series.index ?? position) + valXml("order", series.order ?? position) + chartTextXml(context, series.tx, true) + shapePropertiesXml(context, series.spPr) + valXml("invertIfNegative", series.invertIfNegative) + markerXml(context, series.marker) + valXml("explosion", series.explosion) + series.dataPoints.map((point) => dataPointXml(context, point)).join("") + dataLabelsXml(context, series.dataLabels) + seriesAnalysisXml(context, series) + dataSourceXml("cat", series.categories) + dataSourceXml("val", series.values) + dataSourceXml("xVal", series.xValues) + dataSourceXml("yVal", series.yValues) + dataSourceXml("bubbleSize", series.bubbleSizes) + valXml("smooth", series.smooth) + valXml("shape", series.shape) + valXml("bubble3D", series.bubble3D) + raw(context, series.extLst)
|
|
3590
4554
|
);
|
|
3591
4555
|
}
|
|
3592
4556
|
|
|
3593
4557
|
// chart/write-plot.ts
|
|
3594
|
-
var linesXml = (context, local,
|
|
4558
|
+
var linesXml = (context, local, present2, shape) => present2 ? elementXml(local, shapePropertiesXml(context, shape)) : "";
|
|
3595
4559
|
var barsXml = (context, local, bars2) => bars2 ? elementXml(local, shapePropertiesXml(context, bars2.spPr)) : "";
|
|
3596
|
-
function upDownBarsXml(context,
|
|
3597
|
-
if (!
|
|
4560
|
+
function upDownBarsXml(context, group2) {
|
|
4561
|
+
if (!group2.upDownBars) return "";
|
|
3598
4562
|
return elementXml(
|
|
3599
4563
|
"upDownBars",
|
|
3600
|
-
valXml("gapWidth",
|
|
4564
|
+
valXml("gapWidth", group2.upDownBarsGapWidth) + barsXml(context, "upBars", group2.upBars) + barsXml(context, "downBars", group2.downBars)
|
|
3601
4565
|
);
|
|
3602
4566
|
}
|
|
3603
|
-
function groupElement(
|
|
3604
|
-
if (Object.hasOwn(CHART_GROUP_ELEMENTS,
|
|
4567
|
+
function groupElement(group2) {
|
|
4568
|
+
if (Object.hasOwn(CHART_GROUP_ELEMENTS, group2.element)) return group2.element;
|
|
3605
4569
|
const match = Object.entries(CHART_GROUP_ELEMENTS).find(
|
|
3606
|
-
([, value]) => value.kind ===
|
|
4570
|
+
([, value]) => value.kind === group2.kind && value.is3D === group2.is3D
|
|
3607
4571
|
);
|
|
3608
|
-
if (!match) throw new Error(`No chart group element for ${
|
|
4572
|
+
if (!match) throw new Error(`No chart group element for ${group2.kind}`);
|
|
3609
4573
|
return match[0];
|
|
3610
4574
|
}
|
|
3611
|
-
function groupXml(context,
|
|
4575
|
+
function groupXml(context, group2) {
|
|
3612
4576
|
return elementXml(
|
|
3613
|
-
groupElement(
|
|
3614
|
-
valXml("ofPieType",
|
|
4577
|
+
groupElement(group2),
|
|
4578
|
+
valXml("ofPieType", group2.ofPieType) + valXml("scatterStyle", group2.scatterStyle) + valXml("radarStyle", group2.radarStyle) + valXml("wireframe", group2.wireframe) + valXml("barDir", group2.barDirection) + valXml("grouping", group2.grouping) + valXml("varyColors", group2.varyColors) + group2.series.map((series, position) => seriesXml(context, series, position)).join("") + dataLabelsXml(context, group2.dataLabels) + valXml("gapWidth", group2.gapWidth) + valXml("overlap", group2.overlap) + linesXml(context, "dropLines", group2.dropLines, group2.dropLinesSpPr) + linesXml(context, "hiLowLines", group2.hiLowLines, group2.hiLowLinesSpPr) + upDownBarsXml(context, group2) + valXml("marker", group2.marker) + valXml("smooth", group2.smooth) + valXml("gapDepth", group2.gapDepth) + valXml("shape", group2.shape) + valXml("firstSliceAng", group2.firstSliceAngle) + valXml("holeSize", group2.holeSize) + valXml("bubble3D", group2.bubble3D) + valXml("bubbleScale", group2.bubbleScale) + valXml("showNegBubbles", group2.showNegativeBubbles) + valXml("sizeRepresents", group2.sizeRepresents) + linesXml(context, "serLines", group2.seriesLines, group2.seriesLinesSpPr) + group2.axisIds.map((id) => valXml("axId", id)).join("") + raw(context, group2.extLst)
|
|
3615
4579
|
);
|
|
3616
4580
|
}
|
|
3617
4581
|
function plotAreaXml(context, plotArea) {
|
|
3618
4582
|
return elementXml(
|
|
3619
4583
|
"plotArea",
|
|
3620
|
-
layoutXml(context, plotArea.layout) + plotArea.groups.map((
|
|
4584
|
+
layoutXml(context, plotArea.layout) + plotArea.groups.map((group2) => groupXml(context, group2)).join("") + plotArea.axes.map((axis) => axisXml(context, axis)).join("") + dataTableXml(context, plotArea.dataTable) + shapePropertiesXml(context, plotArea.spPr) + raw(context, plotArea.extLst)
|
|
3621
4585
|
);
|
|
3622
4586
|
}
|
|
3623
4587
|
|
|
@@ -3673,6 +4637,46 @@ function writeChartSpace(space, options = {}) {
|
|
|
3673
4637
|
return `${DECLARATION2}${breakAfter}<c:chartSpace${declarations}>${body}</c:chartSpace>`;
|
|
3674
4638
|
}
|
|
3675
4639
|
|
|
4640
|
+
// chart/render/summary-analysis.ts
|
|
4641
|
+
function summaryTrendline(source) {
|
|
4642
|
+
const kind = chartTrendlineKind(source.trendlineType);
|
|
4643
|
+
if (!kind) return void 0;
|
|
4644
|
+
const out = { kind };
|
|
4645
|
+
if (source.order !== void 0) out.order = source.order;
|
|
4646
|
+
if (source.period !== void 0) out.period = source.period;
|
|
4647
|
+
if (source.forward !== void 0) out.forward = source.forward;
|
|
4648
|
+
if (source.backward !== void 0) out.backward = source.backward;
|
|
4649
|
+
if (source.intercept !== void 0) out.intercept = source.intercept;
|
|
4650
|
+
if (source.name !== void 0) out.name = source.name;
|
|
4651
|
+
if (source.spPr?.line) out.line = source.spPr.line;
|
|
4652
|
+
return out;
|
|
4653
|
+
}
|
|
4654
|
+
var amounts = (source) => chartSourceValues(source).map((value) => typeof value === "number" ? value : 0);
|
|
4655
|
+
function summaryErrorBars(source) {
|
|
4656
|
+
if (!source.valueType) return void 0;
|
|
4657
|
+
const out = {
|
|
4658
|
+
direction: source.direction ?? "y",
|
|
4659
|
+
barType: source.barType ?? "both",
|
|
4660
|
+
valueType: source.valueType
|
|
4661
|
+
};
|
|
4662
|
+
if (source.value !== void 0) out.value = source.value;
|
|
4663
|
+
if (source.valueType === "cust") {
|
|
4664
|
+
out.customPlus = amounts(source.plus);
|
|
4665
|
+
out.customMinus = amounts(source.minus);
|
|
4666
|
+
}
|
|
4667
|
+
if (source.noEndCap !== void 0) out.noEndCap = source.noEndCap;
|
|
4668
|
+
if (source.spPr?.line) out.line = source.spPr.line;
|
|
4669
|
+
return out;
|
|
4670
|
+
}
|
|
4671
|
+
function summaryAnalysis(series) {
|
|
4672
|
+
const trendlines2 = (series.trendlines ?? []).map(summaryTrendline).filter((entry3) => entry3 !== void 0);
|
|
4673
|
+
const errorBars = (series.errorBars ?? []).map(summaryErrorBars).filter((entry3) => entry3 !== void 0);
|
|
4674
|
+
return {
|
|
4675
|
+
...trendlines2.length ? { trendlines: trendlines2 } : {},
|
|
4676
|
+
...errorBars.length ? { errorBars } : {}
|
|
4677
|
+
};
|
|
4678
|
+
}
|
|
4679
|
+
|
|
3676
4680
|
// chart/render/summary-from-space.ts
|
|
3677
4681
|
var solidColor = (fill) => fill?.kind === "solid" ? fill.color : void 0;
|
|
3678
4682
|
var isSolidFill = (fill) => fill?.kind === "solid" || fill?.kind === "unsupported" && fill.element === "solidFill";
|
|
@@ -3693,12 +4697,15 @@ var GROUPINGS = /* @__PURE__ */ new Set(["clustered", "stacked", "percentStacked
|
|
|
3693
4697
|
function chartSummarySeries(source, chartType) {
|
|
3694
4698
|
const categories = source.categories ?? source.xValues;
|
|
3695
4699
|
const values = source.values ?? source.yValues;
|
|
4700
|
+
const numeric = (v) => typeof v === "number" ? v : v === "" ? null : Number.isFinite(Number(v)) ? Number(v) : null;
|
|
3696
4701
|
const out = {
|
|
3697
4702
|
categories: chartSourceValues(categories),
|
|
3698
|
-
values: chartSourceValues(values).map(
|
|
3699
|
-
(v) => typeof v === "number" ? v : v === "" ? null : Number.isFinite(Number(v)) ? Number(v) : null
|
|
3700
|
-
)
|
|
4703
|
+
values: chartSourceValues(values).map(numeric)
|
|
3701
4704
|
};
|
|
4705
|
+
if (source.bubbleSizes) {
|
|
4706
|
+
out.bubbleSizes = chartSourceValues(source.bubbleSizes).map(numeric);
|
|
4707
|
+
if (source.bubbleSizes.formula) out.bubbleSizesRef = source.bubbleSizes.formula;
|
|
4708
|
+
}
|
|
3702
4709
|
if (source.tx?.text !== void 0) out.name = source.tx.text;
|
|
3703
4710
|
const nameRef = source.tx?.reference?.formula;
|
|
3704
4711
|
if (nameRef) out.nameRef = nameRef;
|
|
@@ -3723,50 +4730,446 @@ function chartSummarySeries(source, chartType) {
|
|
|
3723
4730
|
}
|
|
3724
4731
|
if (Object.keys(points).length) out.pointColors = points;
|
|
3725
4732
|
if (Object.keys(pointFills).length) out.pointFills = pointFills;
|
|
4733
|
+
Object.assign(out, summaryAnalysis(source));
|
|
4734
|
+
return out;
|
|
4735
|
+
}
|
|
4736
|
+
function valueAxisId(chartSpace, axisIds) {
|
|
4737
|
+
return axisIds.find(
|
|
4738
|
+
(id) => chartSpace.plotArea.axes.some((a2) => a2.id === id && a2.kind === "val")
|
|
4739
|
+
);
|
|
4740
|
+
}
|
|
4741
|
+
function stockStyle(group2) {
|
|
4742
|
+
return {
|
|
4743
|
+
...group2.hiLowLinesSpPr ? { hiLowLines: group2.hiLowLinesSpPr } : {},
|
|
4744
|
+
...group2.upBars?.spPr ? { upBars: group2.upBars.spPr } : {},
|
|
4745
|
+
...group2.downBars?.spPr ? { downBars: group2.downBars.spPr } : {},
|
|
4746
|
+
...group2.upDownBarsGapWidth === void 0 ? {} : { gapWidth: group2.upDownBarsGapWidth }
|
|
4747
|
+
};
|
|
4748
|
+
}
|
|
4749
|
+
function extraGroups(chartSpace, firstType) {
|
|
4750
|
+
const [first2, ...rest] = chartSpace.plotArea.groups;
|
|
4751
|
+
if (!first2 || !["column", "line", "area"].includes(firstType)) return [];
|
|
4752
|
+
const primary = valueAxisId(chartSpace, first2.axisIds);
|
|
4753
|
+
const out = [];
|
|
4754
|
+
for (const group2 of rest) {
|
|
4755
|
+
const stockOverColumns = group2.kind === "stock" && firstType === "column";
|
|
4756
|
+
if (group2.is3D || !(["bar", "line", "area"].includes(group2.kind) || stockOverColumns)) continue;
|
|
4757
|
+
const type = group2.kind === "bar" ? "column" : group2.kind;
|
|
4758
|
+
const entry3 = {
|
|
4759
|
+
chartType: type,
|
|
4760
|
+
series: group2.series.map((source) => chartSummarySeries(source, type)),
|
|
4761
|
+
secondary: valueAxisId(chartSpace, group2.axisIds) !== primary
|
|
4762
|
+
};
|
|
4763
|
+
if (group2.grouping && GROUPINGS.has(group2.grouping))
|
|
4764
|
+
entry3.grouping = group2.grouping;
|
|
4765
|
+
if (type === "stock") entry3.stock = stockStyle(group2);
|
|
4766
|
+
if (type === "column") {
|
|
4767
|
+
if (group2.gapWidth !== void 0) entry3.barGapWidth = group2.gapWidth;
|
|
4768
|
+
if (group2.overlap !== void 0) entry3.barOverlap = group2.overlap;
|
|
4769
|
+
}
|
|
4770
|
+
if (entry3.series.length) out.push(entry3);
|
|
4771
|
+
}
|
|
4772
|
+
return out;
|
|
4773
|
+
}
|
|
4774
|
+
function chartSummaryFromSpace(chartSpace, extras = {}) {
|
|
4775
|
+
const group2 = chartSpace.plotArea.groups[0];
|
|
4776
|
+
let chartType = group2 ? GROUP_TYPES[group2.kind] : "column";
|
|
4777
|
+
if (chartType === "bar" && group2?.barDirection !== "bar") chartType = "column";
|
|
4778
|
+
const series = (group2?.series ?? []).map((source) => chartSummarySeries(source, chartType));
|
|
4779
|
+
const summary = {
|
|
4780
|
+
chartType,
|
|
4781
|
+
series,
|
|
4782
|
+
showLegend: chartSpace.legend !== void 0
|
|
4783
|
+
};
|
|
4784
|
+
const combined = extraGroups(chartSpace, chartType);
|
|
4785
|
+
if (combined.length) summary.extraGroups = combined;
|
|
4786
|
+
if (chartType === "stock" && group2) summary.stock = stockStyle(group2);
|
|
4787
|
+
if (chartType === "bubble" && group2) {
|
|
4788
|
+
const sizeRepresents = group2.sizeRepresents === "w" ? "w" : "area";
|
|
4789
|
+
summary.bubble = {
|
|
4790
|
+
sizeRepresents,
|
|
4791
|
+
...group2.bubbleScale === void 0 ? {} : { bubbleScale: group2.bubbleScale },
|
|
4792
|
+
showNegativeBubbles: group2.showNegativeBubbles === true
|
|
4793
|
+
};
|
|
4794
|
+
}
|
|
4795
|
+
const grouping = group2?.grouping;
|
|
4796
|
+
if (grouping && GROUPINGS.has(grouping))
|
|
4797
|
+
summary.grouping = grouping;
|
|
4798
|
+
if (chartType === "bar" || chartType === "column") {
|
|
4799
|
+
for (const [value, field, fallback, min, max] of [
|
|
4800
|
+
[group2?.gapWidth, "barGapWidth", 150, 0, 500],
|
|
4801
|
+
[group2?.overlap, "barOverlap", 0, -100, 100]
|
|
4802
|
+
]) {
|
|
4803
|
+
const resolved = value ?? fallback;
|
|
4804
|
+
if (Number.isInteger(resolved) && resolved >= min && resolved <= max)
|
|
4805
|
+
summary[field] = resolved;
|
|
4806
|
+
}
|
|
4807
|
+
}
|
|
4808
|
+
if (chartSpace.title && chartSpace.autoTitleDeleted !== true) {
|
|
4809
|
+
const title = chartSpace.title.text;
|
|
4810
|
+
if (title !== void 0) summary.title = title;
|
|
4811
|
+
else if (series.length === 1 && series[0]?.name) summary.title = series[0].name;
|
|
4812
|
+
}
|
|
4813
|
+
const legendPos = chartSpace.legend?.position;
|
|
4814
|
+
if (legendPos && ["r", "l", "t", "b", "tr"].includes(legendPos))
|
|
4815
|
+
summary.legendPosition = legendPos;
|
|
4816
|
+
if (extras.formatting) summary.formatting = extras.formatting;
|
|
4817
|
+
if (extras.colorPalette !== void 0) summary.colorPalette = extras.colorPalette;
|
|
4818
|
+
if (extras.styleDefinition) summary.styleDefinition = extras.styleDefinition;
|
|
4819
|
+
return summary;
|
|
4820
|
+
}
|
|
4821
|
+
|
|
4822
|
+
// chart/render/summary-from-chartex.ts
|
|
4823
|
+
var cx = (parent, local) => first(parent, local, NS.cx);
|
|
4824
|
+
var text = (element) => (element?.textContent ?? "").trim();
|
|
4825
|
+
function scalar(parent, local) {
|
|
4826
|
+
const element = cx(parent, local);
|
|
4827
|
+
if (!element) return void 0;
|
|
4828
|
+
return element.hasAttribute("val") ? element.getAttribute("val") ?? "" : text(element);
|
|
4829
|
+
}
|
|
4830
|
+
function seriesData(root, series) {
|
|
4831
|
+
const inline = cx(series, "data");
|
|
4832
|
+
if (inline) return inline;
|
|
4833
|
+
const id = cx(series, "dataId")?.getAttribute("val");
|
|
4834
|
+
const shared = children(cx(root, "chartData") ?? root, "data", NS.cx);
|
|
4835
|
+
return id === null || id === void 0 ? shared[0] : shared.find((d) => d.getAttribute("id") === id);
|
|
4836
|
+
}
|
|
4837
|
+
function dimension(data, kind, type) {
|
|
4838
|
+
const all = data ? children(data, kind, NS.cx) : [];
|
|
4839
|
+
const element = all.find((d) => (d.getAttribute("type") ?? "") === type) ?? void 0;
|
|
4840
|
+
if (!element) return void 0;
|
|
4841
|
+
const out = { points: [] };
|
|
4842
|
+
const formula = text(cx(element, "f"));
|
|
4843
|
+
if (formula) out.formula = formula;
|
|
4844
|
+
const level = cx(element, "lvl");
|
|
4845
|
+
const count = Number(level?.getAttribute("ptCount") ?? 0);
|
|
4846
|
+
for (const point of level ? children(level, "pt", NS.cx) : []) {
|
|
4847
|
+
const index = Number(point.getAttribute("idx") ?? out.points.length);
|
|
4848
|
+
if (Number.isInteger(index) && index >= 0) out.points[index] = text(point);
|
|
4849
|
+
}
|
|
4850
|
+
for (let i = 0; i < Math.max(count, out.points.length); i++) out.points[i] ??= "";
|
|
4851
|
+
return out;
|
|
4852
|
+
}
|
|
4853
|
+
function categoryLevels(data) {
|
|
4854
|
+
const element = data ? children(data, "strDim", NS.cx).find((d) => (d.getAttribute("type") ?? "") === "cat") : void 0;
|
|
4855
|
+
return (element ? children(element, "lvl", NS.cx) : []).map((level) => {
|
|
4856
|
+
const points = [];
|
|
4857
|
+
const count = Number(level.getAttribute("ptCount") ?? 0);
|
|
4858
|
+
for (const point of children(level, "pt", NS.cx)) {
|
|
4859
|
+
const index = Number(point.getAttribute("idx") ?? points.length);
|
|
4860
|
+
if (Number.isInteger(index) && index >= 0) points[index] = text(point);
|
|
4861
|
+
}
|
|
4862
|
+
for (let i = 0; i < Math.max(count, points.length); i++) points[i] ??= "";
|
|
4863
|
+
return points;
|
|
4864
|
+
});
|
|
4865
|
+
}
|
|
4866
|
+
function titleOf(chart) {
|
|
4867
|
+
const tx = cx(cx(chart, "title"), "tx");
|
|
4868
|
+
const data = text(cx(cx(tx, "txData"), "v"));
|
|
4869
|
+
if (data) return data;
|
|
4870
|
+
const rich = cx(tx, "rich");
|
|
4871
|
+
if (!rich) return void 0;
|
|
4872
|
+
const runs = Array.from(rich.getElementsByTagNameNS(NS.a, "t")).map((t) => t.textContent ?? "");
|
|
4873
|
+
return runs.join("") || void 0;
|
|
4874
|
+
}
|
|
4875
|
+
function seriesFill(series) {
|
|
4876
|
+
const fill = parseDrawingFill(cx(series, "spPr"));
|
|
4877
|
+
const color = fill?.kind === "solid" ? fill.color : void 0;
|
|
4878
|
+
return color ? { drawingColor: color } : {};
|
|
4879
|
+
}
|
|
4880
|
+
function numberOf(value) {
|
|
4881
|
+
const parsed = Number.parseFloat(value ?? "");
|
|
4882
|
+
return Number.isFinite(parsed) ? parsed : void 0;
|
|
4883
|
+
}
|
|
4884
|
+
function histogramOptions(layoutPr) {
|
|
4885
|
+
const binning = cx(layoutPr, "binning");
|
|
4886
|
+
const out = {};
|
|
4887
|
+
const size = numberOf(scalar(binning, "binSize"));
|
|
4888
|
+
const count = numberOf(scalar(binning, "binCount"));
|
|
4889
|
+
if (size !== void 0) out.binSize = size;
|
|
4890
|
+
if (count !== void 0 && count >= 0) out.binCount = Math.trunc(count);
|
|
4891
|
+
const closed = binning?.getAttribute("intervalClosed");
|
|
4892
|
+
if (closed === "l" || closed === "r") out.intervalClosed = closed;
|
|
4893
|
+
for (const key of ["underflow", "overflow"]) {
|
|
4894
|
+
const raw2 = binning?.getAttribute(key);
|
|
4895
|
+
if (raw2 === "auto") out[key] = "auto";
|
|
4896
|
+
else if (raw2 !== null && raw2 !== void 0 && numberOf(raw2) !== void 0)
|
|
4897
|
+
out[key] = numberOf(raw2);
|
|
4898
|
+
}
|
|
4899
|
+
if (cx(layoutPr, "aggregation")) out.aggregateByCategory = true;
|
|
3726
4900
|
return out;
|
|
3727
4901
|
}
|
|
3728
|
-
|
|
3729
|
-
|
|
3730
|
-
|
|
3731
|
-
if (
|
|
3732
|
-
const
|
|
3733
|
-
const
|
|
3734
|
-
|
|
3735
|
-
|
|
3736
|
-
|
|
3737
|
-
|
|
3738
|
-
|
|
3739
|
-
|
|
3740
|
-
|
|
3741
|
-
|
|
3742
|
-
|
|
3743
|
-
|
|
3744
|
-
|
|
3745
|
-
|
|
3746
|
-
|
|
3747
|
-
|
|
3748
|
-
|
|
3749
|
-
|
|
4902
|
+
var LEGEND_POSITIONS = ["r", "l", "t", "b", "tr"];
|
|
4903
|
+
function chartExSummary(source) {
|
|
4904
|
+
const root = typeof source === "string" ? parseXml(source, { label: "Chart part" }).documentElement : source;
|
|
4905
|
+
if (root.localName !== "chartSpace" || root.namespaceURI !== NS.cx) return void 0;
|
|
4906
|
+
const chart = cx(root, "chart");
|
|
4907
|
+
const region = cx(cx(chart, "plotArea"), "plotAreaRegion");
|
|
4908
|
+
const all = region ? children(region, "series", NS.cx) : [];
|
|
4909
|
+
const primary = all.find((s) => s.getAttribute("layoutId") !== "paretoLine") ?? all[0];
|
|
4910
|
+
const layoutId = primary?.getAttribute("layoutId") ?? "";
|
|
4911
|
+
const chartType = layoutId === "waterfall" ? "waterfall" : layoutId === "clusteredColumn" ? "histogram" : layoutId === "treemap" || layoutId === "sunburst" ? layoutId : void 0;
|
|
4912
|
+
if (!primary || !chartType) return { layoutId };
|
|
4913
|
+
const data = seriesData(root, primary);
|
|
4914
|
+
const categories = dimension(data, "strDim", "cat");
|
|
4915
|
+
const values = dimension(
|
|
4916
|
+
data,
|
|
4917
|
+
"numDim",
|
|
4918
|
+
chartType === "treemap" || chartType === "sunburst" ? "size" : "val"
|
|
4919
|
+
);
|
|
4920
|
+
const txData = cx(cx(primary, "tx"), "txData");
|
|
4921
|
+
const series = {
|
|
4922
|
+
categories: categories?.points ?? [],
|
|
4923
|
+
values: (values?.points ?? []).map(
|
|
4924
|
+
(p) => p !== "" && Number.isFinite(Number(p)) ? Number(p) : null
|
|
4925
|
+
),
|
|
4926
|
+
...seriesFill(primary)
|
|
4927
|
+
};
|
|
4928
|
+
const name = text(cx(txData, "v"));
|
|
4929
|
+
if (name) series.name = name;
|
|
4930
|
+
const nameRef = text(cx(txData, "f"));
|
|
4931
|
+
if (nameRef) series.nameRef = nameRef;
|
|
4932
|
+
if (categories?.formula) series.categoriesRef = categories.formula;
|
|
4933
|
+
if (values?.formula) series.valuesRef = values.formula;
|
|
4934
|
+
const layoutPr = cx(primary, "layoutPr");
|
|
4935
|
+
const legend = cx(chart, "legend");
|
|
4936
|
+
const summary = { chartType, series: [series], showLegend: legend !== void 0 };
|
|
4937
|
+
summary.formatting = {
|
|
4938
|
+
builtInStyle: 2,
|
|
4939
|
+
sourceXml: "",
|
|
4940
|
+
entries: {
|
|
4941
|
+
title: {
|
|
4942
|
+
fontSize: 14,
|
|
4943
|
+
bold: false,
|
|
4944
|
+
textColor: {
|
|
4945
|
+
kind: "scheme",
|
|
4946
|
+
value: "tx1",
|
|
4947
|
+
transforms: [
|
|
4948
|
+
{ name: "lumMod", value: "65000" },
|
|
4949
|
+
{ name: "lumOff", value: "35000" }
|
|
4950
|
+
]
|
|
4951
|
+
},
|
|
4952
|
+
sourceXml: ""
|
|
4953
|
+
}
|
|
4954
|
+
}
|
|
4955
|
+
};
|
|
4956
|
+
const title = titleOf(chart);
|
|
4957
|
+
if (title) summary.title = title;
|
|
4958
|
+
const position = legend?.getAttribute("pos");
|
|
4959
|
+
if (position && LEGEND_POSITIONS.includes(position))
|
|
4960
|
+
summary.legendPosition = position;
|
|
4961
|
+
if (chartType === "waterfall") {
|
|
4962
|
+
const subtotals = cx(layoutPr, "subtotals");
|
|
4963
|
+
const connectors = cx(layoutPr, "visibility")?.getAttribute("connectorLines");
|
|
4964
|
+
summary.waterfall = {
|
|
4965
|
+
...subtotals ? {
|
|
4966
|
+
subtotalIndices: children(subtotals, "idx", NS.cx).map((idx) => Number.parseInt(idx.getAttribute("val") ?? "", 10)).filter((idx) => Number.isInteger(idx) && idx >= 0)
|
|
4967
|
+
} : {},
|
|
4968
|
+
...connectors === "0" || connectors === "false" ? { connectorLines: false } : {}
|
|
4969
|
+
};
|
|
4970
|
+
} else if (chartType === "treemap" || chartType === "sunburst") {
|
|
4971
|
+
const layout = cx(layoutPr, "parentLabelLayout")?.getAttribute("val");
|
|
4972
|
+
summary.hierarchy = {
|
|
4973
|
+
levels: categoryLevels(data),
|
|
4974
|
+
dataLabels: cx(primary, "dataLabels") !== void 0,
|
|
4975
|
+
...layout === "none" || layout === "banner" || layout === "overlapping" ? { parentLabelLayout: layout } : {}
|
|
4976
|
+
};
|
|
4977
|
+
} else summary.histogram = histogramOptions(layoutPr);
|
|
4978
|
+
return { layoutId, summary };
|
|
4979
|
+
}
|
|
4980
|
+
|
|
4981
|
+
// drawingml/theme-color.ts
|
|
4982
|
+
function themeSlotHex(color) {
|
|
4983
|
+
if (!color) return void 0;
|
|
4984
|
+
const value = color.kind === "srgb" ? color.value : color.kind === "system" ? color.fallback : void 0;
|
|
4985
|
+
return value ? value.toUpperCase() : void 0;
|
|
4986
|
+
}
|
|
4987
|
+
|
|
4988
|
+
// chart/render/chart-svg-util.ts
|
|
4989
|
+
var TEXT_COLOR = "#595959";
|
|
4990
|
+
var GRID_COLOR = "#D9D9D9";
|
|
4991
|
+
var AXIS_COLOR = "#BFBFBF";
|
|
4992
|
+
var FONT_SIZE = 10;
|
|
4993
|
+
function esc(text3) {
|
|
4994
|
+
return text3.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
4995
|
+
}
|
|
4996
|
+
var n = (value) => String(Math.round(value * 100) / 100);
|
|
4997
|
+
var textWidth = (text3, size = FONT_SIZE) => text3.length * size * 0.55;
|
|
4998
|
+
function text2(x, y, content, attrs = {}) {
|
|
4999
|
+
const parts = [`x="${n(x)}"`, `y="${n(y)}"`];
|
|
5000
|
+
parts.push(`font-size="${attrs.size ?? FONT_SIZE}"`);
|
|
5001
|
+
parts.push(`fill="${esc(attrs.fill ?? TEXT_COLOR)}"`);
|
|
5002
|
+
if (attrs.anchor && attrs.anchor !== "start") parts.push(`text-anchor="${attrs.anchor}"`);
|
|
5003
|
+
if (attrs.weight) parts.push(`font-weight="${attrs.weight}"`);
|
|
5004
|
+
if (attrs.baseline) parts.push(`dominant-baseline="${attrs.baseline}"`);
|
|
5005
|
+
if (attrs.family) parts.push(`font-family="${esc(attrs.family)}"`);
|
|
5006
|
+
if (attrs.filter) parts.push(`filter="${esc(attrs.filter)}"`);
|
|
5007
|
+
if (attrs.italic !== void 0) parts.push(`font-style="${attrs.italic ? "italic" : "normal"}"`);
|
|
5008
|
+
if (attrs.underline !== void 0)
|
|
5009
|
+
parts.push(`text-decoration="${attrs.underline ? "underline" : "none"}"`);
|
|
5010
|
+
return `<text ${parts.join(" ")}>${esc(content)}</text>`;
|
|
5011
|
+
}
|
|
5012
|
+
var line = (x1, y1, x2, y2, stroke, width = 1) => `<line x1="${n(x1)}" y1="${n(y1)}" x2="${n(x2)}" y2="${n(y2)}" stroke="${stroke}" stroke-width="${width}"/>`;
|
|
5013
|
+
var rect = (x, y, w, h, fill, filter) => `<rect x="${n(x)}" y="${n(y)}" width="${n(Math.max(0, w))}" height="${n(Math.max(0, h))}" fill="${fill}"${filter ? ` filter="${esc(filter)}"` : ""}/>`;
|
|
5014
|
+
function fit(content, maxWidth, size = FONT_SIZE) {
|
|
5015
|
+
if (textWidth(content, size) <= maxWidth) return content;
|
|
5016
|
+
const chars = Math.max(1, Math.floor(maxWidth / (size * 0.55)) - 1);
|
|
5017
|
+
return `${content.slice(0, chars)}\u2026`;
|
|
5018
|
+
}
|
|
5019
|
+
|
|
5020
|
+
// chart/render/chart-spacing.ts
|
|
5021
|
+
function chartBarSpacing(chart) {
|
|
5022
|
+
const stacked = chart.grouping === "stacked" || chart.grouping === "percentStacked";
|
|
5023
|
+
return {
|
|
5024
|
+
barGapWidth: chart.barGapWidth ?? DEFAULT_BAR_GAP_WIDTH,
|
|
5025
|
+
barOverlap: chart.barOverlap ?? (stacked ? 100 : 0)
|
|
5026
|
+
};
|
|
5027
|
+
}
|
|
5028
|
+
|
|
5029
|
+
// chart/render/chart-svg-bars.ts
|
|
5030
|
+
function barLayout(model, frame) {
|
|
5031
|
+
const count = Math.max(1, model.series.length);
|
|
5032
|
+
const geometry = clusteredBarGeometry(frame.bandSize, count, chartBarSpacing(model));
|
|
5033
|
+
const barSize = geometry.singleBarWidth;
|
|
5034
|
+
const offset = (si) => model.horizontal ? geometry.clusterWidth / 2 - barSize - si * geometry.step : -geometry.clusterWidth / 2 + si * geometry.step;
|
|
5035
|
+
return { barSize, offset };
|
|
5036
|
+
}
|
|
5037
|
+
function bars(model, frame, out, values) {
|
|
5038
|
+
const stacked = model.grouping === "stacked" || model.grouping === "percentStacked";
|
|
5039
|
+
const { barSize, offset: barOffset } = barLayout(model, frame);
|
|
5040
|
+
const base = frame.value(0);
|
|
5041
|
+
const pos = new Array(model.categories.length).fill(0);
|
|
5042
|
+
const neg = new Array(model.categories.length).fill(0);
|
|
5043
|
+
model.series.forEach((s, si) => {
|
|
5044
|
+
values[si]?.forEach((v, i) => {
|
|
5045
|
+
if (v === null || i >= model.categories.length) return;
|
|
5046
|
+
let from = 0;
|
|
5047
|
+
let to = v;
|
|
5048
|
+
if (stacked) {
|
|
5049
|
+
const acc = v >= 0 ? pos : neg;
|
|
5050
|
+
from = acc[i] ?? 0;
|
|
5051
|
+
to = from + v;
|
|
5052
|
+
acc[i] = to;
|
|
5053
|
+
}
|
|
5054
|
+
const a2 = stacked ? frame.value(from) : base;
|
|
5055
|
+
const b = frame.value(to);
|
|
5056
|
+
const offset = barOffset(si);
|
|
5057
|
+
const center = frame.band(i);
|
|
5058
|
+
const width = model.horizontal ? Math.abs(b - a2) : barSize;
|
|
5059
|
+
const height = model.horizontal ? barSize : Math.abs(b - a2);
|
|
5060
|
+
let color = s.pointColors?.[i] ?? s.color;
|
|
5061
|
+
const gradient = s.pointGradients?.[i] ?? (s.pointColors?.[i] === void 0 ? s.gradient : void 0);
|
|
5062
|
+
if (gradient && (gradient.path === "circle" || gradient.path === "shape")) {
|
|
5063
|
+
const baseId = color.match(/^url\(#(.+)\)$/)?.[1];
|
|
5064
|
+
if (baseId) {
|
|
5065
|
+
const id = baseId.replace(/(-s\d+(?:-p\d+)?)$/, `-mark${i}$1`);
|
|
5066
|
+
const def = buildChartGradientDef(id, gradient, {
|
|
5067
|
+
width: Number(n(width)),
|
|
5068
|
+
height: Number(n(height)),
|
|
5069
|
+
shape: "rect"
|
|
5070
|
+
});
|
|
5071
|
+
out.push(`<defs>${chartGradientMarkup(def)}</defs>`);
|
|
5072
|
+
color = `url(#${id})`;
|
|
5073
|
+
}
|
|
5074
|
+
}
|
|
5075
|
+
out.push(`<g data-chart-series="${si}" data-chart-point="${i}">`);
|
|
5076
|
+
if (model.horizontal)
|
|
5077
|
+
out.push(
|
|
5078
|
+
rect(Math.min(a2, b), center + offset, Math.abs(b - a2), barSize, color, s.shadowFilter)
|
|
5079
|
+
);
|
|
5080
|
+
else
|
|
5081
|
+
out.push(
|
|
5082
|
+
rect(center + offset, Math.min(a2, b), barSize, Math.abs(b - a2), color, s.shadowFilter)
|
|
5083
|
+
);
|
|
5084
|
+
out.push("</g>");
|
|
5085
|
+
});
|
|
5086
|
+
});
|
|
5087
|
+
}
|
|
5088
|
+
|
|
5089
|
+
// chart/render/chart-svg-analysis.ts
|
|
5090
|
+
var DASHES = {
|
|
5091
|
+
dot: [1, 3],
|
|
5092
|
+
dash: [4, 3],
|
|
5093
|
+
lgDash: [8, 3],
|
|
5094
|
+
dashDot: [4, 3, 1, 3],
|
|
5095
|
+
lgDashDot: [8, 3, 1, 3],
|
|
5096
|
+
lgDashDotDot: [8, 3, 1, 3, 1, 3],
|
|
5097
|
+
sysDash: [3, 1],
|
|
5098
|
+
sysDot: [1, 1],
|
|
5099
|
+
sysDashDot: [3, 1, 1, 1],
|
|
5100
|
+
sysDashDotDot: [3, 1, 1, 1, 1, 1]
|
|
5101
|
+
};
|
|
5102
|
+
var CAP = 4;
|
|
5103
|
+
function strokeAttributes(stroke) {
|
|
5104
|
+
const pattern = stroke.dash ? DASHES[stroke.dash] : void 0;
|
|
5105
|
+
const dash = pattern ? ` stroke-dasharray="${pattern.map((step) => n(step * stroke.width)).join(" ")}"` : "";
|
|
5106
|
+
return `stroke="${esc(stroke.color)}" stroke-width="${n(stroke.width)}"${dash}`;
|
|
5107
|
+
}
|
|
5108
|
+
var segment = (x1, y1, x2, y2, stroke) => `<line x1="${n(x1)}" y1="${n(y1)}" x2="${n(x2)}" y2="${n(y2)}" ${stroke}/>`;
|
|
5109
|
+
function trendlines(series, si, xs, ys, plane, out) {
|
|
5110
|
+
for (const trendline of series.trendlines ?? []) {
|
|
5111
|
+
const fit2 = fitChartTrendline(trendline.fit, xs, ys);
|
|
5112
|
+
if (fit2.points.length < 2) continue;
|
|
5113
|
+
const points = fit2.points.map(({ x, y }) => plane(x, y).map(n).join(",")).join(" ");
|
|
5114
|
+
out.push(
|
|
5115
|
+
`<polyline points="${points}" fill="none" ${strokeAttributes(trendline.stroke)} data-chart-part="trendline" data-chart-series="${si}"/>`
|
|
5116
|
+
);
|
|
3750
5117
|
}
|
|
3751
|
-
|
|
3752
|
-
|
|
3753
|
-
|
|
3754
|
-
|
|
5118
|
+
}
|
|
5119
|
+
function errorBar(bars2, at, values, plane, out) {
|
|
5120
|
+
const stroke = strokeAttributes(bars2.stroke);
|
|
5121
|
+
for (const side of ["plus", "minus"]) {
|
|
5122
|
+
if (bars2.barType !== side && bars2.barType !== "both") continue;
|
|
5123
|
+
const amount = chartErrorBarAmount(bars2.amount, values, at.displayIndex, at.sourceIndex, side);
|
|
5124
|
+
const sign = side === "plus" ? 1 : -1;
|
|
5125
|
+
const [x1, y1] = plane(at.x, at.y);
|
|
5126
|
+
const [x2, y2] = bars2.direction === "x" ? plane(at.x + sign * amount, at.y) : plane(at.x, at.y + sign * amount);
|
|
5127
|
+
out.push(segment(x1, y1, x2, y2, stroke));
|
|
5128
|
+
if (!bars2.endCap) continue;
|
|
5129
|
+
if (x1 === x2) out.push(segment(x2 - CAP, y2, x2 + CAP, y2, stroke));
|
|
5130
|
+
else out.push(segment(x2, y2 - CAP, x2, y2 + CAP, stroke));
|
|
5131
|
+
}
|
|
5132
|
+
}
|
|
5133
|
+
function plottedPoints(series, xOf) {
|
|
5134
|
+
return series.values.flatMap((y, index) => {
|
|
5135
|
+
const x = xOf(index);
|
|
5136
|
+
return y === null || x === null ? [] : [{ x, y, index }];
|
|
5137
|
+
});
|
|
5138
|
+
}
|
|
5139
|
+
function seriesAnalysis(series, si, xOf, plane, barPlane, categoryAxis, out) {
|
|
5140
|
+
const points = plottedPoints(series, xOf);
|
|
5141
|
+
const xs = points.map((p) => p.x);
|
|
5142
|
+
const ys = points.map((p) => p.y);
|
|
5143
|
+
trendlines(series, si, xs, ys, plane, out);
|
|
5144
|
+
for (const bars2 of series.errorBars ?? []) {
|
|
5145
|
+
if (categoryAxis && bars2.direction === "x") continue;
|
|
5146
|
+
const values = bars2.direction === "x" ? xs : ys;
|
|
5147
|
+
points.forEach(
|
|
5148
|
+
(p, displayIndex) => errorBar(bars2, { x: p.x, y: p.y, displayIndex, sourceIndex: p.index }, values, barPlane, out)
|
|
5149
|
+
);
|
|
3755
5150
|
}
|
|
3756
|
-
const legendPos = chartSpace.legend?.position;
|
|
3757
|
-
if (legendPos && ["r", "l", "t", "b", "tr"].includes(legendPos))
|
|
3758
|
-
summary.legendPosition = legendPos;
|
|
3759
|
-
if (extras.formatting) summary.formatting = extras.formatting;
|
|
3760
|
-
if (extras.colorPalette !== void 0) summary.colorPalette = extras.colorPalette;
|
|
3761
|
-
if (extras.styleDefinition) summary.styleDefinition = extras.styleDefinition;
|
|
3762
|
-
return summary;
|
|
3763
5151
|
}
|
|
3764
|
-
|
|
3765
|
-
|
|
3766
|
-
|
|
3767
|
-
|
|
3768
|
-
const
|
|
3769
|
-
|
|
5152
|
+
function categoryAnalysis(model, frame, out) {
|
|
5153
|
+
if (model.grouping === "stacked" || model.grouping === "percentStacked") return;
|
|
5154
|
+
const plane = (x, y) => model.horizontal ? [frame.value(y), frame.band(x - 1)] : [frame.band(x - 1), frame.value(y)];
|
|
5155
|
+
const barred = model.type === "bar" || model.type === "column";
|
|
5156
|
+
const layout = barred ? barLayout(model, frame) : void 0;
|
|
5157
|
+
model.series.forEach((series, si) => {
|
|
5158
|
+
if (!series.trendlines && !series.errorBars) return;
|
|
5159
|
+
const shift = layout ? layout.offset(si) + layout.barSize / 2 : 0;
|
|
5160
|
+
const barPlane = (x, y) => {
|
|
5161
|
+
const [px, py] = plane(x, y);
|
|
5162
|
+
return model.horizontal ? [px, py + shift] : [px + shift, py];
|
|
5163
|
+
};
|
|
5164
|
+
seriesAnalysis(series, si, (i) => i + 1, plane, barPlane, true, out);
|
|
5165
|
+
});
|
|
5166
|
+
}
|
|
5167
|
+
function scatterAnalysis(model, px, py, out) {
|
|
5168
|
+
const plane = (x, y) => [px(x), py(y)];
|
|
5169
|
+
model.series.forEach((series, si) => {
|
|
5170
|
+
if (!series.trendlines && !series.errorBars) return;
|
|
5171
|
+
seriesAnalysis(series, si, (i) => series.xValues?.[i] ?? null, plane, plane, false, out);
|
|
5172
|
+
});
|
|
3770
5173
|
}
|
|
3771
5174
|
|
|
3772
5175
|
// chart/render/chart-scale.ts
|
|
@@ -3835,36 +5238,47 @@ function formatAxisValue(value, percent = false) {
|
|
|
3835
5238
|
return `${v < 0 ? "-" : ""}${grouped}${frac ? `.${frac}` : ""}`;
|
|
3836
5239
|
}
|
|
3837
5240
|
|
|
3838
|
-
//
|
|
3839
|
-
|
|
3840
|
-
|
|
3841
|
-
|
|
3842
|
-
|
|
3843
|
-
|
|
3844
|
-
return
|
|
5241
|
+
// drawingml/drawing-color-css.ts
|
|
5242
|
+
function drawingColorCss(value) {
|
|
5243
|
+
if (!value || value.alpha === 1) return value?.hex;
|
|
5244
|
+
const channels = [1, 3, 5].map(
|
|
5245
|
+
(offset) => Number.parseInt(value.hex.slice(offset, offset + 2), 16)
|
|
5246
|
+
);
|
|
5247
|
+
return `rgba(${channels.join(",")},${value.alpha})`;
|
|
3845
5248
|
}
|
|
3846
|
-
|
|
3847
|
-
|
|
3848
|
-
|
|
3849
|
-
|
|
3850
|
-
|
|
3851
|
-
|
|
3852
|
-
|
|
3853
|
-
|
|
3854
|
-
if (
|
|
3855
|
-
|
|
3856
|
-
if (
|
|
3857
|
-
|
|
3858
|
-
|
|
3859
|
-
|
|
3860
|
-
|
|
5249
|
+
|
|
5250
|
+
// units/constants.ts
|
|
5251
|
+
var EMU_PER_PIXEL = 9525;
|
|
5252
|
+
var EMU_PER_POINT = 12700;
|
|
5253
|
+
|
|
5254
|
+
// drawingml/drawing-shadow.ts
|
|
5255
|
+
function resolveDrawingShadow(effects, theme) {
|
|
5256
|
+
const node = first(effects, "outerShdw", NS.a);
|
|
5257
|
+
if (!node) return void 0;
|
|
5258
|
+
const value = (key, fallback) => Number(node.getAttribute(key) ?? fallback);
|
|
5259
|
+
if (value("sx", 1e5) !== 1e5 || value("sy", 1e5) !== 1e5 || value("kx", 0) !== 0 || value("ky", 0) !== 0)
|
|
5260
|
+
return void 0;
|
|
5261
|
+
const color = parseDrawingColorIn(node);
|
|
5262
|
+
const resolved = color && resolveDrawingColor(color, theme, { transformOrder: "document" });
|
|
5263
|
+
const blur = value("blurRad", 0) / EMU_PER_PIXEL;
|
|
5264
|
+
const distance = value("dist", 0) / EMU_PER_PIXEL;
|
|
5265
|
+
const angle = value("dir", 0) / 6e4 * Math.PI / 180;
|
|
5266
|
+
if (!resolved || ![blur, distance, angle].every(Number.isFinite) || blur < 0 || distance < 0)
|
|
5267
|
+
return void 0;
|
|
5268
|
+
return {
|
|
5269
|
+
color: resolved.hex,
|
|
5270
|
+
opacity: resolved.alpha,
|
|
5271
|
+
blur,
|
|
5272
|
+
dx: Math.cos(angle) * distance,
|
|
5273
|
+
dy: Math.sin(angle) * distance
|
|
5274
|
+
};
|
|
3861
5275
|
}
|
|
3862
|
-
|
|
3863
|
-
|
|
3864
|
-
|
|
3865
|
-
|
|
3866
|
-
const
|
|
3867
|
-
return
|
|
5276
|
+
function resolveDrawingShadowXml(xml, theme) {
|
|
5277
|
+
return xml ? resolveDrawingShadow(parseXml(xml).documentElement, theme) : void 0;
|
|
5278
|
+
}
|
|
5279
|
+
function svgDropShadowElement(s, format) {
|
|
5280
|
+
const num = format.number;
|
|
5281
|
+
return `<feDropShadow dx="${num(s.dx)}" dy="${num(s.dy)}" stdDeviation="${num(s.blur / 2)}" flood-color="${format.color(s.color, "#000000")}" flood-opacity="${num(s.opacity)}" result="shadow"/>`;
|
|
3868
5282
|
}
|
|
3869
5283
|
|
|
3870
5284
|
// chart/render/theme-palette.ts
|
|
@@ -3928,88 +5342,6 @@ function autoSeriesColor(theme, index) {
|
|
|
3928
5342
|
return chartPaletteSeriesColor(findChartColorPalette(10), i, i + 1, chartColorScheme(theme));
|
|
3929
5343
|
}
|
|
3930
5344
|
|
|
3931
|
-
// drawingml/drawing-color-css.ts
|
|
3932
|
-
function drawingColorCss(value) {
|
|
3933
|
-
if (!value || value.alpha === 1) return value?.hex;
|
|
3934
|
-
const channels = [1, 3, 5].map(
|
|
3935
|
-
(offset) => Number.parseInt(value.hex.slice(offset, offset + 2), 16)
|
|
3936
|
-
);
|
|
3937
|
-
return `rgba(${channels.join(",")},${value.alpha})`;
|
|
3938
|
-
}
|
|
3939
|
-
|
|
3940
|
-
// chart/render/chart-value-axis.ts
|
|
3941
|
-
function valueAxis(model) {
|
|
3942
|
-
const stackable = model.type === "bar" || model.type === "column" || model.type === "line" || model.type === "area";
|
|
3943
|
-
if (stackable && model.grouping === "percentStacked")
|
|
3944
|
-
return { ...PERCENT_SCALE, ticks: [...PERCENT_SCALE.ticks], percent: true };
|
|
3945
|
-
let min = Infinity;
|
|
3946
|
-
let max = -Infinity;
|
|
3947
|
-
if (stackable && model.grouping === "stacked") {
|
|
3948
|
-
for (let i = 0; i < model.categories.length; i++) {
|
|
3949
|
-
let pos = 0;
|
|
3950
|
-
let neg = 0;
|
|
3951
|
-
for (const s of model.series) {
|
|
3952
|
-
const v = s.values[i] ?? 0;
|
|
3953
|
-
if (v >= 0) pos += v;
|
|
3954
|
-
else neg += v;
|
|
3955
|
-
}
|
|
3956
|
-
min = Math.min(min, neg);
|
|
3957
|
-
max = Math.max(max, pos);
|
|
3958
|
-
}
|
|
3959
|
-
} else {
|
|
3960
|
-
for (const s of model.series)
|
|
3961
|
-
for (const v of s.values)
|
|
3962
|
-
if (v !== null) {
|
|
3963
|
-
min = Math.min(min, v);
|
|
3964
|
-
max = Math.max(max, v);
|
|
3965
|
-
}
|
|
3966
|
-
}
|
|
3967
|
-
if (min === Infinity) {
|
|
3968
|
-
min = 0;
|
|
3969
|
-
max = 1;
|
|
3970
|
-
}
|
|
3971
|
-
return { ...niceScale(min, max), percent: false };
|
|
3972
|
-
}
|
|
3973
|
-
function categoryTotals(model) {
|
|
3974
|
-
return model.categories.map(
|
|
3975
|
-
(_, i) => model.series.reduce((sum, s) => sum + Math.abs(s.values[i] ?? 0), 0)
|
|
3976
|
-
);
|
|
3977
|
-
}
|
|
3978
|
-
|
|
3979
|
-
// units/constants.ts
|
|
3980
|
-
var EMU_PER_PIXEL = 9525;
|
|
3981
|
-
var EMU_PER_POINT = 12700;
|
|
3982
|
-
|
|
3983
|
-
// drawingml/drawing-shadow.ts
|
|
3984
|
-
function resolveDrawingShadow(effects, theme) {
|
|
3985
|
-
const node = first(effects, "outerShdw", NS.a);
|
|
3986
|
-
if (!node) return void 0;
|
|
3987
|
-
const value = (key, fallback) => Number(node.getAttribute(key) ?? fallback);
|
|
3988
|
-
if (value("sx", 1e5) !== 1e5 || value("sy", 1e5) !== 1e5 || value("kx", 0) !== 0 || value("ky", 0) !== 0)
|
|
3989
|
-
return void 0;
|
|
3990
|
-
const color = parseDrawingColorIn(node);
|
|
3991
|
-
const resolved = color && resolveDrawingColor(color, theme, { transformOrder: "document" });
|
|
3992
|
-
const blur = value("blurRad", 0) / EMU_PER_PIXEL;
|
|
3993
|
-
const distance = value("dist", 0) / EMU_PER_PIXEL;
|
|
3994
|
-
const angle = value("dir", 0) / 6e4 * Math.PI / 180;
|
|
3995
|
-
if (!resolved || ![blur, distance, angle].every(Number.isFinite) || blur < 0 || distance < 0)
|
|
3996
|
-
return void 0;
|
|
3997
|
-
return {
|
|
3998
|
-
color: resolved.hex,
|
|
3999
|
-
opacity: resolved.alpha,
|
|
4000
|
-
blur,
|
|
4001
|
-
dx: Math.cos(angle) * distance,
|
|
4002
|
-
dy: Math.sin(angle) * distance
|
|
4003
|
-
};
|
|
4004
|
-
}
|
|
4005
|
-
function resolveDrawingShadowXml(xml, theme) {
|
|
4006
|
-
return xml ? resolveDrawingShadow(parseXml(xml).documentElement, theme) : void 0;
|
|
4007
|
-
}
|
|
4008
|
-
function svgDropShadowElement(s, format) {
|
|
4009
|
-
const num = format.number;
|
|
4010
|
-
return `<feDropShadow dx="${num(s.dx)}" dy="${num(s.dy)}" stdDeviation="${num(s.blur / 2)}" flood-color="${format.color(s.color, "#000000")}" flood-opacity="${num(s.opacity)}" result="shadow"/>`;
|
|
4011
|
-
}
|
|
4012
|
-
|
|
4013
5345
|
// chart/text-inheritance.ts
|
|
4014
5346
|
var TEXT_KEYS = [
|
|
4015
5347
|
"fontSize",
|
|
@@ -4075,27 +5407,239 @@ function chartAppearance(chart, theme) {
|
|
|
4075
5407
|
{ scheme: (name) => scheme[name] },
|
|
4076
5408
|
{ hslRounding: "halfDown", transformOrder: "document" }
|
|
4077
5409
|
);
|
|
4078
|
-
const out = resolveChartStyleDefinition(
|
|
4079
|
-
{ entries},
|
|
4080
|
-
(color) => drawingColorCss(resolve(color))
|
|
4081
|
-
) ?? {};
|
|
4082
|
-
for (const part of CHART_STYLE_PARTS) {
|
|
4083
|
-
const entry3 = entries[part];
|
|
4084
|
-
if (!entry3) continue;
|
|
4085
|
-
const family = typeface(entry3, theme);
|
|
4086
|
-
const shadow = resolveDrawingShadowXml(entry3.textEffectsXml, {
|
|
4087
|
-
scheme: (name) => scheme[name]
|
|
4088
|
-
});
|
|
4089
|
-
if (shadow) (out[part] ??= {}).textShadow = shadow;
|
|
4090
|
-
if (family) (out[part] ??= {}).typeface = family;
|
|
4091
|
-
if (entry3.axisVisible !== void 0) (out[part] ??= {}).axisVisible = entry3.axisVisible;
|
|
4092
|
-
if (entry3.labelsVisible !== void 0) (out[part] ??= {}).labelsVisible = entry3.labelsVisible;
|
|
4093
|
-
if (entry3.line?.widthEmu === 0) (out[part] ??= {}).lineWidth = 0;
|
|
4094
|
-
if (entry3.fill?.kind === "gradient") {
|
|
4095
|
-
(out[part] ??= {}).gradient = resolveChartGradient(entry3.fill, resolve);
|
|
5410
|
+
const out = resolveChartStyleDefinition(
|
|
5411
|
+
{ entries},
|
|
5412
|
+
(color) => drawingColorCss(resolve(color))
|
|
5413
|
+
) ?? {};
|
|
5414
|
+
for (const part of CHART_STYLE_PARTS) {
|
|
5415
|
+
const entry3 = entries[part];
|
|
5416
|
+
if (!entry3) continue;
|
|
5417
|
+
const family = typeface(entry3, theme);
|
|
5418
|
+
const shadow = resolveDrawingShadowXml(entry3.textEffectsXml, {
|
|
5419
|
+
scheme: (name) => scheme[name]
|
|
5420
|
+
});
|
|
5421
|
+
if (shadow) (out[part] ??= {}).textShadow = shadow;
|
|
5422
|
+
if (family) (out[part] ??= {}).typeface = family;
|
|
5423
|
+
if (entry3.axisVisible !== void 0) (out[part] ??= {}).axisVisible = entry3.axisVisible;
|
|
5424
|
+
if (entry3.labelsVisible !== void 0) (out[part] ??= {}).labelsVisible = entry3.labelsVisible;
|
|
5425
|
+
if (entry3.line?.widthEmu === 0) (out[part] ??= {}).lineWidth = 0;
|
|
5426
|
+
if (entry3.fill?.kind === "gradient") {
|
|
5427
|
+
(out[part] ??= {}).gradient = resolveChartGradient(entry3.fill, resolve);
|
|
5428
|
+
}
|
|
5429
|
+
}
|
|
5430
|
+
return out;
|
|
5431
|
+
}
|
|
5432
|
+
|
|
5433
|
+
// chart/render/chart-view-analysis.ts
|
|
5434
|
+
function strokeOf(line2, fallback, resolve) {
|
|
5435
|
+
if (line2?.fill?.kind === "none") return void 0;
|
|
5436
|
+
const color = (line2?.fill?.kind === "solid" ? resolve(line2.fill.color) : void 0) ?? fallback.color;
|
|
5437
|
+
const width = line2?.widthEmu === void 0 ? fallback.width : chartPointsToPixels(line2.widthEmu / 12700);
|
|
5438
|
+
const dash = line2?.dash ?? fallback.dash;
|
|
5439
|
+
return { color, width, ...dash && dash !== "solid" ? { dash } : {} };
|
|
5440
|
+
}
|
|
5441
|
+
function analysisView(source, seriesColor, resolve) {
|
|
5442
|
+
const plain = seriesColor === "none" || seriesColor.startsWith("url(") ? TEXT_COLOR : seriesColor;
|
|
5443
|
+
const trendlines2 = (source.trendlines ?? []).flatMap((entry3) => {
|
|
5444
|
+
const { name: _name, line: line2, ...fit2 } = entry3;
|
|
5445
|
+
const fallback = { color: plain, width: chartPointsToPixels(1.5), dash: "sysDot" };
|
|
5446
|
+
const stroke = strokeOf(line2, fallback, resolve);
|
|
5447
|
+
return stroke ? [{ fit: fit2, stroke }] : [];
|
|
5448
|
+
});
|
|
5449
|
+
const errorBars = (source.errorBars ?? []).flatMap((entry3) => {
|
|
5450
|
+
const { direction, barType, noEndCap, line: line2, ...amount } = entry3;
|
|
5451
|
+
const stroke = strokeOf(line2, { color: TEXT_COLOR, width: chartPointsToPixels(0.75) }, resolve);
|
|
5452
|
+
return stroke ? [{ direction, barType, amount, endCap: noEndCap !== true, stroke }] : [];
|
|
5453
|
+
});
|
|
5454
|
+
return {
|
|
5455
|
+
...trendlines2.length ? { trendlines: trendlines2 } : {},
|
|
5456
|
+
...errorBars.length ? { errorBars } : {}
|
|
5457
|
+
};
|
|
5458
|
+
}
|
|
5459
|
+
|
|
5460
|
+
// chart/render/chart-view-series.ts
|
|
5461
|
+
var isRefError = (value) => typeof value === "object" && value !== null && "error" in value;
|
|
5462
|
+
function toText(value) {
|
|
5463
|
+
if (value === null) return "";
|
|
5464
|
+
if (typeof value === "boolean") return value ? "TRUE" : "FALSE";
|
|
5465
|
+
if (isRefError(value)) return value.error;
|
|
5466
|
+
return String(value);
|
|
5467
|
+
}
|
|
5468
|
+
var toNumber = (value) => typeof value === "number" && Number.isFinite(value) ? value : null;
|
|
5469
|
+
function resolveRef(ref, evaluateRef) {
|
|
5470
|
+
if (!ref) return void 0;
|
|
5471
|
+
try {
|
|
5472
|
+
const values = evaluateRef(ref);
|
|
5473
|
+
return values.length ? values : void 0;
|
|
5474
|
+
} catch {
|
|
5475
|
+
return void 0;
|
|
5476
|
+
}
|
|
5477
|
+
}
|
|
5478
|
+
function seriesName(series, index, evaluateRef) {
|
|
5479
|
+
const fromRef = resolveRef(series.nameRef, evaluateRef)?.map(toText).filter((t) => t !== "").join(" ");
|
|
5480
|
+
return fromRef || series.name || `Series${index + 1}`;
|
|
5481
|
+
}
|
|
5482
|
+
function seriesContext(chart, theme, options) {
|
|
5483
|
+
const scheme = chartColorScheme(theme);
|
|
5484
|
+
const resolver = { scheme: (name) => scheme[name] };
|
|
5485
|
+
return {
|
|
5486
|
+
theme,
|
|
5487
|
+
scheme,
|
|
5488
|
+
palette: chart.colorPalette === void 0 ? void 0 : findChartColorPalette(chart.colorPalette),
|
|
5489
|
+
evaluateRef: options.evaluateRef ?? (() => []),
|
|
5490
|
+
seriesColor: options.seriesColor,
|
|
5491
|
+
drawingColor: (color) => color && drawingColorCss(resolveDrawingColor(color, resolver, { transformOrder: "document" })),
|
|
5492
|
+
gradient: (fill) => fill?.kind === "gradient" ? resolveChartGradient(
|
|
5493
|
+
fill,
|
|
5494
|
+
(color) => resolveDrawingColor(color, resolver, { transformOrder: "document" })
|
|
5495
|
+
) : void 0
|
|
5496
|
+
};
|
|
5497
|
+
}
|
|
5498
|
+
function seriesView(ctx, s, index, total, categoriesOf) {
|
|
5499
|
+
const { theme, scheme, palette, evaluateRef } = ctx;
|
|
5500
|
+
const values = resolveRef(s.valuesRef, evaluateRef)?.map(toNumber) ?? s.values.map(toNumber);
|
|
5501
|
+
categoriesOf(resolveRef(s.categoriesRef, evaluateRef) ?? s.categories);
|
|
5502
|
+
const paletteColor = palette && chartPaletteSeriesColor(palette, index, total, scheme);
|
|
5503
|
+
const color = s.fill?.kind === "none" ? "none" : ctx.drawingColor(s.fill?.kind === "solid" ? s.fill.color : s.drawingColor) ?? ctx.seriesColor?.(s, index) ?? paletteColor ?? autoSeriesColor(theme, index);
|
|
5504
|
+
const view = { name: seriesName(s, index, evaluateRef), values, color };
|
|
5505
|
+
const shadow = resolveDrawingShadowXml(s.effectsXml, { scheme: (name) => scheme[name] });
|
|
5506
|
+
if (shadow) view.shadow = shadow;
|
|
5507
|
+
const resolvedGradient = ctx.gradient(s.fill);
|
|
5508
|
+
if (resolvedGradient) view.gradient = resolvedGradient;
|
|
5509
|
+
const points = Object.fromEntries(
|
|
5510
|
+
Object.entries(s.pointFills ?? {}).flatMap(([key, fill]) => {
|
|
5511
|
+
const value = ctx.gradient(fill);
|
|
5512
|
+
return value ? [[key, value]] : [];
|
|
5513
|
+
})
|
|
5514
|
+
);
|
|
5515
|
+
if (Object.keys(points).length) view.pointGradients = points;
|
|
5516
|
+
Object.assign(view, analysisView(s, color, ctx.drawingColor));
|
|
5517
|
+
return view;
|
|
5518
|
+
}
|
|
5519
|
+
|
|
5520
|
+
// chart/render/chart-view-families.ts
|
|
5521
|
+
function bubbleView(chart, model, evaluateRef) {
|
|
5522
|
+
chart.series.forEach((source, i) => {
|
|
5523
|
+
const view = model.series[i];
|
|
5524
|
+
if (!view) return;
|
|
5525
|
+
const live = resolveRef(source.bubbleSizesRef, evaluateRef)?.map(toNumber);
|
|
5526
|
+
const sizes = live ?? source.bubbleSizes;
|
|
5527
|
+
if (sizes) view.sizes = sizes;
|
|
5528
|
+
});
|
|
5529
|
+
model.bubble = {
|
|
5530
|
+
sizeRepresents: chart.bubble?.sizeRepresents ?? "area",
|
|
5531
|
+
...chart.bubble?.bubbleScale === void 0 ? {} : { bubbleScale: chart.bubble.bubbleScale },
|
|
5532
|
+
showNegativeBubbles: chart.bubble?.showNegativeBubbles === true
|
|
5533
|
+
};
|
|
5534
|
+
}
|
|
5535
|
+
var columnNumber = (letters) => [...letters].reduce((n2, ch) => n2 * 26 + ch.charCodeAt(0) - 64, 0);
|
|
5536
|
+
function refColumns(ref) {
|
|
5537
|
+
const match = /\$?([A-Z]{1,3})\$?\d+:\$?([A-Z]{1,3})\$?\d+\s*$/i.exec(ref);
|
|
5538
|
+
if (!match) return 1;
|
|
5539
|
+
return Math.max(
|
|
5540
|
+
1,
|
|
5541
|
+
columnNumber((match[2] ?? "").toUpperCase()) - columnNumber((match[1] ?? "").toUpperCase()) + 1
|
|
5542
|
+
);
|
|
5543
|
+
}
|
|
5544
|
+
function liveLevels(ref, evaluateRef) {
|
|
5545
|
+
const columns = ref ? refColumns(ref) : 1;
|
|
5546
|
+
const flat = columns > 1 ? resolveRef(ref, evaluateRef)?.map(toText) : void 0;
|
|
5547
|
+
if (!flat || flat.length % columns !== 0) return void 0;
|
|
5548
|
+
const levels = Array.from({ length: columns }, () => []);
|
|
5549
|
+
flat.forEach((label, i) => levels[columns - 1 - i % columns]?.push(label));
|
|
5550
|
+
return levels;
|
|
5551
|
+
}
|
|
5552
|
+
function hierarchyView(chart, model, evaluateRef) {
|
|
5553
|
+
const first2 = model.series[0];
|
|
5554
|
+
const live = liveLevels(chart.series[0]?.categoriesRef, evaluateRef);
|
|
5555
|
+
if (live?.[0]) model.categories = live[0];
|
|
5556
|
+
const count = Math.max(first2?.values.length ?? 0, model.categories.length);
|
|
5557
|
+
const supplied = live ?? chart.hierarchy?.levels ?? [];
|
|
5558
|
+
const levels = supplied.length > 1 ? normalizeLevels(supplied, count) : [];
|
|
5559
|
+
model.hierarchy = {
|
|
5560
|
+
levels,
|
|
5561
|
+
parentLabelLayout: chart.hierarchy?.parentLabelLayout ?? "banner",
|
|
5562
|
+
labels: chart.hierarchy?.dataLabels !== false,
|
|
5563
|
+
branches: hierarchyBranchLabels(
|
|
5564
|
+
model.series.map((s) => ({ name: s.name, values: s.values.map((v) => v ?? 0) })),
|
|
5565
|
+
model.categories,
|
|
5566
|
+
levels.length > 1 ? levels : void 0
|
|
5567
|
+
)
|
|
5568
|
+
};
|
|
5569
|
+
}
|
|
5570
|
+
|
|
5571
|
+
// chart/render/chart-view-stock.ts
|
|
5572
|
+
var EMU_PER_PX = 9525;
|
|
5573
|
+
function paintOf(fill, ctx) {
|
|
5574
|
+
if (fill?.kind === "none") return "none";
|
|
5575
|
+
return fill?.kind === "solid" ? ctx.drawingColor(fill.color) : void 0;
|
|
5576
|
+
}
|
|
5577
|
+
function lineOf(shape, ctx, color) {
|
|
5578
|
+
const line2 = shape?.line;
|
|
5579
|
+
return {
|
|
5580
|
+
color: paintOf(line2?.fill, ctx) ?? color,
|
|
5581
|
+
width: line2?.widthEmu === void 0 ? 1 : Math.max(0.5, line2.widthEmu / EMU_PER_PX)
|
|
5582
|
+
};
|
|
5583
|
+
}
|
|
5584
|
+
function barOf(shape, ctx, fallback) {
|
|
5585
|
+
const stroke = lineOf(shape, ctx, "#404040");
|
|
5586
|
+
return {
|
|
5587
|
+
fill: paintOf(shape?.fill, ctx) ?? fallback,
|
|
5588
|
+
stroke: stroke.color,
|
|
5589
|
+
strokeWidth: stroke.width
|
|
5590
|
+
};
|
|
5591
|
+
}
|
|
5592
|
+
function stockView(style, ctx) {
|
|
5593
|
+
return {
|
|
5594
|
+
wick: lineOf(style?.hiLowLines, ctx, STOCK_DEFAULT_WICK_COLOR),
|
|
5595
|
+
up: barOf(style?.upBars, ctx, STOCK_DEFAULT_UP_FILL),
|
|
5596
|
+
down: barOf(style?.downBars, ctx, STOCK_DEFAULT_DOWN_FILL),
|
|
5597
|
+
bodyShare: 1 / (1 + Math.max(0, style?.gapWidth ?? 150) / 100)
|
|
5598
|
+
};
|
|
5599
|
+
}
|
|
5600
|
+
|
|
5601
|
+
// chart/render/chart-value-axis.ts
|
|
5602
|
+
function valueExtent(type, grouping, series, categories) {
|
|
5603
|
+
const stackable = type === "bar" || type === "column" || type === "line" || type === "area";
|
|
5604
|
+
let min = Infinity;
|
|
5605
|
+
let max = -Infinity;
|
|
5606
|
+
if (stackable && grouping === "stacked") {
|
|
5607
|
+
for (let i = 0; i < categories; i++) {
|
|
5608
|
+
let pos = 0;
|
|
5609
|
+
let neg = 0;
|
|
5610
|
+
for (const s of series) {
|
|
5611
|
+
const v = s.values[i] ?? 0;
|
|
5612
|
+
if (v >= 0) pos += v;
|
|
5613
|
+
else neg += v;
|
|
5614
|
+
}
|
|
5615
|
+
min = Math.min(min, neg);
|
|
5616
|
+
max = Math.max(max, pos);
|
|
4096
5617
|
}
|
|
5618
|
+
} else {
|
|
5619
|
+
for (const s of series)
|
|
5620
|
+
for (const v of s.values)
|
|
5621
|
+
if (v !== null) {
|
|
5622
|
+
min = Math.min(min, v);
|
|
5623
|
+
max = Math.max(max, v);
|
|
5624
|
+
}
|
|
4097
5625
|
}
|
|
4098
|
-
return
|
|
5626
|
+
return { min, max };
|
|
5627
|
+
}
|
|
5628
|
+
function valueAxis(model) {
|
|
5629
|
+
const stackable = model.type === "bar" || model.type === "column" || model.type === "line" || model.type === "area";
|
|
5630
|
+
if (stackable && model.grouping === "percentStacked")
|
|
5631
|
+
return { ...PERCENT_SCALE, ticks: [...PERCENT_SCALE.ticks], percent: true };
|
|
5632
|
+
let { min, max } = valueExtent(model.type, model.grouping, model.series, model.categories.length);
|
|
5633
|
+
if (min === Infinity) {
|
|
5634
|
+
min = 0;
|
|
5635
|
+
max = 1;
|
|
5636
|
+
}
|
|
5637
|
+
return { ...niceScale(min, max), percent: false };
|
|
5638
|
+
}
|
|
5639
|
+
function categoryTotals(model) {
|
|
5640
|
+
return model.categories.map(
|
|
5641
|
+
(_, i) => model.series.reduce((sum, s) => sum + Math.abs(s.values[i] ?? 0), 0)
|
|
5642
|
+
);
|
|
4099
5643
|
}
|
|
4100
5644
|
|
|
4101
5645
|
// chart/render/chart-title-text.ts
|
|
@@ -4142,8 +5686,87 @@ function chartTitleText(chart, theme) {
|
|
|
4142
5686
|
};
|
|
4143
5687
|
}
|
|
4144
5688
|
|
|
5689
|
+
// chart/render/chart-view-ex.ts
|
|
5690
|
+
function groupsAxis(groups, categories) {
|
|
5691
|
+
let min = Infinity;
|
|
5692
|
+
let max = -Infinity;
|
|
5693
|
+
for (const group2 of groups) {
|
|
5694
|
+
const extent = valueExtent(group2.type, group2.grouping, group2.series, categories);
|
|
5695
|
+
min = Math.min(min, extent.min);
|
|
5696
|
+
max = Math.max(max, extent.max);
|
|
5697
|
+
}
|
|
5698
|
+
return min === Infinity ? { ...niceScale(0, 1), percent: false } : { ...niceScale(min, max), percent: false };
|
|
5699
|
+
}
|
|
5700
|
+
function chartExtraView(chart, model, ctx, total, categoriesOf) {
|
|
5701
|
+
let index = chart.series.length;
|
|
5702
|
+
const groups = [];
|
|
5703
|
+
for (const group2 of chart.extraGroups ?? []) {
|
|
5704
|
+
const series = group2.series.map((s) => seriesView(ctx, s, index++, total, categoriesOf));
|
|
5705
|
+
const view = {
|
|
5706
|
+
type: group2.chartType,
|
|
5707
|
+
grouping: group2.grouping ?? (group2.chartType === "column" ? "clustered" : "standard"),
|
|
5708
|
+
series,
|
|
5709
|
+
secondary: group2.secondary
|
|
5710
|
+
};
|
|
5711
|
+
if (group2.chartType === "stock") view.stock = stockView(group2.stock, ctx);
|
|
5712
|
+
if (group2.barGapWidth !== void 0) view.barGapWidth = group2.barGapWidth;
|
|
5713
|
+
if (group2.barOverlap !== void 0) view.barOverlap = group2.barOverlap;
|
|
5714
|
+
groups.push(view);
|
|
5715
|
+
}
|
|
5716
|
+
if (!groups.length) return;
|
|
5717
|
+
model.extraGroups = groups;
|
|
5718
|
+
}
|
|
5719
|
+
function chartExtraAxes(model) {
|
|
5720
|
+
const groups = model.extraGroups;
|
|
5721
|
+
if (!groups || !model.valueAxis) return;
|
|
5722
|
+
const count = model.categories.length;
|
|
5723
|
+
const secondary = groups.filter((g) => g.secondary);
|
|
5724
|
+
if (secondary.length) model.secondaryAxis = groupsAxis(secondary, count);
|
|
5725
|
+
const shared = groups.filter((g) => !g.secondary);
|
|
5726
|
+
if (!shared.length || model.valueAxis.percent) return;
|
|
5727
|
+
const own = valueExtent(model.type, model.grouping, model.series, count);
|
|
5728
|
+
let min = own.min;
|
|
5729
|
+
let max = own.max;
|
|
5730
|
+
for (const group2 of shared) {
|
|
5731
|
+
const extent = valueExtent(group2.type, group2.grouping, group2.series, count);
|
|
5732
|
+
min = Math.min(min, extent.min);
|
|
5733
|
+
max = Math.max(max, extent.max);
|
|
5734
|
+
}
|
|
5735
|
+
model.valueAxis = { ...niceScale(min, max), percent: false };
|
|
5736
|
+
}
|
|
5737
|
+
function waterfallView(chart, model, ctx) {
|
|
5738
|
+
const values = (model.series[0]?.values ?? []).map((v) => v ?? 0);
|
|
5739
|
+
const steps = buildWaterfallSteps(values, chart.waterfall);
|
|
5740
|
+
const role = (i) => ctx.palette && chartPaletteSeriesColor(ctx.palette, i, 3, ctx.scheme) || autoSeriesColor(ctx.theme, i);
|
|
5741
|
+
model.waterfall = {
|
|
5742
|
+
steps,
|
|
5743
|
+
connectors: chart.waterfall?.connectorLines !== false,
|
|
5744
|
+
colors: { increase: role(0), decrease: role(1), total: role(2) }
|
|
5745
|
+
};
|
|
5746
|
+
const ends = steps.flatMap((step) => [step.startValue, step.endValue]);
|
|
5747
|
+
model.valueAxis = {
|
|
5748
|
+
...ends.length ? niceScale(Math.min(...ends), Math.max(...ends)) : niceScale(0, 1),
|
|
5749
|
+
percent: false
|
|
5750
|
+
};
|
|
5751
|
+
const labels = model.categories;
|
|
5752
|
+
model.categories = steps.map((_, i) => labels[i] ?? String(i + 1));
|
|
5753
|
+
}
|
|
5754
|
+
function histogramView(chart, model) {
|
|
5755
|
+
const first2 = model.series[0];
|
|
5756
|
+
if (!first2) return;
|
|
5757
|
+
const raw2 = first2.values.map((v) => v ?? Number.NaN);
|
|
5758
|
+
const options = chart.histogram ?? {};
|
|
5759
|
+
const bins = options.aggregateByCategory ? aggregateByCategory(
|
|
5760
|
+
first2.values.map((v) => v ?? 0),
|
|
5761
|
+
model.categories
|
|
5762
|
+
) : computeHistogramBins(raw2, options, formatAxisValue);
|
|
5763
|
+
model.categories = bins.map((bin) => bin.label);
|
|
5764
|
+
first2.values = bins.map((bin) => bin.value);
|
|
5765
|
+
model.barGapWidth = 0;
|
|
5766
|
+
model.barOverlap = 0;
|
|
5767
|
+
}
|
|
5768
|
+
|
|
4145
5769
|
// chart/render/chart-view.ts
|
|
4146
|
-
var isRefError = (value) => typeof value === "object" && value !== null && "error" in value;
|
|
4147
5770
|
var SUPPORTED = /* @__PURE__ */ new Set([
|
|
4148
5771
|
"bar",
|
|
4149
5772
|
"column",
|
|
@@ -4152,85 +5775,37 @@ var SUPPORTED = /* @__PURE__ */ new Set([
|
|
|
4152
5775
|
"pie",
|
|
4153
5776
|
"doughnut",
|
|
4154
5777
|
"scatter",
|
|
4155
|
-
"radar"
|
|
5778
|
+
"radar",
|
|
5779
|
+
"waterfall",
|
|
5780
|
+
"histogram",
|
|
5781
|
+
"bubble",
|
|
5782
|
+
"stock",
|
|
5783
|
+
"treemap",
|
|
5784
|
+
"sunburst"
|
|
4156
5785
|
]);
|
|
4157
|
-
function toText(value) {
|
|
4158
|
-
if (value === null) return "";
|
|
4159
|
-
if (typeof value === "boolean") return value ? "TRUE" : "FALSE";
|
|
4160
|
-
if (isRefError(value)) return value.error;
|
|
4161
|
-
return String(value);
|
|
4162
|
-
}
|
|
4163
|
-
var toNumber = (value) => typeof value === "number" && Number.isFinite(value) ? value : null;
|
|
4164
|
-
function resolveRef(ref, evaluateRef) {
|
|
4165
|
-
if (!ref) return void 0;
|
|
4166
|
-
try {
|
|
4167
|
-
const values = evaluateRef(ref);
|
|
4168
|
-
return values.length ? values : void 0;
|
|
4169
|
-
} catch {
|
|
4170
|
-
return void 0;
|
|
4171
|
-
}
|
|
4172
|
-
}
|
|
4173
|
-
function seriesName(series, index, evaluateRef) {
|
|
4174
|
-
const fromRef = resolveRef(series.nameRef, evaluateRef)?.map(toText).filter((t) => t !== "").join(" ");
|
|
4175
|
-
return fromRef || series.name || `Series${index + 1}`;
|
|
4176
|
-
}
|
|
4177
5786
|
function chartSummaryView(chart, theme, options = {}) {
|
|
4178
|
-
const evaluateRef = options.evaluateRef ?? (() => []);
|
|
4179
5787
|
const type = chart.chartType;
|
|
4180
5788
|
const radial = type === "pie" || type === "doughnut";
|
|
4181
|
-
const
|
|
4182
|
-
const
|
|
4183
|
-
const
|
|
4184
|
-
resolveDrawingColor(
|
|
4185
|
-
color,
|
|
4186
|
-
{
|
|
4187
|
-
scheme: (name) => scheme[name]
|
|
4188
|
-
},
|
|
4189
|
-
{ transformOrder: "document" }
|
|
4190
|
-
)
|
|
4191
|
-
);
|
|
4192
|
-
const gradient = (fill) => fill?.kind === "gradient" ? resolveChartGradient(
|
|
4193
|
-
fill,
|
|
4194
|
-
(color) => resolveDrawingColor(
|
|
4195
|
-
color,
|
|
4196
|
-
{
|
|
4197
|
-
scheme: (name) => scheme[name]
|
|
4198
|
-
},
|
|
4199
|
-
{ transformOrder: "document" }
|
|
4200
|
-
)
|
|
4201
|
-
) : void 0;
|
|
5789
|
+
const byPoint = radial || type === "treemap" || type === "sunburst";
|
|
5790
|
+
const ctx = seriesContext(chart, theme, options);
|
|
5791
|
+
const { palette, scheme, drawingColor } = ctx;
|
|
4202
5792
|
const grouping = chart.grouping ?? (type === "bar" || type === "column" ? "clustered" : "standard");
|
|
4203
|
-
let categories = [];
|
|
4204
5793
|
const rawCategories = [];
|
|
4205
|
-
const
|
|
4206
|
-
|
|
4207
|
-
|
|
4208
|
-
|
|
4209
|
-
|
|
4210
|
-
|
|
4211
|
-
|
|
4212
|
-
|
|
4213
|
-
|
|
4214
|
-
});
|
|
4215
|
-
if (shadow) view.shadow = shadow;
|
|
4216
|
-
const resolvedGradient = gradient(s.fill);
|
|
4217
|
-
if (resolvedGradient) view.gradient = resolvedGradient;
|
|
4218
|
-
const points = Object.fromEntries(
|
|
4219
|
-
Object.entries(s.pointFills ?? {}).flatMap(([key, fill]) => {
|
|
4220
|
-
const value = gradient(fill);
|
|
4221
|
-
return value ? [[key, value]] : [];
|
|
4222
|
-
})
|
|
4223
|
-
);
|
|
4224
|
-
if (Object.keys(points).length) view.pointGradients = points;
|
|
4225
|
-
return view;
|
|
4226
|
-
});
|
|
4227
|
-
const longest = Math.max(0, ...series.map((s) => s.values.length));
|
|
5794
|
+
const collect = (cats) => void rawCategories.push(cats);
|
|
5795
|
+
const extra = chart.extraGroups ?? [];
|
|
5796
|
+
const total = chart.series.length + extra.reduce((n2, g) => n2 + g.series.length, 0);
|
|
5797
|
+
const series = chart.series.map((s, i) => seriesView(ctx, s, i, total, collect));
|
|
5798
|
+
const longest = Math.max(
|
|
5799
|
+
0,
|
|
5800
|
+
...series.map((s) => s.values.length),
|
|
5801
|
+
...extra.flatMap((g) => g.series.map((s) => s.values.length))
|
|
5802
|
+
);
|
|
4228
5803
|
const firstCats = rawCategories.find((c2) => c2.length > 0) ?? [];
|
|
4229
|
-
categories = Array.from(
|
|
5804
|
+
const categories = Array.from(
|
|
4230
5805
|
{ length: Math.max(longest, firstCats.length) },
|
|
4231
5806
|
(_, i) => firstCats[i] !== void 0 ? toText(firstCats[i] ?? null) : String(i + 1)
|
|
4232
5807
|
);
|
|
4233
|
-
if (
|
|
5808
|
+
if (byPoint) {
|
|
4234
5809
|
series.forEach((s, seriesIndex) => {
|
|
4235
5810
|
s.pointColors = s.values.map((_, i) => {
|
|
4236
5811
|
const explicit = drawingColor(chart.series[seriesIndex]?.pointColors?.[i]);
|
|
@@ -4251,8 +5826,8 @@ function chartSummaryView(chart, theme, options = {}) {
|
|
|
4251
5826
|
for (const [key, fill] of Object.entries(source.pointFills ?? {})) {
|
|
4252
5827
|
if (fill.kind === "none") (s.pointColors ??= [])[Number(key)] = "none";
|
|
4253
5828
|
else if (fill.kind === "solid") {
|
|
4254
|
-
const
|
|
4255
|
-
if (
|
|
5829
|
+
const paint2 = drawingColor(fill.color);
|
|
5830
|
+
if (paint2) (s.pointColors ??= [])[Number(key)] = paint2;
|
|
4256
5831
|
}
|
|
4257
5832
|
}
|
|
4258
5833
|
});
|
|
@@ -4279,7 +5854,7 @@ function chartSummaryView(chart, theme, options = {}) {
|
|
|
4279
5854
|
if (titleText) model.titleText = titleText;
|
|
4280
5855
|
const appearance = chartAppearance(chart, theme);
|
|
4281
5856
|
if (appearance) model.appearance = appearance;
|
|
4282
|
-
if (type === "scatter") {
|
|
5857
|
+
if (type === "scatter" || type === "bubble") {
|
|
4283
5858
|
series.forEach((s, i) => {
|
|
4284
5859
|
const cats = rawCategories[i] ?? [];
|
|
4285
5860
|
const numeric = cats.length > 0 && cats.every((c2) => typeof c2 === "number");
|
|
@@ -4288,7 +5863,15 @@ function chartSummaryView(chart, theme, options = {}) {
|
|
|
4288
5863
|
const xs = series.flatMap((s) => s.xValues ?? []).filter((x) => x !== null);
|
|
4289
5864
|
model.xAxis = xs.length ? niceScale(Math.min(...xs), Math.max(...xs)) : niceScale(0, 1);
|
|
4290
5865
|
}
|
|
4291
|
-
if (
|
|
5866
|
+
if (type === "stock") model.stock = stockView(chart.stock, ctx);
|
|
5867
|
+
if (type === "bubble") bubbleView(chart, model, ctx.evaluateRef);
|
|
5868
|
+
if (type === "treemap" || type === "sunburst") hierarchyView(chart, model, ctx.evaluateRef);
|
|
5869
|
+
if (type === "histogram") histogramView(chart, model);
|
|
5870
|
+
if (extra.length && (type === "column" || type === "line" || type === "area"))
|
|
5871
|
+
chartExtraView(chart, model, ctx, total, collect);
|
|
5872
|
+
if (type === "waterfall") waterfallView(chart, model, ctx);
|
|
5873
|
+
else if (!byPoint) model.valueAxis = valueAxis(model);
|
|
5874
|
+
chartExtraAxes(model);
|
|
4292
5875
|
return model;
|
|
4293
5876
|
}
|
|
4294
5877
|
|
|
@@ -4330,7 +5913,7 @@ function chartGradientPaint(model, width = 1024, height = 768) {
|
|
|
4330
5913
|
textShadowFilter: shadowPaint(entry3.textShadow, `${part}-text-shadow`)
|
|
4331
5914
|
};
|
|
4332
5915
|
}
|
|
4333
|
-
const
|
|
5916
|
+
const paint2 = (gradient, suffix, bounds) => {
|
|
4334
5917
|
const def = buildChartGradientDef(`${prefix}-${suffix}`, gradient, bounds);
|
|
4335
5918
|
defs.push(chartGradientMarkup(def));
|
|
4336
5919
|
return `url(#${def.id})`;
|
|
@@ -4341,18 +5924,18 @@ function chartGradientPaint(model, width = 1024, height = 768) {
|
|
|
4341
5924
|
if (part === "plotArea" && ["circle", "shape"].includes(entry3.gradient.path ?? "")) continue;
|
|
4342
5925
|
appearance[part] = {
|
|
4343
5926
|
...entry3,
|
|
4344
|
-
fillColor:
|
|
5927
|
+
fillColor: paint2(entry3.gradient, part, { width, height, shape: "rect" })
|
|
4345
5928
|
};
|
|
4346
5929
|
}
|
|
4347
5930
|
const series = model.series.map((source, index) => {
|
|
4348
5931
|
const view = { ...source };
|
|
4349
5932
|
if (source.shadow) view.shadowFilter = shadowPaint(source.shadow, `s${index}-shadow`);
|
|
4350
5933
|
const bounds = model.type === "bar" || model.type === "column" ? { width: 1, height: 1, shape: "rect" } : void 0;
|
|
4351
|
-
if (source.gradient) view.color =
|
|
5934
|
+
if (source.gradient) view.color = paint2(source.gradient, `s${index}`, bounds);
|
|
4352
5935
|
if (source.pointGradients) {
|
|
4353
5936
|
view.pointColors = [...source.pointColors ?? []];
|
|
4354
5937
|
for (const [key, gradient] of Object.entries(source.pointGradients))
|
|
4355
|
-
view.pointColors[Number(key)] =
|
|
5938
|
+
view.pointColors[Number(key)] = paint2(gradient, `s${index}-p${key}`, bounds);
|
|
4356
5939
|
}
|
|
4357
5940
|
return view;
|
|
4358
5941
|
});
|
|
@@ -4397,72 +5980,8 @@ function chartAreaRect(model, part, area) {
|
|
|
4397
5980
|
return `${defs}<rect x="${n(area.x)}" y="${n(area.y)}" width="${n(area.w)}" height="${n(area.h)}" fill="${esc(fill)}" stroke="${esc(stroke)}" stroke-width="${n(width)}" data-chart-part="${part}"/>`;
|
|
4398
5981
|
}
|
|
4399
5982
|
|
|
4400
|
-
// chart/render/chart-spacing.ts
|
|
4401
|
-
function chartBarSpacing(chart) {
|
|
4402
|
-
const stacked = chart.grouping === "stacked" || chart.grouping === "percentStacked";
|
|
4403
|
-
return {
|
|
4404
|
-
barGapWidth: chart.barGapWidth ?? DEFAULT_BAR_GAP_WIDTH,
|
|
4405
|
-
barOverlap: chart.barOverlap ?? (stacked ? 100 : 0)
|
|
4406
|
-
};
|
|
4407
|
-
}
|
|
4408
|
-
|
|
4409
|
-
// chart/render/chart-svg-bars.ts
|
|
4410
|
-
function bars(model, frame, out, values) {
|
|
4411
|
-
const stacked = model.grouping === "stacked" || model.grouping === "percentStacked";
|
|
4412
|
-
const count = Math.max(1, model.series.length);
|
|
4413
|
-
const geometry = clusteredBarGeometry(frame.bandSize, count, chartBarSpacing(model));
|
|
4414
|
-
const barSize = geometry.singleBarWidth;
|
|
4415
|
-
const base = frame.value(0);
|
|
4416
|
-
const pos = new Array(model.categories.length).fill(0);
|
|
4417
|
-
const neg = new Array(model.categories.length).fill(0);
|
|
4418
|
-
model.series.forEach((s, si) => {
|
|
4419
|
-
values[si]?.forEach((v, i) => {
|
|
4420
|
-
if (v === null || i >= model.categories.length) return;
|
|
4421
|
-
let from = 0;
|
|
4422
|
-
let to = v;
|
|
4423
|
-
if (stacked) {
|
|
4424
|
-
const acc = v >= 0 ? pos : neg;
|
|
4425
|
-
from = acc[i] ?? 0;
|
|
4426
|
-
to = from + v;
|
|
4427
|
-
acc[i] = to;
|
|
4428
|
-
}
|
|
4429
|
-
const a2 = stacked ? frame.value(from) : base;
|
|
4430
|
-
const b = frame.value(to);
|
|
4431
|
-
const offset = model.horizontal ? geometry.clusterWidth / 2 - barSize - si * geometry.step : -geometry.clusterWidth / 2 + si * geometry.step;
|
|
4432
|
-
const center = frame.band(i);
|
|
4433
|
-
const width = model.horizontal ? Math.abs(b - a2) : barSize;
|
|
4434
|
-
const height = model.horizontal ? barSize : Math.abs(b - a2);
|
|
4435
|
-
let color = s.pointColors?.[i] ?? s.color;
|
|
4436
|
-
const gradient = s.pointGradients?.[i] ?? (s.pointColors?.[i] === void 0 ? s.gradient : void 0);
|
|
4437
|
-
if (gradient && (gradient.path === "circle" || gradient.path === "shape")) {
|
|
4438
|
-
const baseId = color.match(/^url\(#(.+)\)$/)?.[1];
|
|
4439
|
-
if (baseId) {
|
|
4440
|
-
const id = baseId.replace(/(-s\d+(?:-p\d+)?)$/, `-mark${i}$1`);
|
|
4441
|
-
const def = buildChartGradientDef(id, gradient, {
|
|
4442
|
-
width: Number(n(width)),
|
|
4443
|
-
height: Number(n(height)),
|
|
4444
|
-
shape: "rect"
|
|
4445
|
-
});
|
|
4446
|
-
out.push(`<defs>${chartGradientMarkup(def)}</defs>`);
|
|
4447
|
-
color = `url(#${id})`;
|
|
4448
|
-
}
|
|
4449
|
-
}
|
|
4450
|
-
out.push(`<g data-chart-series="${si}" data-chart-point="${i}">`);
|
|
4451
|
-
if (model.horizontal)
|
|
4452
|
-
out.push(
|
|
4453
|
-
rect(Math.min(a2, b), center + offset, Math.abs(b - a2), barSize, color, s.shadowFilter)
|
|
4454
|
-
);
|
|
4455
|
-
else
|
|
4456
|
-
out.push(
|
|
4457
|
-
rect(center + offset, Math.min(a2, b), barSize, Math.abs(b - a2), color, s.shadowFilter)
|
|
4458
|
-
);
|
|
4459
|
-
out.push("</g>");
|
|
4460
|
-
});
|
|
4461
|
-
});
|
|
4462
|
-
}
|
|
4463
|
-
|
|
4464
5983
|
// chart/render/chart-svg-cartesian.ts
|
|
4465
|
-
function
|
|
5984
|
+
function cartesianAxes(model, area, out) {
|
|
4466
5985
|
const scale = model.valueAxis;
|
|
4467
5986
|
if (!scale) return void 0;
|
|
4468
5987
|
const labels = scale.ticks.map((t) => formatAxisValue(t, scale.percent));
|
|
@@ -4481,6 +6000,9 @@ function axes(model, area, out) {
|
|
|
4481
6000
|
area.w * 0.3,
|
|
4482
6001
|
Math.max(...model.categories.map((c2) => textWidth(c2, categorySize)), 8) + 6
|
|
4483
6002
|
);
|
|
6003
|
+
const second = horizontal ? void 0 : model.secondaryAxis;
|
|
6004
|
+
const secondLabels = second?.ticks.map((t) => formatAxisValue(t, second.percent)) ?? [];
|
|
6005
|
+
const secondW = second ? valueLabels ? Math.max(...secondLabels.map((l) => textWidth(l, valueSize)), 8) + 8 : 4 : 0;
|
|
4484
6006
|
const plot = horizontal ? {
|
|
4485
6007
|
x: area.x + catW,
|
|
4486
6008
|
y: area.y,
|
|
@@ -4489,7 +6011,7 @@ function axes(model, area, out) {
|
|
|
4489
6011
|
} : {
|
|
4490
6012
|
x: area.x + labelW,
|
|
4491
6013
|
y: area.y + 4,
|
|
4492
|
-
w: Math.max(1, area.w - labelW - 4),
|
|
6014
|
+
w: Math.max(1, area.w - labelW - 4 - secondW),
|
|
4493
6015
|
h: Math.max(1, area.h - Math.max(20, categorySize * 1.5))
|
|
4494
6016
|
};
|
|
4495
6017
|
const span = scale.max - scale.min || 1;
|
|
@@ -4504,12 +6026,12 @@ function axes(model, area, out) {
|
|
|
4504
6026
|
out.push(line(p, plot.y, p, plot.y + plot.h, grid.color, grid.width));
|
|
4505
6027
|
if (valueLabels)
|
|
4506
6028
|
out.push(
|
|
4507
|
-
|
|
6029
|
+
text2(p, plot.y + plot.h + valueSize + 2, label, { anchor: "middle", ...valueAttrs })
|
|
4508
6030
|
);
|
|
4509
6031
|
} else {
|
|
4510
6032
|
out.push(line(plot.x, p, plot.x + plot.w, p, grid.color, grid.width));
|
|
4511
6033
|
if (valueLabels)
|
|
4512
|
-
out.push(
|
|
6034
|
+
out.push(text2(plot.x - 4, p + valueSize * 0.3, label, { anchor: "end", ...valueAttrs }));
|
|
4513
6035
|
}
|
|
4514
6036
|
});
|
|
4515
6037
|
const zero = value(Math.min(Math.max(0, scale.min), scale.max));
|
|
@@ -4524,20 +6046,45 @@ function axes(model, area, out) {
|
|
|
4524
6046
|
const p = band(i);
|
|
4525
6047
|
if (horizontal)
|
|
4526
6048
|
out.push(
|
|
4527
|
-
|
|
6049
|
+
text2(plot.x - 4, p + categorySize * 0.3, fit(c2, catW - 6, categorySize), {
|
|
4528
6050
|
anchor: "end",
|
|
4529
6051
|
...categoryAttrs
|
|
4530
6052
|
})
|
|
4531
6053
|
);
|
|
4532
6054
|
else
|
|
4533
6055
|
out.push(
|
|
4534
|
-
|
|
6056
|
+
text2(p, plot.y + plot.h + categorySize + 3, fit(c2, bandSize * step, categorySize), {
|
|
4535
6057
|
anchor: "middle",
|
|
4536
6058
|
...categoryAttrs
|
|
4537
6059
|
})
|
|
4538
6060
|
);
|
|
4539
6061
|
});
|
|
4540
|
-
|
|
6062
|
+
const frame = { plot, value, band, bandSize };
|
|
6063
|
+
if (second) {
|
|
6064
|
+
const secondSpan = second.max - second.min || 1;
|
|
6065
|
+
frame.secondary = (v) => plot.y + plot.h - (v - second.min) / secondSpan * plot.h;
|
|
6066
|
+
const secondAxis = chartStroke(model, "valueAxis");
|
|
6067
|
+
out.push(
|
|
6068
|
+
line(
|
|
6069
|
+
plot.x + plot.w,
|
|
6070
|
+
plot.y,
|
|
6071
|
+
plot.x + plot.w,
|
|
6072
|
+
plot.y + plot.h,
|
|
6073
|
+
secondAxis.color,
|
|
6074
|
+
secondAxis.width
|
|
6075
|
+
)
|
|
6076
|
+
);
|
|
6077
|
+
if (valueLabels)
|
|
6078
|
+
second.ticks.forEach(
|
|
6079
|
+
(t, i) => out.push(
|
|
6080
|
+
text2(plot.x + plot.w + 4, frame.secondary(t) + valueSize * 0.3, secondLabels[i] ?? "", {
|
|
6081
|
+
anchor: "start",
|
|
6082
|
+
...valueAttrs
|
|
6083
|
+
})
|
|
6084
|
+
)
|
|
6085
|
+
);
|
|
6086
|
+
}
|
|
6087
|
+
return frame;
|
|
4541
6088
|
}
|
|
4542
6089
|
function plotted(model) {
|
|
4543
6090
|
if (model.grouping !== "percentStacked") return model.series.map((s) => s.values);
|
|
@@ -4580,17 +6127,17 @@ function linesAndAreas(model, frame, out) {
|
|
|
4580
6127
|
out.push(`<polygon points="${poly}" fill="${color}" fill-opacity="0.85"${filter}/>`);
|
|
4581
6128
|
continue;
|
|
4582
6129
|
}
|
|
4583
|
-
let
|
|
6130
|
+
let segment2 = [];
|
|
4584
6131
|
const flush = () => {
|
|
4585
|
-
if (
|
|
6132
|
+
if (segment2.length > 1)
|
|
4586
6133
|
out.push(
|
|
4587
|
-
`<polyline points="${
|
|
6134
|
+
`<polyline points="${segment2.join(" ")}" fill="none" stroke="${color}" stroke-width="2.25" stroke-linejoin="round"${filter}/>`
|
|
4588
6135
|
);
|
|
4589
|
-
|
|
6136
|
+
segment2 = [];
|
|
4590
6137
|
};
|
|
4591
6138
|
for (const [x, y] of points) {
|
|
4592
6139
|
if (Number.isNaN(x)) flush();
|
|
4593
|
-
else
|
|
6140
|
+
else segment2.push(`${n(x)},${n(y)}`);
|
|
4594
6141
|
}
|
|
4595
6142
|
flush();
|
|
4596
6143
|
for (const [x, y] of points)
|
|
@@ -4598,6 +6145,8 @@ function linesAndAreas(model, frame, out) {
|
|
|
4598
6145
|
out.push(`<circle cx="${n(x)}" cy="${n(y)}" r="2.5" fill="${color}"${filter}/>`);
|
|
4599
6146
|
}
|
|
4600
6147
|
}
|
|
6148
|
+
|
|
6149
|
+
// chart/render/chart-svg-xy.ts
|
|
4601
6150
|
function scatter(model, area, out) {
|
|
4602
6151
|
const ys = model.valueAxis;
|
|
4603
6152
|
const xs = model.xAxis;
|
|
@@ -4619,26 +6168,42 @@ function scatter(model, area, out) {
|
|
|
4619
6168
|
w: Math.max(1, area.w - labelW - 8),
|
|
4620
6169
|
h: Math.max(1, area.h - Math.max(20, categorySize * 1.5))
|
|
4621
6170
|
};
|
|
4622
|
-
const
|
|
4623
|
-
const
|
|
6171
|
+
const bubble = model.type === "bubble" ? model.bubble : void 0;
|
|
6172
|
+
const biggest = maxBubbleSize(
|
|
6173
|
+
model.series.flatMap((s) => (s.sizes ?? []).filter((v) => v !== null))
|
|
6174
|
+
);
|
|
6175
|
+
const median = medianBubbleRadius(plot.w, plot.h);
|
|
6176
|
+
const radiusOf = (size) => bubble && !(size !== void 0 && size < 0 && !bubble.showNegativeBubbles) ? computeBubbleRadius(size, biggest, median, bubble) : void 0;
|
|
6177
|
+
let reach = 0;
|
|
6178
|
+
if (bubble)
|
|
6179
|
+
for (const s of model.series)
|
|
6180
|
+
s.values.forEach((_, i) => {
|
|
6181
|
+
reach = Math.max(reach, radiusOf(s.sizes?.[i] ?? void 0) ?? 0);
|
|
6182
|
+
});
|
|
6183
|
+
const widen = (s, length) => {
|
|
6184
|
+
const pad = reach * (s.max - s.min || 1) / Math.max(1, length - 2 * reach);
|
|
6185
|
+
return { ...s, min: s.min - pad, max: s.max + pad };
|
|
6186
|
+
};
|
|
6187
|
+
const xView = widen(xs, plot.w);
|
|
6188
|
+
const yView = widen(ys, plot.h);
|
|
6189
|
+
const px = (v) => plot.x + (v - xView.min) / (xView.max - xView.min || 1) * plot.w;
|
|
6190
|
+
const py = (v) => plot.y + plot.h - (v - yView.min) / (yView.max - yView.min || 1) * plot.h;
|
|
4624
6191
|
out.push(chartAreaRect(model, "plotArea", plot));
|
|
4625
6192
|
ys.ticks.forEach((t, i) => {
|
|
4626
|
-
out.push(line(plot.x, py(t
|
|
6193
|
+
out.push(line(plot.x, py(t), plot.x + plot.w, py(t), grid.color, grid.width));
|
|
4627
6194
|
if (valueLabels)
|
|
4628
6195
|
out.push(
|
|
4629
|
-
|
|
6196
|
+
text2(plot.x - 4, py(t) + valueSize * 0.3, yLabels[i] ?? "", {
|
|
4630
6197
|
anchor: "end",
|
|
4631
6198
|
...valueAttrs
|
|
4632
6199
|
})
|
|
4633
6200
|
);
|
|
4634
6201
|
});
|
|
4635
6202
|
for (const t of xs.ticks) {
|
|
4636
|
-
out.push(
|
|
4637
|
-
line(px(t, xs), plot.y + plot.h, px(t, xs), plot.y + plot.h + 3, xAxis.color, xAxis.width)
|
|
4638
|
-
);
|
|
6203
|
+
out.push(line(px(t), plot.y + plot.h, px(t), plot.y + plot.h + 3, xAxis.color, xAxis.width));
|
|
4639
6204
|
if (categoryLabels)
|
|
4640
6205
|
out.push(
|
|
4641
|
-
|
|
6206
|
+
text2(px(t), plot.y + plot.h + categorySize + 3, formatAxisValue(t), {
|
|
4642
6207
|
anchor: "middle",
|
|
4643
6208
|
...categoryAttrs
|
|
4644
6209
|
})
|
|
@@ -4648,51 +6213,185 @@ function scatter(model, area, out) {
|
|
|
4648
6213
|
line(plot.x, plot.y + plot.h, plot.x + plot.w, plot.y + plot.h, xAxis.color, xAxis.width)
|
|
4649
6214
|
);
|
|
4650
6215
|
out.push(line(plot.x, plot.y, plot.x, plot.y + plot.h, yAxis.color, yAxis.width));
|
|
4651
|
-
for (const s of model.series)
|
|
6216
|
+
for (const [si, s] of model.series.entries())
|
|
4652
6217
|
s.values.forEach((v, i) => {
|
|
4653
6218
|
const x = s.xValues?.[i] ?? null;
|
|
4654
6219
|
if (v === null || x === null) return;
|
|
6220
|
+
const filter = s.shadowFilter ? ` filter="${s.shadowFilter}"` : "";
|
|
6221
|
+
const fill = s.pointColors?.[i] ?? s.color;
|
|
6222
|
+
if (!bubble) {
|
|
6223
|
+
out.push(`<circle cx="${n(px(x))}" cy="${n(py(v))}" r="3" fill="${fill}"${filter}/>`);
|
|
6224
|
+
return;
|
|
6225
|
+
}
|
|
6226
|
+
const r = radiusOf(s.sizes?.[i] ?? void 0);
|
|
6227
|
+
if (r === void 0) return;
|
|
4655
6228
|
out.push(
|
|
4656
|
-
`<circle cx="${n(px(x
|
|
6229
|
+
`<circle cx="${n(px(x))}" cy="${n(py(v))}" r="${n(r)}" fill="${fill}" fill-opacity="0.6" data-chart-series="${si}" data-chart-point="${i}"${filter}/>`
|
|
4657
6230
|
);
|
|
4658
6231
|
});
|
|
6232
|
+
scatterAnalysis(model, px, py, out);
|
|
6233
|
+
}
|
|
6234
|
+
|
|
6235
|
+
// chart/render/chart-svg-stock.ts
|
|
6236
|
+
function stockBars(model, frame, out) {
|
|
6237
|
+
const slots = stockSlots(model.series.length);
|
|
6238
|
+
if (!slots) return;
|
|
6239
|
+
const style = model.stock ?? stockView(void 0, { drawingColor: () => void 0 });
|
|
6240
|
+
const at = (role, i) => role === void 0 ? void 0 : model.series[role]?.values[i];
|
|
6241
|
+
const closeColor = model.series[slots.close]?.color ?? style.wick.color;
|
|
6242
|
+
model.categories.forEach((_, i) => {
|
|
6243
|
+
const candle = stockCandle({
|
|
6244
|
+
x: frame.band(i),
|
|
6245
|
+
band: frame.bandSize,
|
|
6246
|
+
high: at(slots.high, i),
|
|
6247
|
+
low: at(slots.low, i),
|
|
6248
|
+
close: at(slots.close, i),
|
|
6249
|
+
open: at(slots.open, i),
|
|
6250
|
+
hasOpen: slots.open !== void 0,
|
|
6251
|
+
bodyShare: style.bodyShare,
|
|
6252
|
+
y: frame.value
|
|
6253
|
+
});
|
|
6254
|
+
if (!candle) return;
|
|
6255
|
+
out.push(`<g data-chart-series="${slots.close}" data-chart-point="${i}">`);
|
|
6256
|
+
out.push(
|
|
6257
|
+
line(
|
|
6258
|
+
candle.wick.x,
|
|
6259
|
+
candle.wick.y1,
|
|
6260
|
+
candle.wick.x,
|
|
6261
|
+
candle.wick.y2,
|
|
6262
|
+
style.wick.color,
|
|
6263
|
+
style.wick.width
|
|
6264
|
+
)
|
|
6265
|
+
);
|
|
6266
|
+
if (candle.body) {
|
|
6267
|
+
const { x, y, w, h, up } = candle.body;
|
|
6268
|
+
const bar = up ? style.up : style.down;
|
|
6269
|
+
const stroke = bar.stroke === "none" ? "" : ` stroke="${esc(bar.stroke)}" stroke-width="${n(bar.strokeWidth)}"`;
|
|
6270
|
+
out.push(rect(x, y, w, h, bar.fill).replace("/>", `${stroke}/>`));
|
|
6271
|
+
} else if (candle.tick) {
|
|
6272
|
+
out.push(
|
|
6273
|
+
line(
|
|
6274
|
+
candle.tick.x1,
|
|
6275
|
+
candle.tick.y,
|
|
6276
|
+
candle.tick.x2,
|
|
6277
|
+
candle.tick.y,
|
|
6278
|
+
closeColor,
|
|
6279
|
+
STOCK_TICK_WIDTH
|
|
6280
|
+
)
|
|
6281
|
+
);
|
|
6282
|
+
}
|
|
6283
|
+
out.push("</g>");
|
|
6284
|
+
});
|
|
6285
|
+
}
|
|
6286
|
+
|
|
6287
|
+
// chart/render/chart-svg-waterfall.ts
|
|
6288
|
+
var CONNECTOR_COLOR = "#7F7F7F";
|
|
6289
|
+
var BAR_SHARE = 2 / 3;
|
|
6290
|
+
function waterfallBars(model, frame, out) {
|
|
6291
|
+
const view = model.waterfall;
|
|
6292
|
+
if (!view) return;
|
|
6293
|
+
const width = frame.bandSize * BAR_SHARE;
|
|
6294
|
+
view.steps.forEach((step, i) => {
|
|
6295
|
+
const a2 = frame.value(step.startValue);
|
|
6296
|
+
const b = frame.value(step.endValue);
|
|
6297
|
+
const color = step.isSubtotal ? view.colors.total : step.value >= 0 ? view.colors.increase : view.colors.decrease;
|
|
6298
|
+
const x = frame.band(i) - width / 2;
|
|
6299
|
+
out.push(`<g data-chart-series="0" data-chart-point="${step.sourceIndex}">`);
|
|
6300
|
+
out.push(rect(x, Math.min(a2, b), width, Math.max(Math.abs(b - a2), 1), color));
|
|
6301
|
+
out.push("</g>");
|
|
6302
|
+
const next = view.steps[i + 1];
|
|
6303
|
+
if (view.connectors && next) {
|
|
6304
|
+
const xNext = frame.band(i + 1) - width / 2;
|
|
6305
|
+
out.push(
|
|
6306
|
+
line(x + width, b, xNext, b, CONNECTOR_COLOR, 0.75).replace(
|
|
6307
|
+
"/>",
|
|
6308
|
+
` stroke-dasharray="${n(3)} ${n(2)}"/>`
|
|
6309
|
+
)
|
|
6310
|
+
);
|
|
6311
|
+
}
|
|
6312
|
+
});
|
|
6313
|
+
}
|
|
6314
|
+
|
|
6315
|
+
// chart/render/chart-svg-plots.ts
|
|
6316
|
+
var RANK = {
|
|
6317
|
+
area: 0,
|
|
6318
|
+
bar: 1,
|
|
6319
|
+
column: 1,
|
|
6320
|
+
histogram: 1,
|
|
6321
|
+
line: 2,
|
|
6322
|
+
stock: 2
|
|
6323
|
+
};
|
|
6324
|
+
function paint(layer, out) {
|
|
6325
|
+
const { model, frame } = layer;
|
|
6326
|
+
if (model.type === "stock") stockBars(model, frame, out);
|
|
6327
|
+
else if (model.type === "bar" || model.type === "column" || model.type === "histogram")
|
|
6328
|
+
bars(model, frame, out, plotted(model));
|
|
6329
|
+
else linesAndAreas(model, frame, out);
|
|
4659
6330
|
}
|
|
4660
6331
|
function cartesianSvg(model, area) {
|
|
4661
6332
|
const out = [];
|
|
4662
|
-
if (model.type === "scatter") {
|
|
6333
|
+
if (model.type === "scatter" || model.type === "bubble") {
|
|
4663
6334
|
scatter(model, area, out);
|
|
4664
6335
|
return out.join("");
|
|
4665
6336
|
}
|
|
4666
|
-
const frame =
|
|
6337
|
+
const frame = cartesianAxes(model, area, out);
|
|
4667
6338
|
if (!frame) return "";
|
|
4668
|
-
if (model.type === "
|
|
4669
|
-
|
|
6339
|
+
if (model.type === "waterfall") {
|
|
6340
|
+
waterfallBars(model, frame, out);
|
|
6341
|
+
return out.join("");
|
|
6342
|
+
}
|
|
6343
|
+
if (model.type === "stock") {
|
|
6344
|
+
stockBars(model, frame, out);
|
|
6345
|
+
return out.join("");
|
|
6346
|
+
}
|
|
6347
|
+
const layers = [{ model, frame }];
|
|
6348
|
+
for (const group2 of model.extraGroups ?? []) {
|
|
6349
|
+
const grouped = {
|
|
6350
|
+
...model,
|
|
6351
|
+
type: group2.type,
|
|
6352
|
+
grouping: group2.grouping,
|
|
6353
|
+
series: group2.series,
|
|
6354
|
+
horizontal: false
|
|
6355
|
+
};
|
|
6356
|
+
if (group2.stock) grouped.stock = group2.stock;
|
|
6357
|
+
else delete grouped.stock;
|
|
6358
|
+
if (group2.barGapWidth !== void 0) grouped.barGapWidth = group2.barGapWidth;
|
|
6359
|
+
else delete grouped.barGapWidth;
|
|
6360
|
+
if (group2.barOverlap !== void 0) grouped.barOverlap = group2.barOverlap;
|
|
6361
|
+
else delete grouped.barOverlap;
|
|
6362
|
+
const value = group2.secondary && frame.secondary ? frame.secondary : frame.value;
|
|
6363
|
+
layers.push({ model: grouped, frame: { ...frame, value } });
|
|
6364
|
+
}
|
|
6365
|
+
layers.map((layer, order) => ({ layer, order })).sort(
|
|
6366
|
+
(a2, b) => (RANK[a2.layer.model.type] ?? 1) - (RANK[b.layer.model.type] ?? 1) || a2.order - b.order
|
|
6367
|
+
).forEach(({ layer }) => paint(layer, out));
|
|
6368
|
+
categoryAnalysis(model, frame, out);
|
|
4670
6369
|
return out.join("");
|
|
4671
6370
|
}
|
|
4672
6371
|
|
|
4673
6372
|
// chart/render/chart-svg-radial.ts
|
|
4674
|
-
var polar = (
|
|
4675
|
-
|
|
6373
|
+
var polar = (cx2, cy, r, angle) => [
|
|
6374
|
+
cx2 + r * Math.sin(angle),
|
|
4676
6375
|
cy - r * Math.cos(angle)
|
|
4677
6376
|
];
|
|
4678
|
-
function slicePath(
|
|
6377
|
+
function slicePath(cx2, cy, r, inner, a0, a1) {
|
|
4679
6378
|
const sweep = a1 - a0;
|
|
4680
6379
|
if (sweep >= Math.PI * 2 - 1e-9) {
|
|
4681
6380
|
const mid = a0 + Math.PI;
|
|
4682
|
-
return slicePath(
|
|
6381
|
+
return slicePath(cx2, cy, r, inner, a0, mid) + slicePath(cx2, cy, r, inner, mid, a1);
|
|
4683
6382
|
}
|
|
4684
6383
|
const large = sweep > Math.PI ? 1 : 0;
|
|
4685
|
-
const [x0, y0] = polar(
|
|
4686
|
-
const [x1, y1] = polar(
|
|
6384
|
+
const [x0, y0] = polar(cx2, cy, r, a0);
|
|
6385
|
+
const [x1, y1] = polar(cx2, cy, r, a1);
|
|
4687
6386
|
if (inner <= 0)
|
|
4688
|
-
return `M${n(
|
|
4689
|
-
const [ix1, iy1] = polar(
|
|
4690
|
-
const [ix0, iy0] = polar(
|
|
6387
|
+
return `M${n(cx2)},${n(cy)} L${n(x0)},${n(y0)} A${n(r)},${n(r)} 0 ${large} 1 ${n(x1)},${n(y1)} Z`;
|
|
6388
|
+
const [ix1, iy1] = polar(cx2, cy, inner, a1);
|
|
6389
|
+
const [ix0, iy0] = polar(cx2, cy, inner, a0);
|
|
4691
6390
|
return `M${n(x0)},${n(y0)} A${n(r)},${n(r)} 0 ${large} 1 ${n(x1)},${n(y1)} L${n(ix1)},${n(iy1)} A${n(inner)},${n(inner)} 0 ${large} 0 ${n(ix0)},${n(iy0)} Z`;
|
|
4692
6391
|
}
|
|
4693
6392
|
function pieSvg(model, area) {
|
|
4694
6393
|
const out = [chartAreaRect(model, "plotArea", area)];
|
|
4695
|
-
const
|
|
6394
|
+
const cx2 = area.x + area.w / 2;
|
|
4696
6395
|
const cy = area.y + area.h / 2;
|
|
4697
6396
|
const radius = Math.max(1, Math.min(area.w, area.h) / 2 - 4);
|
|
4698
6397
|
const rings = model.type === "doughnut" ? model.series : model.series.slice(0, 1);
|
|
@@ -4709,7 +6408,7 @@ function pieSvg(model, area) {
|
|
|
4709
6408
|
const sweep = v / total * Math.PI * 2;
|
|
4710
6409
|
const color = s.pointColors?.[i] ?? s.color;
|
|
4711
6410
|
out.push(
|
|
4712
|
-
`<path d="${slicePath(
|
|
6411
|
+
`<path d="${slicePath(cx2, cy, outer, inner, angle, angle + sweep)}" fill="${color}" stroke="#FFFFFF" stroke-width="1"${s.shadowFilter ? ` filter="${s.shadowFilter}"` : ""}/>`
|
|
4713
6412
|
);
|
|
4714
6413
|
angle += sweep;
|
|
4715
6414
|
});
|
|
@@ -4727,7 +6426,7 @@ function radarSvg(model, area) {
|
|
|
4727
6426
|
const categorySize = categoryAttrs.size ?? 10;
|
|
4728
6427
|
const grid = chartStroke(model, "gridlineMajor");
|
|
4729
6428
|
const axis = chartStroke(model, "categoryAxis");
|
|
4730
|
-
const
|
|
6429
|
+
const cx2 = area.x + area.w / 2;
|
|
4731
6430
|
const cy = area.y + area.h / 2 + 4;
|
|
4732
6431
|
const radius = Math.max(1, Math.min(area.w, area.h) / 2 - Math.max(18, categorySize * 1.8));
|
|
4733
6432
|
const angle = (i) => i / count * Math.PI * 2;
|
|
@@ -4737,30 +6436,30 @@ function radarSvg(model, area) {
|
|
|
4737
6436
|
Math.ceil(12 / Math.max(1, radius / Math.max(1, scale.ticks.length - 1)))
|
|
4738
6437
|
);
|
|
4739
6438
|
for (const [k, t] of scale.ticks.entries()) {
|
|
4740
|
-
const ring = Array.from({ length: count }, (_, i) => polar(
|
|
6439
|
+
const ring = Array.from({ length: count }, (_, i) => polar(cx2, cy, r(t), angle(i))).map(([x, y]) => `${n(x)},${n(y)}`).join(" ");
|
|
4741
6440
|
out.push(
|
|
4742
6441
|
`<polygon points="${ring}" fill="none" stroke="${grid.color}" stroke-width="${n(grid.width)}"/>`
|
|
4743
6442
|
);
|
|
4744
6443
|
if (model.appearance?.valueAxis?.labelsVisible !== false && k % labelEvery === 0)
|
|
4745
6444
|
out.push(
|
|
4746
|
-
|
|
6445
|
+
text2(cx2 + 3, cy - r(t) + valueSize * 0.3, formatAxisValue(t, scale.percent), valueAttrs)
|
|
4747
6446
|
);
|
|
4748
6447
|
}
|
|
4749
6448
|
model.categories.forEach((c2, i) => {
|
|
4750
|
-
const [x, y] = polar(
|
|
4751
|
-
out.push(line(
|
|
4752
|
-
const [lx, ly] = polar(
|
|
4753
|
-
const anchor = Math.abs(lx -
|
|
6449
|
+
const [x, y] = polar(cx2, cy, radius, angle(i));
|
|
6450
|
+
out.push(line(cx2, cy, x, y, axis.color, axis.width));
|
|
6451
|
+
const [lx, ly] = polar(cx2, cy, radius + 10, angle(i));
|
|
6452
|
+
const anchor = Math.abs(lx - cx2) < 2 ? "middle" : lx > cx2 ? "start" : "end";
|
|
4754
6453
|
if (model.appearance?.categoryAxis?.labelsVisible !== false)
|
|
4755
6454
|
out.push(
|
|
4756
|
-
|
|
6455
|
+
text2(lx, ly + categorySize * 0.3, fit(c2, area.w / 4, categorySize), {
|
|
4757
6456
|
anchor,
|
|
4758
6457
|
...categoryAttrs
|
|
4759
6458
|
})
|
|
4760
6459
|
);
|
|
4761
6460
|
});
|
|
4762
6461
|
for (const s of model.series) {
|
|
4763
|
-
const points = s.values.slice(0, count).map((v, i) => polar(
|
|
6462
|
+
const points = s.values.slice(0, count).map((v, i) => polar(cx2, cy, r(v ?? scale.min), angle(i))).map(([x, y]) => `${n(x)},${n(y)}`).join(" ");
|
|
4764
6463
|
out.push(
|
|
4765
6464
|
`<polygon points="${points}" fill="none" stroke="${s.color}" stroke-width="2"${s.shadowFilter ? ` filter="${s.shadowFilter}"` : ""}/>`
|
|
4766
6465
|
);
|
|
@@ -4768,6 +6467,88 @@ function radarSvg(model, area) {
|
|
|
4768
6467
|
return out.join("");
|
|
4769
6468
|
}
|
|
4770
6469
|
|
|
6470
|
+
// chart/render/chart-svg-hierarchy.ts
|
|
6471
|
+
var colorAt2 = (model, index) => {
|
|
6472
|
+
const first2 = model.series[0];
|
|
6473
|
+
const colors = first2?.pointColors;
|
|
6474
|
+
return (colors && colors.length > 0 ? colors[index % colors.length] : void 0) ?? first2?.color ?? "#4472C4";
|
|
6475
|
+
};
|
|
6476
|
+
var leafValues = (model) => (model.series[0]?.values ?? []).map((v) => v ?? 0);
|
|
6477
|
+
function treemapSvg(model, area) {
|
|
6478
|
+
const out = [chartAreaRect(model, "plotArea", area)];
|
|
6479
|
+
const hierarchy = model.hierarchy;
|
|
6480
|
+
const series = model.series.map((s) => ({
|
|
6481
|
+
name: s.name,
|
|
6482
|
+
values: s.values.map((v) => v ?? 0),
|
|
6483
|
+
// Without data labels Office draws no parent banners either, so no space is reserved.
|
|
6484
|
+
parentLabelLayout: hierarchy?.labels === false ? "none" : hierarchy?.parentLabelLayout
|
|
6485
|
+
}));
|
|
6486
|
+
const roots = buildHierarchyRoots(
|
|
6487
|
+
series,
|
|
6488
|
+
model.categories,
|
|
6489
|
+
hierarchy && hierarchy.levels.length > 1 ? hierarchy.levels : void 0
|
|
6490
|
+
);
|
|
6491
|
+
const cells = layoutTreemap(roots, { x: area.x, y: area.y, w: area.w, h: area.h });
|
|
6492
|
+
for (const cell of cells) {
|
|
6493
|
+
if (cell.kind === "parent") {
|
|
6494
|
+
if (hierarchy?.labels !== false)
|
|
6495
|
+
out.push(text2(cell.x, cell.y, cell.label, { size: 10, weight: "bold", fill: "#303030" }));
|
|
6496
|
+
continue;
|
|
6497
|
+
}
|
|
6498
|
+
out.push(`<g data-chart-series="${cell.seriesIndex}" data-chart-point="${cell.pointIndex}">`);
|
|
6499
|
+
out.push(
|
|
6500
|
+
rect(cell.x, cell.y, cell.w, cell.h, colorAt2(model, cell.colorIndex)).replace(
|
|
6501
|
+
"/>",
|
|
6502
|
+
' rx="2"/>'
|
|
6503
|
+
)
|
|
6504
|
+
);
|
|
6505
|
+
if (cell.labelFits && hierarchy?.labels !== false)
|
|
6506
|
+
out.push(
|
|
6507
|
+
text2(
|
|
6508
|
+
cell.x + cell.w / 2,
|
|
6509
|
+
cell.y + cell.h / 2,
|
|
6510
|
+
fit(cell.label, cell.w - 4, cell.labelSize),
|
|
6511
|
+
{
|
|
6512
|
+
anchor: "middle",
|
|
6513
|
+
size: cell.labelSize,
|
|
6514
|
+
weight: "bold",
|
|
6515
|
+
fill: "#FFFFFF",
|
|
6516
|
+
baseline: "central"
|
|
6517
|
+
}
|
|
6518
|
+
)
|
|
6519
|
+
);
|
|
6520
|
+
out.push("</g>");
|
|
6521
|
+
}
|
|
6522
|
+
return out.join("");
|
|
6523
|
+
}
|
|
6524
|
+
function sunburstSvg(model, area) {
|
|
6525
|
+
const out = [chartAreaRect(model, "plotArea", area)];
|
|
6526
|
+
const cx2 = area.x + area.w / 2;
|
|
6527
|
+
const cy = area.y + area.h / 2;
|
|
6528
|
+
const maxR = Math.min(area.w, area.h) / 2 - 4;
|
|
6529
|
+
if (maxR <= 0) return out.join("");
|
|
6530
|
+
const levels = model.hierarchy?.levels ?? [];
|
|
6531
|
+
const arcs = levels.length > 1 ? computeHierarchicalSunburstArcs(levels, leafValues(model), cx2, cy, maxR) : computeSunburstArcs(
|
|
6532
|
+
model.series.map((s) => ({ values: s.values.map((v) => v ?? 0) })),
|
|
6533
|
+
cx2,
|
|
6534
|
+
cy,
|
|
6535
|
+
maxR
|
|
6536
|
+
);
|
|
6537
|
+
for (const arc of arcs)
|
|
6538
|
+
out.push(
|
|
6539
|
+
`<path d="${arc.d}" fill="${colorAt2(model, arc.colorIndex)}" stroke="#FFFFFF" stroke-width="1.5"${arc.pointIndex === void 0 ? "" : ` data-chart-series="0" data-chart-point="${arc.pointIndex}"`}/>`
|
|
6540
|
+
);
|
|
6541
|
+
const flatLabels = levels.length > 1 || model.series.length !== 1 ? void 0 : model.categories;
|
|
6542
|
+
for (const arc of model.hierarchy?.labels === false ? [] : arcs) {
|
|
6543
|
+
const label = arc.label ?? (arc.pointIndex === void 0 ? void 0 : flatLabels?.[arc.pointIndex]);
|
|
6544
|
+
if (!label) continue;
|
|
6545
|
+
out.push(
|
|
6546
|
+
`<text x="${n(arc.labelX)}" y="${n(arc.labelY)}" font-size="10" fill="#FFFFFF" text-anchor="middle" dominant-baseline="central" transform="rotate(${n(arc.labelRotation)}, ${n(arc.labelX)}, ${n(arc.labelY)})">${esc(label)}</text>`
|
|
6547
|
+
);
|
|
6548
|
+
}
|
|
6549
|
+
return out.join("");
|
|
6550
|
+
}
|
|
6551
|
+
|
|
4771
6552
|
// chart/render/chart-svg-text-metrics.ts
|
|
4772
6553
|
var CHART_FONT_FAMILY = "Calibri, Carlito, Arial, sans-serif";
|
|
4773
6554
|
function cssFont(attrs) {
|
|
@@ -4841,7 +6622,7 @@ function chartLegendSvg(model, area, frame, options) {
|
|
|
4841
6622
|
const x = horizontal ? horizontalX : manual.x + Math.max(size / 4, (rowWidth - contentWidth) / 2);
|
|
4842
6623
|
const centerY = manual.y + (horizontal ? 0 : i * rowHeight) + rowHeight / 2;
|
|
4843
6624
|
markup.push(rect(x, centerY - keySize / 2, keySize, keySize, entry3.color));
|
|
4844
|
-
markup.push(
|
|
6625
|
+
markup.push(text2(x + keySize + keyGap, centerY + baselineOffset, label, attrs));
|
|
4845
6626
|
if (horizontal) horizontalX += (widths[i] ?? 0) + horizontalGap;
|
|
4846
6627
|
});
|
|
4847
6628
|
return {
|
|
@@ -4858,7 +6639,23 @@ function legendEntries(model) {
|
|
|
4858
6639
|
color: first2?.pointColors?.[i] ?? first2?.color ?? "#4472C4"
|
|
4859
6640
|
}));
|
|
4860
6641
|
}
|
|
4861
|
-
|
|
6642
|
+
if ((model.type === "treemap" || model.type === "sunburst") && model.hierarchy) {
|
|
6643
|
+
const first2 = model.series[0];
|
|
6644
|
+
return model.hierarchy.branches.map((label, i) => ({
|
|
6645
|
+
label,
|
|
6646
|
+
color: first2?.pointColors?.[i % Math.max(1, first2.pointColors.length)] ?? first2?.color ?? "#4472C4"
|
|
6647
|
+
}));
|
|
6648
|
+
}
|
|
6649
|
+
if (model.type === "waterfall" && model.waterfall)
|
|
6650
|
+
return [
|
|
6651
|
+
{ label: "Increase", color: model.waterfall.colors.increase },
|
|
6652
|
+
{ label: "Decrease", color: model.waterfall.colors.decrease },
|
|
6653
|
+
{ label: "Total", color: model.waterfall.colors.total }
|
|
6654
|
+
];
|
|
6655
|
+
return [...model.series, ...(model.extraGroups ?? []).flatMap((g) => g.series)].map((s) => ({
|
|
6656
|
+
label: s.name,
|
|
6657
|
+
color: s.color
|
|
6658
|
+
}));
|
|
4862
6659
|
}
|
|
4863
6660
|
function automaticLegend(model, area, out, options, bounds) {
|
|
4864
6661
|
const entries = legendEntries(model);
|
|
@@ -4886,7 +6683,7 @@ function automaticLegend(model, area, out, options, bounds) {
|
|
|
4886
6683
|
entries.forEach((e, i) => {
|
|
4887
6684
|
const w = widths[i] ?? 0;
|
|
4888
6685
|
out.push(rect(x2, y, 8, 8, e.color));
|
|
4889
|
-
out.push(
|
|
6686
|
+
out.push(text2(x2 + 12, y + 8, fitChartText(e.label, w - 16, attrs, options), attrs));
|
|
4890
6687
|
x2 += w;
|
|
4891
6688
|
});
|
|
4892
6689
|
return pos === "t" ? { x: area.x, y: area.y + rowH + 4, w: area.w, h: area.h - rowH - 4 } : { x: area.x, y: area.y, w: area.w, h: area.h - rowH - 4 };
|
|
@@ -4911,7 +6708,7 @@ function automaticLegend(model, area, out, options, bounds) {
|
|
|
4911
6708
|
const y = y0 + i * rowH;
|
|
4912
6709
|
if (y + rowH > area.y + area.h + 2) return;
|
|
4913
6710
|
out.push(rect(x, y + 3, 8, 8, e.color));
|
|
4914
|
-
out.push(
|
|
6711
|
+
out.push(text2(x + 12, y + 11, fitChartText(e.label, width - 16, attrs, options), attrs));
|
|
4915
6712
|
});
|
|
4916
6713
|
return pos === "l" ? { x: area.x + width + 8, y: area.y, w: area.w - width - 8, h: area.h } : { x: area.x, y: area.y, w: area.w - width - 8, h: area.h };
|
|
4917
6714
|
}
|
|
@@ -4923,12 +6720,12 @@ function wrapStyledRuns(runs, maxWidth, measure, options = {}) {
|
|
|
4923
6720
|
for (const [source, run2] of runs.entries()) {
|
|
4924
6721
|
for (const token of run2.text.split(/(\r\n|[\r\n]|[ \t]+)/u).filter(Boolean)) {
|
|
4925
6722
|
const kind = /^[\r\n]+$/u.test(token) ? "break" : /^[ \t]+$/u.test(token) ? "space" : "word";
|
|
4926
|
-
let
|
|
4927
|
-
if (!
|
|
4928
|
-
|
|
4929
|
-
groups.push(
|
|
6723
|
+
let group2 = groups.at(-1);
|
|
6724
|
+
if (!group2 || group2.kind !== kind || kind === "break") {
|
|
6725
|
+
group2 = { kind, pieces: [] };
|
|
6726
|
+
groups.push(group2);
|
|
4930
6727
|
}
|
|
4931
|
-
if (kind !== "break")
|
|
6728
|
+
if (kind !== "break") group2.pieces.push({ run: run2, source, text: token });
|
|
4932
6729
|
}
|
|
4933
6730
|
}
|
|
4934
6731
|
const merged = (left, right) => {
|
|
@@ -4952,29 +6749,29 @@ function wrapStyledRuns(runs, maxWidth, measure, options = {}) {
|
|
|
4952
6749
|
line2 = [];
|
|
4953
6750
|
spaces = [];
|
|
4954
6751
|
};
|
|
4955
|
-
for (const
|
|
4956
|
-
if (
|
|
6752
|
+
for (const group2 of groups) {
|
|
6753
|
+
if (group2.kind === "break") {
|
|
4957
6754
|
flush();
|
|
4958
6755
|
continue;
|
|
4959
6756
|
}
|
|
4960
|
-
if (
|
|
4961
|
-
spaces =
|
|
6757
|
+
if (group2.kind === "space") {
|
|
6758
|
+
spaces = group2.pieces;
|
|
4962
6759
|
continue;
|
|
4963
6760
|
}
|
|
4964
6761
|
const separator = line2.length ? spaces : [];
|
|
4965
|
-
const wordWidth = width(
|
|
4966
|
-
if (line2.length && width(merged(line2, [...separator, ...
|
|
6762
|
+
const wordWidth = width(group2.pieces);
|
|
6763
|
+
if (line2.length && width(merged(line2, [...separator, ...group2.pieces])) > maxWidth) flush();
|
|
4967
6764
|
else line2 = merged(line2, separator);
|
|
4968
6765
|
spaces = [];
|
|
4969
6766
|
if (options.breakWords && wordWidth > maxWidth) {
|
|
4970
|
-
for (const piece of
|
|
4971
|
-
for (const { segment } of graphemes.segment(piece.text)) {
|
|
4972
|
-
const next = { ...piece, text:
|
|
6767
|
+
for (const piece of group2.pieces) {
|
|
6768
|
+
for (const { segment: segment2 } of graphemes.segment(piece.text)) {
|
|
6769
|
+
const next = { ...piece, text: segment2 };
|
|
4973
6770
|
if (line2.length && width(merged(line2, [next])) > maxWidth) flush();
|
|
4974
6771
|
line2 = merged(line2, [next]);
|
|
4975
6772
|
}
|
|
4976
6773
|
}
|
|
4977
|
-
} else line2 = merged(line2,
|
|
6774
|
+
} else line2 = merged(line2, group2.pieces);
|
|
4978
6775
|
}
|
|
4979
6776
|
flush();
|
|
4980
6777
|
return result;
|
|
@@ -5084,7 +6881,7 @@ function chartRichTitleSvg(model, width, options = {}, frameHeight = 400) {
|
|
|
5084
6881
|
let x = line2.align === "l" ? (width - boxWidth) / 2 + 4 : line2.align === "r" ? (width + boxWidth) / 2 - 4 - line2.width : (width - line2.width) / 2;
|
|
5085
6882
|
for (const run2 of line2.runs) {
|
|
5086
6883
|
spans.push(
|
|
5087
|
-
|
|
6884
|
+
text2(x, baseline, run2.text, {
|
|
5088
6885
|
...run2.attrs,
|
|
5089
6886
|
anchor: "start"
|
|
5090
6887
|
}).replace("<text ", '<tspan data-chart-title-run="true" ').replace("</text>", "</tspan>")
|
|
@@ -5092,7 +6889,7 @@ function chartRichTitleSvg(model, width, options = {}, frameHeight = 400) {
|
|
|
5092
6889
|
x += chartTextWidth(run2.text, run2.attrs, options);
|
|
5093
6890
|
}
|
|
5094
6891
|
}
|
|
5095
|
-
const parent =
|
|
6892
|
+
const parent = text2(0, 0, "", { ...base, underline: false }).replace(
|
|
5096
6893
|
"</text>",
|
|
5097
6894
|
`${spans.join("")}</text>`
|
|
5098
6895
|
);
|
|
@@ -5116,8 +6913,8 @@ function chartRichTitleSvg(model, width, options = {}, frameHeight = 400) {
|
|
|
5116
6913
|
|
|
5117
6914
|
// chart/render/chart-svg.ts
|
|
5118
6915
|
function renderChartSvg(model, width, height, options = {}) {
|
|
5119
|
-
const
|
|
5120
|
-
model =
|
|
6916
|
+
const paint2 = chartGradientPaint(model, Math.max(1, width), Math.max(1, height));
|
|
6917
|
+
model = paint2.model;
|
|
5121
6918
|
const w = Math.max(1, width);
|
|
5122
6919
|
const h = Math.max(1, height);
|
|
5123
6920
|
const out = [];
|
|
@@ -5126,7 +6923,7 @@ function renderChartSvg(model, width, height, options = {}) {
|
|
|
5126
6923
|
`<svg xmlns="http://www.w3.org/2000/svg" width="${n(w)}" height="${n(h)}" viewBox="0 0 ${n(w)} ${n(h)}" font-family="${esc(CHART_FONT_FAMILY)}" role="img">`
|
|
5127
6924
|
);
|
|
5128
6925
|
if (model.title) out.push(`<title>${esc(model.title)}</title>`);
|
|
5129
|
-
if (
|
|
6926
|
+
if (paint2.defs) out.push(paint2.defs);
|
|
5130
6927
|
out.push(chartAreaRect(model, "chartArea", { x: 0, y: 0, w, h }));
|
|
5131
6928
|
let area = { x: 8, y: 8, w: w - 16, h: h - 16 };
|
|
5132
6929
|
const richTitle = chartRichTitleSvg(model, w, options, h);
|
|
@@ -5151,7 +6948,7 @@ function renderChartSvg(model, width, height, options = {}) {
|
|
|
5151
6948
|
})
|
|
5152
6949
|
);
|
|
5153
6950
|
out.push(
|
|
5154
|
-
|
|
6951
|
+
text2(w / 2, 8 + size, label, {
|
|
5155
6952
|
anchor: "middle",
|
|
5156
6953
|
fill: "#404040",
|
|
5157
6954
|
...attrs
|
|
@@ -5162,7 +6959,7 @@ function renderChartSvg(model, width, height, options = {}) {
|
|
|
5162
6959
|
}
|
|
5163
6960
|
if (!model.supported) {
|
|
5164
6961
|
out.push(
|
|
5165
|
-
|
|
6962
|
+
text2(w / 2, area.y + area.h / 2, `${model.type} charts are not drawn`, { anchor: "middle" })
|
|
5166
6963
|
);
|
|
5167
6964
|
if (foregroundTitle) out.push(foregroundTitle);
|
|
5168
6965
|
out.push("</svg>");
|
|
@@ -5174,6 +6971,8 @@ function renderChartSvg(model, width, height, options = {}) {
|
|
|
5174
6971
|
if (area.w > 4 && area.h > 4) {
|
|
5175
6972
|
if (model.type === "pie" || model.type === "doughnut") out.push(pieSvg(model, area));
|
|
5176
6973
|
else if (model.type === "radar") out.push(radarSvg(model, area));
|
|
6974
|
+
else if (model.type === "treemap") out.push(treemapSvg(model, area));
|
|
6975
|
+
else if (model.type === "sunburst") out.push(sunburstSvg(model, area));
|
|
5177
6976
|
else out.push(cartesianSvg(model, area));
|
|
5178
6977
|
}
|
|
5179
6978
|
if (legend.foreground) out.push(legend.markup);
|
|
@@ -5191,7 +6990,13 @@ var DRAWN_CHART_TYPES = /* @__PURE__ */ new Set([
|
|
|
5191
6990
|
"pie",
|
|
5192
6991
|
"doughnut",
|
|
5193
6992
|
"scatter",
|
|
5194
|
-
"radar"
|
|
6993
|
+
"radar",
|
|
6994
|
+
"waterfall",
|
|
6995
|
+
"histogram",
|
|
6996
|
+
"bubble",
|
|
6997
|
+
"stock",
|
|
6998
|
+
"treemap",
|
|
6999
|
+
"sunburst"
|
|
5195
7000
|
]);
|
|
5196
7001
|
function chartThemePalette(theme, fonts = {}) {
|
|
5197
7002
|
return {
|
|
@@ -5217,26 +7022,43 @@ function renderChartSpaceSvg(space, options) {
|
|
|
5217
7022
|
const view = chartSummaryView(summary, chartThemePalette(theme, fonts));
|
|
5218
7023
|
return renderChartSvg(view, width, height, svg);
|
|
5219
7024
|
}
|
|
7025
|
+
function renderChartSummarySvg(summary, options) {
|
|
7026
|
+
const { width, height, theme, fonts, ...svg } = options;
|
|
7027
|
+
const view = chartSummaryView(summary, chartThemePalette(theme, fonts));
|
|
7028
|
+
return renderChartSvg(view, width, height, svg);
|
|
7029
|
+
}
|
|
5220
7030
|
|
|
5221
7031
|
exports.BEST_FIT_EDGE_TOLERANCE = BEST_FIT_EDGE_TOLERANCE;
|
|
5222
7032
|
exports.BEST_FIT_OUTSIDE_GAP = BEST_FIT_OUTSIDE_GAP;
|
|
5223
7033
|
exports.BEST_FIT_RIM_INSET = BEST_FIT_RIM_INSET;
|
|
7034
|
+
exports.CHART_AUTO_TITLE = CHART_AUTO_TITLE;
|
|
5224
7035
|
exports.CHART_COLOR_PALETTES = CHART_COLOR_PALETTES;
|
|
5225
7036
|
exports.CHART_COLOR_STYLE_CONTENT_TYPE = CHART_COLOR_STYLE_CONTENT_TYPE;
|
|
5226
7037
|
exports.CHART_COLOR_STYLE_NS = CHART_COLOR_STYLE_NS;
|
|
5227
7038
|
exports.CHART_COLOR_STYLE_REL = CHART_COLOR_STYLE_REL;
|
|
7039
|
+
exports.CHART_ERROR_BAR_DIRECTIONS = CHART_ERROR_BAR_DIRECTIONS;
|
|
7040
|
+
exports.CHART_ERROR_BAR_TYPES = CHART_ERROR_BAR_TYPES;
|
|
7041
|
+
exports.CHART_ERROR_VALUE_TYPES = CHART_ERROR_VALUE_TYPES;
|
|
5228
7042
|
exports.CHART_GROUP_ELEMENTS = CHART_GROUP_ELEMENTS;
|
|
5229
7043
|
exports.CHART_STYLE_PARTS = CHART_STYLE_PARTS;
|
|
5230
7044
|
exports.DEFAULT_BAR_GAP_WIDTH = DEFAULT_BAR_GAP_WIDTH;
|
|
7045
|
+
exports.DEFAULT_CHART_PALETTE = DEFAULT_CHART_PALETTE;
|
|
5231
7046
|
exports.DEFAULT_THEME_COLORS = DEFAULT_THEME_COLORS;
|
|
5232
7047
|
exports.DRAWN_CHART_TYPES = DRAWN_CHART_TYPES;
|
|
5233
7048
|
exports.LABEL_COLLISION_GAP = LABEL_COLLISION_GAP;
|
|
7049
|
+
exports.STOCK_DEFAULT_DOWN_FILL = STOCK_DEFAULT_DOWN_FILL;
|
|
7050
|
+
exports.STOCK_DEFAULT_UP_FILL = STOCK_DEFAULT_UP_FILL;
|
|
7051
|
+
exports.STOCK_DEFAULT_WICK_COLOR = STOCK_DEFAULT_WICK_COLOR;
|
|
7052
|
+
exports.STOCK_TICK_WIDTH = STOCK_TICK_WIDTH;
|
|
5234
7053
|
exports.THEME_SLOTS = THEME_SLOTS;
|
|
7054
|
+
exports.aggregate = aggregate;
|
|
5235
7055
|
exports.aggregateByCategory = aggregateByCategory;
|
|
5236
7056
|
exports.assertBarClusterOptions = assertBarClusterOptions;
|
|
5237
7057
|
exports.autoSeriesColor = autoSeriesColor;
|
|
5238
7058
|
exports.axisTargetIntervals = axisTargetIntervals;
|
|
5239
7059
|
exports.buildChartGradientDef = buildChartGradientDef;
|
|
7060
|
+
exports.buildHierarchyRoots = buildHierarchyRoots;
|
|
7061
|
+
exports.buildWaterfallSteps = buildWaterfallSteps;
|
|
5240
7062
|
exports.builtInChartStyleXml = builtInChartStyleXml;
|
|
5241
7063
|
exports.builtInChartTextStyle = builtInChartTextStyle;
|
|
5242
7064
|
exports.categoryTotals = categoryTotals;
|
|
@@ -5244,37 +7066,58 @@ exports.chartCacheValues = chartCacheValues;
|
|
|
5244
7066
|
exports.chartColorScheme = chartColorScheme;
|
|
5245
7067
|
exports.chartColorStyleId = chartColorStyleId;
|
|
5246
7068
|
exports.chartColorStyleXml = chartColorStyleXml;
|
|
7069
|
+
exports.chartErrorBarAmount = chartErrorBarAmount;
|
|
7070
|
+
exports.chartExSummary = chartExSummary;
|
|
5247
7071
|
exports.chartGradientMarkup = chartGradientMarkup;
|
|
5248
7072
|
exports.chartPaletteColors = chartPaletteColors;
|
|
5249
7073
|
exports.chartPaletteSeriesColor = chartPaletteSeriesColor;
|
|
5250
7074
|
exports.chartPaletteSeriesColorChoice = chartPaletteSeriesColorChoice;
|
|
7075
|
+
exports.chartSampleVariance = chartSampleVariance;
|
|
5251
7076
|
exports.chartSourceValues = chartSourceValues;
|
|
5252
7077
|
exports.chartSpaceKind = chartSpaceKind;
|
|
5253
7078
|
exports.chartSummaryFromSpace = chartSummaryFromSpace;
|
|
5254
7079
|
exports.chartSummarySeries = chartSummarySeries;
|
|
5255
7080
|
exports.chartSummaryView = chartSummaryView;
|
|
5256
7081
|
exports.chartThemePalette = chartThemePalette;
|
|
7082
|
+
exports.chartTrendlineKind = chartTrendlineKind;
|
|
7083
|
+
exports.chartTrendlineType = chartTrendlineType;
|
|
5257
7084
|
exports.clusteredBarGeometry = clusteredBarGeometry;
|
|
5258
7085
|
exports.computeBoxStats = computeBoxStats;
|
|
7086
|
+
exports.computeBubbleRadius = computeBubbleRadius;
|
|
7087
|
+
exports.computeHierarchicalSunburstArcs = computeHierarchicalSunburstArcs;
|
|
5259
7088
|
exports.computeHistogramBins = computeHistogramBins;
|
|
5260
7089
|
exports.computeLinearRegression = computeLinearRegression;
|
|
5261
7090
|
exports.computeRSquared = computeRSquared;
|
|
5262
7091
|
exports.computeRadarPoints = computeRadarPoints;
|
|
5263
7092
|
exports.computeStackedSeriesPlots = computeStackedSeriesPlots;
|
|
7093
|
+
exports.computeSunburstArcs = computeSunburstArcs;
|
|
7094
|
+
exports.computeWaterfallRange = computeWaterfallRange;
|
|
5264
7095
|
exports.effectiveBuiltInChartStyle = effectiveBuiltInChartStyle;
|
|
5265
7096
|
exports.findChartColorPalette = findChartColorPalette;
|
|
7097
|
+
exports.fitChartTrendline = fitChartTrendline;
|
|
5266
7098
|
exports.fitPolynomial = fitPolynomial;
|
|
7099
|
+
exports.formatChartNumber = formatChartNumber;
|
|
7100
|
+
exports.formatChartNumberWithColor = formatChartNumberWithColor;
|
|
7101
|
+
exports.formatCompactAxisValue = formatCompactAxisValue;
|
|
5267
7102
|
exports.formatExponentialEquation = formatExponentialEquation;
|
|
5268
7103
|
exports.formatLinearEquation = formatLinearEquation;
|
|
5269
7104
|
exports.formatLogarithmicEquation = formatLogarithmicEquation;
|
|
5270
7105
|
exports.formatPolynomialEquation = formatPolynomialEquation;
|
|
5271
7106
|
exports.formatPowerEquation = formatPowerEquation;
|
|
5272
7107
|
exports.formatTrendlineCoefficient = formatTrendlineCoefficient;
|
|
7108
|
+
exports.getChartStylePalette = getChartStylePalette;
|
|
5273
7109
|
exports.groupRowsByCategory = groupRowsByCategory;
|
|
5274
7110
|
exports.hasManualLayoutFields = hasManualLayoutFields;
|
|
7111
|
+
exports.hierarchyBranchLabels = hierarchyBranchLabels;
|
|
7112
|
+
exports.impliesAutoTitle = impliesAutoTitle;
|
|
7113
|
+
exports.isChartexOnlyType = isChartexOnlyType;
|
|
7114
|
+
exports.layoutTreemap = layoutTreemap;
|
|
7115
|
+
exports.maxBubbleSize = maxBubbleSize;
|
|
7116
|
+
exports.medianBubbleRadius = medianBubbleRadius;
|
|
5275
7117
|
exports.modulateLuminance = modulateLuminance;
|
|
5276
7118
|
exports.niceAxisStep = niceAxisStep;
|
|
5277
7119
|
exports.niceValueAxisBounds = niceValueAxisBounds;
|
|
7120
|
+
exports.normalizeLevels = normalizeLevels;
|
|
5278
7121
|
exports.nudgeOutsideLabels = nudgeOutsideLabels;
|
|
5279
7122
|
exports.parseChartSpace = parseChartSpace;
|
|
5280
7123
|
exports.placeBestFitLabel = placeBestFitLabel;
|
|
@@ -5287,15 +7130,22 @@ exports.readChartStyle = readChartStyle;
|
|
|
5287
7130
|
exports.readDisplayNaAsBlank = readDisplayNaAsBlank;
|
|
5288
7131
|
exports.removeGradientStop = removeGradientStop;
|
|
5289
7132
|
exports.renderChartSpaceSvg = renderChartSpaceSvg;
|
|
7133
|
+
exports.renderChartSummarySvg = renderChartSummarySvg;
|
|
5290
7134
|
exports.renderChartSvg = renderChartSvg;
|
|
7135
|
+
exports.resolveAutoTitleText = resolveAutoTitleText;
|
|
5291
7136
|
exports.resolveBlankDisplay = resolveBlankDisplay;
|
|
5292
7137
|
exports.resolveChartGradient = resolveChartGradient;
|
|
5293
7138
|
exports.resolveChartStyleDefinition = resolveChartStyleDefinition;
|
|
5294
7139
|
exports.resolveManualLayoutRect = resolveManualLayoutRect;
|
|
5295
7140
|
exports.scottBinCount = scottBinCount;
|
|
7141
|
+
exports.shade = shade;
|
|
5296
7142
|
exports.sortGradientStops = sortGradientStops;
|
|
5297
7143
|
exports.squarify = squarify;
|
|
7144
|
+
exports.stockCandle = stockCandle;
|
|
7145
|
+
exports.stockSlots = stockSlots;
|
|
7146
|
+
exports.sunburstArcPath = sunburstArcPath;
|
|
5298
7147
|
exports.themeColor = themeColor;
|
|
7148
|
+
exports.tint = tint;
|
|
5299
7149
|
exports.updateGradientStop = updateGradientStop;
|
|
5300
7150
|
exports.visibleRuns = visibleRuns;
|
|
5301
7151
|
exports.withChartGradientDirection = withChartGradientDirection;
|