@rowsncolumns/charts 27.0.30

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.
Files changed (281) hide show
  1. package/LICENSE.md +100 -0
  2. package/Readme.md +81 -0
  3. package/dist/cjs/atoms/editing-chart.atom.d.ts +13 -0
  4. package/dist/cjs/atoms/editing-chart.atom.d.ts.map +1 -0
  5. package/dist/cjs/atoms/editing-chart.atom.js +26 -0
  6. package/dist/cjs/basic-chart/basic-chart.d.ts +5 -0
  7. package/dist/cjs/basic-chart/basic-chart.d.ts.map +1 -0
  8. package/dist/cjs/basic-chart/basic-chart.js +2250 -0
  9. package/dist/cjs/basic-chart/helpers.d.ts +12 -0
  10. package/dist/cjs/basic-chart/helpers.d.ts.map +1 -0
  11. package/dist/cjs/basic-chart/helpers.js +105 -0
  12. package/dist/cjs/basic-chart/index.d.ts +5 -0
  13. package/dist/cjs/basic-chart/index.d.ts.map +1 -0
  14. package/dist/cjs/basic-chart/index.js +12 -0
  15. package/dist/cjs/components/dialogs/chart-editor-dialog.d.ts +5 -0
  16. package/dist/cjs/components/dialogs/chart-editor-dialog.d.ts.map +1 -0
  17. package/dist/cjs/components/dialogs/chart-editor-dialog.js +25 -0
  18. package/dist/cjs/components/editors/chart-editor.d.ts +10 -0
  19. package/dist/cjs/components/editors/chart-editor.d.ts.map +1 -0
  20. package/dist/cjs/components/editors/chart-editor.js +631 -0
  21. package/dist/cjs/components/editors/chart-range-input.d.ts +17 -0
  22. package/dist/cjs/components/editors/chart-range-input.d.ts.map +1 -0
  23. package/dist/cjs/components/editors/chart-range-input.js +16 -0
  24. package/dist/cjs/config.d.ts +19 -0
  25. package/dist/cjs/config.d.ts.map +1 -0
  26. package/dist/cjs/config.js +196 -0
  27. package/dist/cjs/hooks/use-chart-editor.d.ts +8 -0
  28. package/dist/cjs/hooks/use-chart-editor.d.ts.map +1 -0
  29. package/dist/cjs/hooks/use-chart-editor.js +29 -0
  30. package/dist/cjs/hooks/use-charts.d.ts +35 -0
  31. package/dist/cjs/hooks/use-charts.d.ts.map +1 -0
  32. package/dist/cjs/hooks/use-charts.js +67 -0
  33. package/dist/cjs/hooks/use-on-create-chart.d.ts +13 -0
  34. package/dist/cjs/hooks/use-on-create-chart.d.ts.map +1 -0
  35. package/dist/cjs/hooks/use-on-create-chart.js +24 -0
  36. package/dist/cjs/hooks/use-on-delete-chart.d.ts +8 -0
  37. package/dist/cjs/hooks/use-on-delete-chart.d.ts.map +1 -0
  38. package/dist/cjs/hooks/use-on-delete-chart.js +19 -0
  39. package/dist/cjs/hooks/use-on-move-chart.d.ts +8 -0
  40. package/dist/cjs/hooks/use-on-move-chart.d.ts.map +1 -0
  41. package/dist/cjs/hooks/use-on-move-chart.js +15 -0
  42. package/dist/cjs/hooks/use-on-resize-chart.d.ts +8 -0
  43. package/dist/cjs/hooks/use-on-resize-chart.d.ts.map +1 -0
  44. package/dist/cjs/hooks/use-on-resize-chart.js +15 -0
  45. package/dist/cjs/hooks/use-on-update-chart.d.ts +9 -0
  46. package/dist/cjs/hooks/use-on-update-chart.d.ts.map +1 -0
  47. package/dist/cjs/hooks/use-on-update-chart.js +15 -0
  48. package/dist/cjs/index.d.ts +11 -0
  49. package/dist/cjs/index.d.ts.map +1 -0
  50. package/dist/cjs/index.js +18 -0
  51. package/dist/cjs/interface/create-chart.d.ts +9 -0
  52. package/dist/cjs/interface/create-chart.d.ts.map +1 -0
  53. package/dist/cjs/interface/create-chart.js +110 -0
  54. package/dist/cjs/interface/delete-chart.d.ts +4 -0
  55. package/dist/cjs/interface/delete-chart.d.ts.map +1 -0
  56. package/dist/cjs/interface/delete-chart.js +26 -0
  57. package/dist/cjs/interface/move-chart.d.ts +5 -0
  58. package/dist/cjs/interface/move-chart.d.ts.map +1 -0
  59. package/dist/cjs/interface/move-chart.js +28 -0
  60. package/dist/cjs/interface/resize-chart.d.ts +5 -0
  61. package/dist/cjs/interface/resize-chart.d.ts.map +1 -0
  62. package/dist/cjs/interface/resize-chart.js +30 -0
  63. package/dist/cjs/interface/update-chart.d.ts +4 -0
  64. package/dist/cjs/interface/update-chart.d.ts.map +1 -0
  65. package/dist/cjs/interface/update-chart.js +29 -0
  66. package/dist/cjs/plotly/basic-chart/basic-chart.d.ts +5 -0
  67. package/dist/cjs/plotly/basic-chart/basic-chart.d.ts.map +1 -0
  68. package/dist/cjs/plotly/basic-chart/basic-chart.js +1586 -0
  69. package/dist/cjs/plotly/basic-chart/helpers.d.ts +20 -0
  70. package/dist/cjs/plotly/basic-chart/helpers.d.ts.map +1 -0
  71. package/dist/cjs/plotly/basic-chart/helpers.js +114 -0
  72. package/dist/cjs/plotly/basic-chart/index.d.ts +5 -0
  73. package/dist/cjs/plotly/basic-chart/index.d.ts.map +1 -0
  74. package/dist/cjs/plotly/basic-chart/index.js +12 -0
  75. package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -0
  76. package/dist/cjs/types.d.ts +27 -0
  77. package/dist/cjs/types.d.ts.map +1 -0
  78. package/dist/cjs/types.js +2 -0
  79. package/dist/cjs/utils/aggregation.d.ts +6 -0
  80. package/dist/cjs/utils/aggregation.d.ts.map +1 -0
  81. package/dist/cjs/utils/aggregation.js +127 -0
  82. package/dist/cjs/utils/bar-layout.d.ts +57 -0
  83. package/dist/cjs/utils/bar-layout.d.ts.map +1 -0
  84. package/dist/cjs/utils/bar-layout.js +81 -0
  85. package/dist/cjs/utils/boxplot.d.ts +62 -0
  86. package/dist/cjs/utils/boxplot.d.ts.map +1 -0
  87. package/dist/cjs/utils/boxplot.js +105 -0
  88. package/dist/cjs/utils/bubble.d.ts +52 -0
  89. package/dist/cjs/utils/bubble.d.ts.map +1 -0
  90. package/dist/cjs/utils/bubble.js +139 -0
  91. package/dist/cjs/utils/chart-spec-utils.d.ts +67 -0
  92. package/dist/cjs/utils/chart-spec-utils.d.ts.map +1 -0
  93. package/dist/cjs/utils/chart-spec-utils.js +355 -0
  94. package/dist/cjs/utils/echarts-gl-loader.d.ts +11 -0
  95. package/dist/cjs/utils/echarts-gl-loader.d.ts.map +1 -0
  96. package/dist/cjs/utils/echarts-gl-loader.js +59 -0
  97. package/dist/cjs/utils/error-bars.d.ts +58 -0
  98. package/dist/cjs/utils/error-bars.d.ts.map +1 -0
  99. package/dist/cjs/utils/error-bars.js +154 -0
  100. package/dist/cjs/utils/gradient.d.ts +52 -0
  101. package/dist/cjs/utils/gradient.d.ts.map +1 -0
  102. package/dist/cjs/utils/gradient.js +93 -0
  103. package/dist/cjs/utils/hierarchy.d.ts +28 -0
  104. package/dist/cjs/utils/hierarchy.d.ts.map +1 -0
  105. package/dist/cjs/utils/hierarchy.js +186 -0
  106. package/dist/cjs/utils/histogram.d.ts +46 -0
  107. package/dist/cjs/utils/histogram.d.ts.map +1 -0
  108. package/dist/cjs/utils/histogram.js +125 -0
  109. package/dist/cjs/utils/of-pie.d.ts +101 -0
  110. package/dist/cjs/utils/of-pie.d.ts.map +1 -0
  111. package/dist/cjs/utils/of-pie.js +159 -0
  112. package/dist/cjs/utils/overrides.d.ts +12 -0
  113. package/dist/cjs/utils/overrides.d.ts.map +1 -0
  114. package/dist/cjs/utils/overrides.js +171 -0
  115. package/dist/cjs/utils/radar.d.ts +37 -0
  116. package/dist/cjs/utils/radar.d.ts.map +1 -0
  117. package/dist/cjs/utils/radar.js +70 -0
  118. package/dist/cjs/utils/region-map-loader.d.ts +22 -0
  119. package/dist/cjs/utils/region-map-loader.d.ts.map +1 -0
  120. package/dist/cjs/utils/region-map-loader.js +174 -0
  121. package/dist/cjs/utils/region-map.d.ts +100 -0
  122. package/dist/cjs/utils/region-map.d.ts.map +1 -0
  123. package/dist/cjs/utils/region-map.js +327 -0
  124. package/dist/cjs/utils/stock.d.ts +64 -0
  125. package/dist/cjs/utils/stock.d.ts.map +1 -0
  126. package/dist/cjs/utils/stock.js +153 -0
  127. package/dist/cjs/utils/three-d.d.ts +96 -0
  128. package/dist/cjs/utils/three-d.d.ts.map +1 -0
  129. package/dist/cjs/utils/three-d.js +191 -0
  130. package/dist/cjs/utils/trendline.d.ts +41 -0
  131. package/dist/cjs/utils/trendline.d.ts.map +1 -0
  132. package/dist/cjs/utils/trendline.js +303 -0
  133. package/dist/cjs/utils/waterfall.d.ts +24 -0
  134. package/dist/cjs/utils/waterfall.d.ts.map +1 -0
  135. package/dist/cjs/utils/waterfall.js +61 -0
  136. package/dist/cjs/utils/webgl.d.ts +12 -0
  137. package/dist/cjs/utils/webgl.d.ts.map +1 -0
  138. package/dist/cjs/utils/webgl.js +36 -0
  139. package/dist/cjs/vitest.config.d.ts +3 -0
  140. package/dist/cjs/vitest.config.d.ts.map +1 -0
  141. package/dist/cjs/vitest.config.js +9 -0
  142. package/dist/esm/atoms/editing-chart.atom.d.ts +13 -0
  143. package/dist/esm/atoms/editing-chart.atom.d.ts.map +1 -0
  144. package/dist/esm/atoms/editing-chart.atom.js +12 -0
  145. package/dist/esm/basic-chart/basic-chart.d.ts +5 -0
  146. package/dist/esm/basic-chart/basic-chart.d.ts.map +1 -0
  147. package/dist/esm/basic-chart/basic-chart.js +2343 -0
  148. package/dist/esm/basic-chart/helpers.d.ts +12 -0
  149. package/dist/esm/basic-chart/helpers.d.ts.map +1 -0
  150. package/dist/esm/basic-chart/helpers.js +98 -0
  151. package/dist/esm/basic-chart/index.d.ts +5 -0
  152. package/dist/esm/basic-chart/index.d.ts.map +1 -0
  153. package/dist/esm/basic-chart/index.js +7 -0
  154. package/dist/esm/components/dialogs/chart-editor-dialog.d.ts +5 -0
  155. package/dist/esm/components/dialogs/chart-editor-dialog.d.ts.map +1 -0
  156. package/dist/esm/components/dialogs/chart-editor-dialog.js +19 -0
  157. package/dist/esm/components/editors/chart-editor.d.ts +10 -0
  158. package/dist/esm/components/editors/chart-editor.d.ts.map +1 -0
  159. package/dist/esm/components/editors/chart-editor.js +550 -0
  160. package/dist/esm/components/editors/chart-range-input.d.ts +17 -0
  161. package/dist/esm/components/editors/chart-range-input.d.ts.map +1 -0
  162. package/dist/esm/components/editors/chart-range-input.js +10 -0
  163. package/dist/esm/config.d.ts +19 -0
  164. package/dist/esm/config.d.ts.map +1 -0
  165. package/dist/esm/config.js +161 -0
  166. package/dist/esm/hooks/use-chart-editor.d.ts +8 -0
  167. package/dist/esm/hooks/use-chart-editor.d.ts.map +1 -0
  168. package/dist/esm/hooks/use-chart-editor.js +32 -0
  169. package/dist/esm/hooks/use-charts.d.ts +35 -0
  170. package/dist/esm/hooks/use-charts.d.ts.map +1 -0
  171. package/dist/esm/hooks/use-charts.js +62 -0
  172. package/dist/esm/hooks/use-on-create-chart.d.ts +13 -0
  173. package/dist/esm/hooks/use-on-create-chart.d.ts.map +1 -0
  174. package/dist/esm/hooks/use-on-create-chart.js +19 -0
  175. package/dist/esm/hooks/use-on-delete-chart.d.ts +8 -0
  176. package/dist/esm/hooks/use-on-delete-chart.d.ts.map +1 -0
  177. package/dist/esm/hooks/use-on-delete-chart.js +14 -0
  178. package/dist/esm/hooks/use-on-move-chart.d.ts +8 -0
  179. package/dist/esm/hooks/use-on-move-chart.d.ts.map +1 -0
  180. package/dist/esm/hooks/use-on-move-chart.js +10 -0
  181. package/dist/esm/hooks/use-on-resize-chart.d.ts +8 -0
  182. package/dist/esm/hooks/use-on-resize-chart.d.ts.map +1 -0
  183. package/dist/esm/hooks/use-on-resize-chart.js +10 -0
  184. package/dist/esm/hooks/use-on-update-chart.d.ts +9 -0
  185. package/dist/esm/hooks/use-on-update-chart.d.ts.map +1 -0
  186. package/dist/esm/hooks/use-on-update-chart.js +10 -0
  187. package/dist/esm/index.d.ts +11 -0
  188. package/dist/esm/index.d.ts.map +1 -0
  189. package/dist/esm/index.js +13 -0
  190. package/dist/esm/interface/create-chart.d.ts +9 -0
  191. package/dist/esm/interface/create-chart.d.ts.map +1 -0
  192. package/dist/esm/interface/create-chart.js +126 -0
  193. package/dist/esm/interface/delete-chart.d.ts +4 -0
  194. package/dist/esm/interface/delete-chart.d.ts.map +1 -0
  195. package/dist/esm/interface/delete-chart.js +20 -0
  196. package/dist/esm/interface/move-chart.d.ts +5 -0
  197. package/dist/esm/interface/move-chart.d.ts.map +1 -0
  198. package/dist/esm/interface/move-chart.js +22 -0
  199. package/dist/esm/interface/resize-chart.d.ts +5 -0
  200. package/dist/esm/interface/resize-chart.d.ts.map +1 -0
  201. package/dist/esm/interface/resize-chart.js +24 -0
  202. package/dist/esm/interface/update-chart.d.ts +4 -0
  203. package/dist/esm/interface/update-chart.d.ts.map +1 -0
  204. package/dist/esm/interface/update-chart.js +26 -0
  205. package/dist/esm/plotly/basic-chart/basic-chart.d.ts +5 -0
  206. package/dist/esm/plotly/basic-chart/basic-chart.d.ts.map +1 -0
  207. package/dist/esm/plotly/basic-chart/basic-chart.js +1682 -0
  208. package/dist/esm/plotly/basic-chart/helpers.d.ts +20 -0
  209. package/dist/esm/plotly/basic-chart/helpers.d.ts.map +1 -0
  210. package/dist/esm/plotly/basic-chart/helpers.js +107 -0
  211. package/dist/esm/plotly/basic-chart/index.d.ts +5 -0
  212. package/dist/esm/plotly/basic-chart/index.d.ts.map +1 -0
  213. package/dist/esm/plotly/basic-chart/index.js +7 -0
  214. package/dist/esm/tsconfig.esm.tsbuildinfo +1 -0
  215. package/dist/esm/types.d.ts +27 -0
  216. package/dist/esm/types.d.ts.map +1 -0
  217. package/dist/esm/types.js +1 -0
  218. package/dist/esm/utils/aggregation.d.ts +6 -0
  219. package/dist/esm/utils/aggregation.d.ts.map +1 -0
  220. package/dist/esm/utils/aggregation.js +96 -0
  221. package/dist/esm/utils/bar-layout.d.ts +57 -0
  222. package/dist/esm/utils/bar-layout.d.ts.map +1 -0
  223. package/dist/esm/utils/bar-layout.js +70 -0
  224. package/dist/esm/utils/boxplot.d.ts +62 -0
  225. package/dist/esm/utils/boxplot.d.ts.map +1 -0
  226. package/dist/esm/utils/boxplot.js +91 -0
  227. package/dist/esm/utils/bubble.d.ts +52 -0
  228. package/dist/esm/utils/bubble.d.ts.map +1 -0
  229. package/dist/esm/utils/bubble.js +122 -0
  230. package/dist/esm/utils/chart-spec-utils.d.ts +67 -0
  231. package/dist/esm/utils/chart-spec-utils.d.ts.map +1 -0
  232. package/dist/esm/utils/chart-spec-utils.js +270 -0
  233. package/dist/esm/utils/echarts-gl-loader.d.ts +11 -0
  234. package/dist/esm/utils/echarts-gl-loader.d.ts.map +1 -0
  235. package/dist/esm/utils/echarts-gl-loader.js +51 -0
  236. package/dist/esm/utils/error-bars.d.ts +58 -0
  237. package/dist/esm/utils/error-bars.d.ts.map +1 -0
  238. package/dist/esm/utils/error-bars.js +134 -0
  239. package/dist/esm/utils/gradient.d.ts +52 -0
  240. package/dist/esm/utils/gradient.d.ts.map +1 -0
  241. package/dist/esm/utils/gradient.js +84 -0
  242. package/dist/esm/utils/hierarchy.d.ts +28 -0
  243. package/dist/esm/utils/hierarchy.d.ts.map +1 -0
  244. package/dist/esm/utils/hierarchy.js +150 -0
  245. package/dist/esm/utils/histogram.d.ts +46 -0
  246. package/dist/esm/utils/histogram.d.ts.map +1 -0
  247. package/dist/esm/utils/histogram.js +95 -0
  248. package/dist/esm/utils/of-pie.d.ts +101 -0
  249. package/dist/esm/utils/of-pie.d.ts.map +1 -0
  250. package/dist/esm/utils/of-pie.js +141 -0
  251. package/dist/esm/utils/overrides.d.ts +12 -0
  252. package/dist/esm/utils/overrides.d.ts.map +1 -0
  253. package/dist/esm/utils/overrides.js +159 -0
  254. package/dist/esm/utils/radar.d.ts +37 -0
  255. package/dist/esm/utils/radar.d.ts.map +1 -0
  256. package/dist/esm/utils/radar.js +49 -0
  257. package/dist/esm/utils/region-map-loader.d.ts +22 -0
  258. package/dist/esm/utils/region-map-loader.d.ts.map +1 -0
  259. package/dist/esm/utils/region-map-loader.js +141 -0
  260. package/dist/esm/utils/region-map.d.ts +100 -0
  261. package/dist/esm/utils/region-map.d.ts.map +1 -0
  262. package/dist/esm/utils/region-map.js +266 -0
  263. package/dist/esm/utils/stock.d.ts +64 -0
  264. package/dist/esm/utils/stock.d.ts.map +1 -0
  265. package/dist/esm/utils/stock.js +123 -0
  266. package/dist/esm/utils/three-d.d.ts +96 -0
  267. package/dist/esm/utils/three-d.d.ts.map +1 -0
  268. package/dist/esm/utils/three-d.js +162 -0
  269. package/dist/esm/utils/trendline.d.ts +41 -0
  270. package/dist/esm/utils/trendline.d.ts.map +1 -0
  271. package/dist/esm/utils/trendline.js +257 -0
  272. package/dist/esm/utils/waterfall.d.ts +24 -0
  273. package/dist/esm/utils/waterfall.d.ts.map +1 -0
  274. package/dist/esm/utils/waterfall.js +55 -0
  275. package/dist/esm/utils/webgl.d.ts +12 -0
  276. package/dist/esm/utils/webgl.d.ts.map +1 -0
  277. package/dist/esm/utils/webgl.js +30 -0
  278. package/dist/esm/vitest.config.d.ts +3 -0
  279. package/dist/esm/vitest.config.d.ts.map +1 -0
  280. package/dist/esm/vitest.config.js +7 -0
  281. package/package.json +96 -0
@@ -0,0 +1,1586 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BasicChart = void 0;
4
+ var tslib_1 = require("tslib");
5
+ var icons_1 = require("@rowsncolumns/icons");
6
+ var spreadsheet_1 = require("@rowsncolumns/spreadsheet");
7
+ var spreadsheet_state_1 = require("@rowsncolumns/spreadsheet-state");
8
+ var ui_1 = require("@rowsncolumns/ui");
9
+ var utils_1 = require("@rowsncolumns/utils");
10
+ var react_1 = tslib_1.__importStar(require("react"));
11
+ var react_plotly_js_1 = tslib_1.__importDefault(require("react-plotly.js"));
12
+ var aggregation_1 = require("../../utils/aggregation");
13
+ var boxplot_1 = require("../../utils/boxplot");
14
+ var bubble_1 = require("../../utils/bubble");
15
+ var chart_spec_utils_1 = require("../../utils/chart-spec-utils");
16
+ var error_bars_1 = require("../../utils/error-bars");
17
+ var gradient_1 = require("../../utils/gradient");
18
+ var hierarchy_1 = require("../../utils/hierarchy");
19
+ var histogram_1 = require("../../utils/histogram");
20
+ var of_pie_1 = require("../../utils/of-pie");
21
+ var radar_1 = require("../../utils/radar");
22
+ var region_map_1 = require("../../utils/region-map");
23
+ var stock_1 = require("../../utils/stock");
24
+ var trendline_1 = require("../../utils/trendline");
25
+ var helpers_1 = require("./helpers");
26
+ var BASIC_CHART_TYPES = new Set([
27
+ "bar",
28
+ "column",
29
+ "line",
30
+ "pie",
31
+ "doughnut",
32
+ "area",
33
+ "radar",
34
+ "stock",
35
+ "histogram",
36
+ "boxplot",
37
+ "waterfall",
38
+ "funnel",
39
+ "combo",
40
+ "regionMap",
41
+ ]);
42
+ // Plotly ships its own world geometry; these are the `layout.geo.scope`
43
+ // values it accepts. Any other authored geoScope falls back to "world".
44
+ var PLOTLY_GEO_SCOPES = new Set([
45
+ "world",
46
+ "usa",
47
+ "europe",
48
+ "asia",
49
+ "africa",
50
+ "north america",
51
+ "south america",
52
+ ]);
53
+ // -------------------------- Phase 5.1 helpers --------------------------
54
+ /** Merge a parsed `ChartTextFormat` onto a plotly font object. */
55
+ var applyTextFormatToFont = function (font, fmt) {
56
+ if (!fmt)
57
+ return font;
58
+ var next = tslib_1.__assign({}, (font !== null && font !== void 0 ? font : {}));
59
+ if (fmt.color)
60
+ next.color = fmt.color;
61
+ if (fmt.fontFamily)
62
+ next.family = fmt.fontFamily;
63
+ if (typeof fmt.fontSize === "number")
64
+ next.size = fmt.fontSize;
65
+ return next;
66
+ };
67
+ var applyLegendOverridesPlotly = function (legend, opts) {
68
+ if (!opts)
69
+ return { legend: legend, showlegend: undefined };
70
+ if (opts.position === "none") {
71
+ return { legend: legend, showlegend: false };
72
+ }
73
+ var next = tslib_1.__assign({}, (legend !== null && legend !== void 0 ? legend : {}));
74
+ switch (opts.position) {
75
+ case "top":
76
+ next.orientation = "h";
77
+ next.x = 0.5;
78
+ next.xanchor = "center";
79
+ next.y = 1.1;
80
+ break;
81
+ case "bottom":
82
+ next.orientation = "h";
83
+ next.x = 0.5;
84
+ next.xanchor = "center";
85
+ next.y = -0.2;
86
+ break;
87
+ case "left":
88
+ next.orientation = "v";
89
+ next.x = -0.2;
90
+ next.y = 0.5;
91
+ next.yanchor = "middle";
92
+ break;
93
+ case "right":
94
+ next.orientation = "v";
95
+ next.x = 1.1;
96
+ next.y = 0.5;
97
+ next.yanchor = "middle";
98
+ break;
99
+ case "topRight":
100
+ next.orientation = "v";
101
+ next.x = 1;
102
+ next.y = 1;
103
+ next.xanchor = "right";
104
+ next.yanchor = "top";
105
+ break;
106
+ }
107
+ // Authored legend `<c:txPr>` overrides the theme-derived default.
108
+ next.font = applyTextFormatToFont(next.font, opts.textFormat);
109
+ return { legend: next, showlegend: true };
110
+ };
111
+ var applyAxisOverridesPlotly = function (axis, opts) {
112
+ var _a, _b, _c, _d;
113
+ if (!opts)
114
+ return axis;
115
+ var next = tslib_1.__assign({}, (axis !== null && axis !== void 0 ? axis : {}));
116
+ if (opts.logarithmic)
117
+ next.type = "log";
118
+ if (opts.reverse)
119
+ next.autorange = "reversed";
120
+ if (typeof opts.min === "number" || typeof opts.max === "number") {
121
+ next.range = [(_a = opts.min) !== null && _a !== void 0 ? _a : null, (_b = opts.max) !== null && _b !== void 0 ? _b : null];
122
+ }
123
+ if (opts.visible === false)
124
+ next.visible = false;
125
+ if (opts.showMajorGridlines === false)
126
+ next.showgrid = false;
127
+ if (opts.showMajorGridlines === true)
128
+ next.showgrid = true;
129
+ // Authored axis-label `<c:txPr>` — affects tick labels (`tickfont`)
130
+ // and the axis title font (`title.font`).
131
+ if (opts.textFormat) {
132
+ next.tickfont = applyTextFormatToFont(next.tickfont, opts.textFormat);
133
+ next.title = tslib_1.__assign(tslib_1.__assign({}, ((_c = next.title) !== null && _c !== void 0 ? _c : {})), { font: applyTextFormatToFont((_d = next.title) === null || _d === void 0 ? void 0 : _d.font, opts.textFormat) });
134
+ }
135
+ return next;
136
+ };
137
+ var PLOTLY_DLBL_POS_PIE = {
138
+ center: "inside",
139
+ inside: "inside",
140
+ outside: "outside",
141
+ insideEnd: "inside",
142
+ outsideEnd: "outside",
143
+ bestFit: "outside",
144
+ };
145
+ var PLOTLY_DLBL_POS_BAR = {
146
+ center: "inside",
147
+ inside: "inside",
148
+ outside: "outside",
149
+ insideEnd: "inside",
150
+ outsideEnd: "outside",
151
+ bestFit: "outside",
152
+ };
153
+ var applyDataLabelsToTracePlotly = function (trace, opts, chartType) {
154
+ var _a;
155
+ if (!(opts === null || opts === void 0 ? void 0 : opts.show))
156
+ return trace;
157
+ var next = tslib_1.__assign({}, trace);
158
+ var isCircular = chartType === "pie" || chartType === "doughnut";
159
+ var posMap = isCircular ? PLOTLY_DLBL_POS_PIE : PLOTLY_DLBL_POS_BAR;
160
+ var position = opts.position ? (_a = posMap[opts.position]) !== null && _a !== void 0 ? _a : "inside" : "inside";
161
+ if (isCircular) {
162
+ // Plotly's pie trace uses `textinfo` to control which fields render.
163
+ var parts = [];
164
+ if (opts.showCategoryName !== false && opts.showCategoryName)
165
+ parts.push("label");
166
+ if (opts.showValue !== false)
167
+ parts.push("value");
168
+ if (opts.showPercent)
169
+ parts.push("percent");
170
+ next.textinfo = parts.length ? parts.join("+") : "value";
171
+ next.textposition = position;
172
+ }
173
+ else {
174
+ // <c:dLbls><c:numFmt formatCode=…> — when authored, run each value
175
+ // through the same numfmt grammar the spreadsheet uses (`"$"#,##0`
176
+ // → `$1,831`). Plotly supports this natively via `texttemplate`
177
+ // with the d3-format mini-language, but our patterns are
178
+ // SpreadsheetML — easier to pre-format the strings.
179
+ var pattern_1 = opts.numberFormatPattern;
180
+ var yVals = Array.isArray(next.y) ? next.y : [];
181
+ next.text = pattern_1
182
+ ? yVals.map(function (v) { return (v === null || v === undefined ? "" : (0, utils_1.ssfFormat)(pattern_1, v)); })
183
+ : next.y;
184
+ next.textposition = position;
185
+ }
186
+ return next;
187
+ };
188
+ var BUBBLE_CHART_TYPES = new Set([
189
+ "bubble",
190
+ "scatter",
191
+ ]);
192
+ var HIERARCHY_CHART_TYPES = new Set([
193
+ "treemap",
194
+ "sunburst",
195
+ ]);
196
+ var isBasicChartSpec = function (spec) {
197
+ return BASIC_CHART_TYPES.has(spec.chartType);
198
+ };
199
+ var isBubbleChartSpec = function (spec) {
200
+ return BUBBLE_CHART_TYPES.has(spec.chartType);
201
+ };
202
+ var isHierarchyChartSpec = function (spec) {
203
+ return HIERARCHY_CHART_TYPES.has(spec.chartType);
204
+ };
205
+ var flattenChartDataValues = function (chartData, extractor, hiddenStrategy, skipFirstRow) {
206
+ if (skipFirstRow === void 0) { skipFirstRow = false; }
207
+ if (!chartData || chartData.length === 0)
208
+ return [];
209
+ var values = [];
210
+ chartData.forEach(function (entry) {
211
+ // Inline values (`<c:strLit>` / `<c:numLit>`) take precedence over
212
+ // cell-range sources — only one is populated by spec.
213
+ var inline = entry
214
+ .inlineValues;
215
+ if (inline && inline.length) {
216
+ var trimmed = skipFirstRow ? inline.slice(1) : inline;
217
+ values.push.apply(values, tslib_1.__spreadArray([], tslib_1.__read(trimmed), false));
218
+ return;
219
+ }
220
+ entry.sources.forEach(function (source) {
221
+ var _a;
222
+ var extracted = (_a = extractor(source, hiddenStrategy)) !== null && _a !== void 0 ? _a : [];
223
+ var trimmed = skipFirstRow && extracted.length > 0 ? extracted.slice(1) : extracted;
224
+ values.push.apply(values, tslib_1.__spreadArray([], tslib_1.__read(trimmed), false));
225
+ });
226
+ });
227
+ return values;
228
+ };
229
+ // Excel error values that should be treated as null in charts
230
+ var EXCEL_ERROR_VALUES = new Set([
231
+ "#N/A",
232
+ "#REF!",
233
+ "#VALUE!",
234
+ "#DIV/0!",
235
+ "#NAME?",
236
+ "#NULL!",
237
+ "#NUM!",
238
+ "#ERROR!",
239
+ "#GETTING_DATA",
240
+ ]);
241
+ /**
242
+ * Check if a value is an Excel error string
243
+ */
244
+ var isErrorValue = function (value) {
245
+ if (typeof value !== "string")
246
+ return false;
247
+ return EXCEL_ERROR_VALUES.has(value.toUpperCase());
248
+ };
249
+ /**
250
+ * Sanitize a value for chart display - convert errors to undefined
251
+ */
252
+ var sanitizeChartValue = function (value) {
253
+ if (value === null || value === undefined)
254
+ return undefined;
255
+ if (isErrorValue(value))
256
+ return undefined;
257
+ if (typeof value === "number" && !isNaN(value))
258
+ return value;
259
+ if (typeof value === "string") {
260
+ var num = parseFloat(value);
261
+ return isNaN(num) ? undefined : num;
262
+ }
263
+ return undefined;
264
+ };
265
+ /**
266
+ * Add alpha transparency to a color (hex or rgb)
267
+ */
268
+ var addAlphaToColor = function (color, alpha) {
269
+ if (!color)
270
+ return "rgba(0, 0, 0, ".concat(alpha, ")");
271
+ // Handle hex colors
272
+ if (color.startsWith("#")) {
273
+ var hex = color.slice(1);
274
+ var r = parseInt(hex.slice(0, 2), 16);
275
+ var g = parseInt(hex.slice(2, 4), 16);
276
+ var b = parseInt(hex.slice(4, 6), 16);
277
+ return "rgba(".concat(r, ", ").concat(g, ", ").concat(b, ", ").concat(alpha, ")");
278
+ }
279
+ // Handle rgb/rgba colors
280
+ if (color.startsWith("rgb")) {
281
+ var match = color.match(/rgba?\((\d+),\s*(\d+),\s*(\d+)/);
282
+ if (match) {
283
+ return "rgba(".concat(match[1], ", ").concat(match[2], ", ").concat(match[3], ", ").concat(alpha, ")");
284
+ }
285
+ }
286
+ return color;
287
+ };
288
+ var BasicChart = function (_a) {
289
+ var _b;
290
+ var width = _a.width, height = _a.height, chart = _a.chart, theme = _a.theme, isDarkMode = _a.isDarkMode, sheetId = _a.sheetId, readonly = _a.readonly, getDomainValuesFromRange = _a.getDomainValuesFromRange, getSeriesValuesFromRange = _a.getSeriesValuesFromRange, onDeleteChart = _a.onDeleteChart, onRequestEdit = _a.onRequestEdit, onRequestCalculate = _a.onRequestCalculate, isSelected = _a.isSelected;
291
+ var spec = chart.spec;
292
+ var hierarchyTitleRef = (0, react_1.useRef)(undefined);
293
+ var explicitChartTitle = (_b = chart.spec.title) !== null && _b !== void 0 ? _b : undefined;
294
+ var title = explicitChartTitle !== null && explicitChartTitle !== void 0 ? explicitChartTitle : hierarchyTitleRef.current;
295
+ var plotRef = (0, react_1.useRef)(null);
296
+ var focusSheet = (0, spreadsheet_1.useFocusSheet)();
297
+ var shouldFocusSheetRef = (0, react_1.useRef)(false);
298
+ var _c = tslib_1.__read((0, react_1.useState)([]), 2), plotData = _c[0], setPlotData = _c[1];
299
+ var _d = tslib_1.__read((0, react_1.useState)({}), 2), layout = _d[0], setLayout = _d[1];
300
+ var getSeriesData = (0, react_1.useCallback)(function (spec, sheetRange, options) {
301
+ var _a;
302
+ var rawSeriesValues = getSeriesValuesFromRange(sheetRange, spec.hiddenDimensionStrategy);
303
+ // Sanitize values - convert error strings like #N/A to null
304
+ var sanitizedValues = rawSeriesValues.map(sanitizeChartValue);
305
+ var aggregateEnabled = options.aggregateEnabled, aggregateType = options.aggregateType, rawDomainValues = options.rawDomainValues, orderedDomainValues = options.orderedDomainValues;
306
+ var canAggregate = aggregateEnabled &&
307
+ !!aggregateType &&
308
+ rawDomainValues.length > 0 &&
309
+ orderedDomainValues.length > 0 &&
310
+ rawDomainValues.length === sanitizedValues.length;
311
+ if (canAggregate) {
312
+ var aggregatedValues = (0, aggregation_1.aggregateSeriesByDomain)(rawDomainValues, sanitizedValues, aggregateType, orderedDomainValues).map(function (value) { return value !== null && value !== void 0 ? value : 0; });
313
+ if ((spec.chartType === "pie" || spec.chartType === "doughnut")) {
314
+ return {
315
+ values: aggregatedValues,
316
+ labels: orderedDomainValues,
317
+ };
318
+ }
319
+ return aggregatedValues;
320
+ }
321
+ // Use sanitized values - errors like #N/A become undefined
322
+ var seriesValues = sanitizedValues;
323
+ if ((spec.chartType === "pie" || spec.chartType === "doughnut")) {
324
+ var domainSheetRange = (_a = spec.domains[0]) === null || _a === void 0 ? void 0 : _a.sources[0];
325
+ if (!domainSheetRange) {
326
+ return { values: [], labels: [] };
327
+ }
328
+ var domainValues = getDomainValuesFromRange(domainSheetRange, spec.hiddenDimensionStrategy);
329
+ return {
330
+ values: seriesValues,
331
+ labels: domainValues,
332
+ };
333
+ }
334
+ return seriesValues;
335
+ }, [getSeriesValuesFromRange, getDomainValuesFromRange]);
336
+ /**
337
+ * Triggers a chart update
338
+ */
339
+ var updateChart = function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
340
+ var traces, chartType, position, isBubble, isHierarchy, textColor, bgColor, gridColor, skipHeaders_1, labels, perSeriesX, perSeriesSize, seriesInputs, i, seriesEntry, resolvedLabel, _a, xValues, sizeValues_1, sharedXValues, sharedSizeValues, _b, categories_1, preparedSeries, sizeValues, sizeScale_1, hasStringX_1, palette_1, isScatter_1, scatterStyle_1, plotlyModeForScatterStyle_1, lineShapeFor_1, traces_1, titleFmt, xAxisFmt, yAxisFmt, legendFmt, bubbleLayout, hierarchyRows, headerTitle, hierarchyData, seriesName, hierarchyTrace, layoutForHierarchy, labels, seriesEntry, rawValues_1, locations_1, z_1, ramp_1, colorscale, geoScope, regionTrace, categories, radarStyle, radarTraces, radarInputs, _c, _d, seriesEntry, label, values, indicators, _loop_1, i, maxR, variant, categories, seriesValues, volumePoints_1, hasVolume, buildVolumeTrace, volumeLayout, priceYAxisDomain, roles, xs_1, candleTrace, lineSeries, stockPalette_1, xs_2, stockTraces, isStacked, isHorizontalBarChart, shouldAggregate, primaryDomainSource, rawPrimaryDomainValues, domainData, assignCartesianData, themeColorPalette, applyTraceColor, hasSecondaryAxis, isPareto, isOfPie, ofPieHandled, ofPieExtras, decorateCartesianTrace, seriesIndex, _e, _f, series, currentSeriesIndex, dataLabel, _g, _h, _loop_2, _j, _k, sheetRange, e_1_1, authoredTitleFmt, newLayout, dlOpts, doughnutHole, formattedTraces, sortedTraces;
341
+ var e_2, _l, e_1, _m, e_3, _o;
342
+ var _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52;
343
+ return tslib_1.__generator(this, function (_53) {
344
+ switch (_53.label) {
345
+ case 0:
346
+ (0, utils_1.debug)("Updating chart", chart);
347
+ traces = [];
348
+ chartType = (0, helpers_1.chartTypeToPlotlyType)(spec === null || spec === void 0 ? void 0 : spec.chartType);
349
+ position = chart.position;
350
+ isBubble = isBubbleChartSpec(spec);
351
+ isHierarchy = isHierarchyChartSpec(spec);
352
+ textColor = (0, spreadsheet_1.getStringifiedColor)({
353
+ theme: 1,
354
+ tint: isDarkMode ? 1 : 0,
355
+ }, theme);
356
+ bgColor = (0, spreadsheet_1.getStringifiedColor)({ theme: 0, tint: isDarkMode ? -1 : 1 }, theme);
357
+ gridColor = isDarkMode ? "rgba(255,255,255,0.3)" : "#CCCCCC";
358
+ if (!isBubble) return [3 /*break*/, 6];
359
+ skipHeaders_1 = spec.useFirstRowAsHeaders !== false;
360
+ labels = flattenChartDataValues(spec.bubbleLabels, getDomainValuesFromRange, spec.hiddenDimensionStrategy, skipHeaders_1).map(bubble_1.toLabelString);
361
+ perSeriesX = ((_p = spec.domains) !== null && _p !== void 0 ? _p : []).map(function (dom) {
362
+ return flattenChartDataValues([dom], getSeriesValuesFromRange, spec.hiddenDimensionStrategy, skipHeaders_1);
363
+ });
364
+ perSeriesSize = ((_q = spec.bubbleSizes) !== null && _q !== void 0 ? _q : []).map(function (sz) {
365
+ return flattenChartDataValues([sz], getSeriesValuesFromRange, spec.hiddenDimensionStrategy, skipHeaders_1);
366
+ });
367
+ seriesInputs = [];
368
+ i = 0;
369
+ _53.label = 1;
370
+ case 1:
371
+ if (!(i < spec.series.length)) return [3 /*break*/, 5];
372
+ seriesEntry = spec.series[i];
373
+ resolvedLabel = (_r = seriesEntry.dataLabel) !== null && _r !== void 0 ? _r : "";
374
+ if (!(resolvedLabel && (0, utils_1.isAFormula)(resolvedLabel))) return [3 /*break*/, 3];
375
+ _a = chart_spec_utils_1.coerceCalculatedLabel;
376
+ return [4 /*yield*/, onRequestCalculate(resolvedLabel, (_s = chart.position.sheetId) !== null && _s !== void 0 ? _s : sheetId, chart.position.overlayPosition.anchorCell.rowIndex, chart.position.overlayPosition.anchorCell.columnIndex)];
377
+ case 2:
378
+ resolvedLabel = _a.apply(void 0, [_53.sent()]);
379
+ _53.label = 3;
380
+ case 3:
381
+ xValues = (_t = perSeriesX[i]) !== null && _t !== void 0 ? _t : perSeriesX[0];
382
+ sizeValues_1 = (_u = perSeriesSize[i]) !== null && _u !== void 0 ? _u : perSeriesSize[0];
383
+ seriesInputs.push(tslib_1.__assign(tslib_1.__assign({ name: resolvedLabel, values: flattenChartDataValues([seriesEntry], getSeriesValuesFromRange, spec.hiddenDimensionStrategy, skipHeaders_1) }, (xValues ? { xValues: xValues } : {})), (sizeValues_1 ? { sizeValues: sizeValues_1 } : {})));
384
+ _53.label = 4;
385
+ case 4:
386
+ i++;
387
+ return [3 /*break*/, 1];
388
+ case 5:
389
+ sharedXValues = (_v = perSeriesX[0]) !== null && _v !== void 0 ? _v : [];
390
+ sharedSizeValues = (_w = perSeriesSize[0]) !== null && _w !== void 0 ? _w : [];
391
+ _b = (0, bubble_1.prepareBubbleSeriesData)({
392
+ xValues: sharedXValues,
393
+ labelValues: labels,
394
+ sizeValues: sharedSizeValues,
395
+ series: seriesInputs,
396
+ }), categories_1 = _b.categories, preparedSeries = _b.series, sizeValues = _b.sizeValues;
397
+ sizeScale_1 = (0, bubble_1.createBubbleSizeScale)(sizeValues);
398
+ hasStringX_1 = categories_1.length > 0;
399
+ palette_1 = [
400
+ theme.themeColors.accent1,
401
+ theme.themeColors.accent2,
402
+ theme.themeColors.accent3,
403
+ theme.themeColors.accent4,
404
+ theme.themeColors.accent5,
405
+ theme.themeColors.accent6,
406
+ ];
407
+ isScatter_1 = spec.chartType === "scatter";
408
+ scatterStyle_1 = (_x = spec.scatterStyle) !== null && _x !== void 0 ? _x : (isScatter_1 ? "lineMarker" : undefined);
409
+ plotlyModeForScatterStyle_1 = function (style) {
410
+ switch (style) {
411
+ case "line":
412
+ return "lines";
413
+ case "smooth":
414
+ return "lines";
415
+ case "marker":
416
+ return "markers";
417
+ case "smoothMarker":
418
+ return "lines+markers";
419
+ case "lineMarker":
420
+ default:
421
+ return "lines+markers";
422
+ }
423
+ };
424
+ lineShapeFor_1 = function (style) {
425
+ return style === "smooth" || style === "smoothMarker"
426
+ ? "spline"
427
+ : "linear";
428
+ };
429
+ traces_1 = preparedSeries.map(function (entry, index) {
430
+ var _a, _b, _c, _d, _e, _f;
431
+ var xValues = entry.points.map(function (point) {
432
+ var _a, _b;
433
+ return hasStringX_1
434
+ ? (_b = (_a = point.xLabel) !== null && _a !== void 0 ? _a : categories_1[Math.round(point.value[0])]) !== null && _b !== void 0 ? _b : point.value[0]
435
+ : point.value[0];
436
+ });
437
+ var yValues = entry.points.map(function (point) { return point.value[1]; });
438
+ var labelValuesForSeries = entry.points.map(function (point) { return point.name; });
439
+ var seriesColor = (_b = (_a = spec.series[index]) === null || _a === void 0 ? void 0 : _a.color) !== null && _b !== void 0 ? _b : palette_1[index % palette_1.length];
440
+ var perSeriesMarker = (_d = (_c = spec.series[index]) === null || _c === void 0 ? void 0 : _c.marker) !== null && _d !== void 0 ? _d : undefined;
441
+ if (isScatter_1) {
442
+ // Per-series marker.symbol = "none" → pure line (no markers).
443
+ // Per-series marker.size overrides the default. Falls back to
444
+ // chart-level scatterStyle for the line/marker mix.
445
+ var symbol = perSeriesMarker === null || perSeriesMarker === void 0 ? void 0 : perSeriesMarker.symbol;
446
+ var noMarkers = symbol === "none";
447
+ var mode = noMarkers
448
+ ? "lines"
449
+ : plotlyModeForScatterStyle_1(scatterStyle_1);
450
+ var markerSize = (_e = perSeriesMarker === null || perSeriesMarker === void 0 ? void 0 : perSeriesMarker.size) !== null && _e !== void 0 ? _e : 6;
451
+ var markerColor = (_f = perSeriesMarker === null || perSeriesMarker === void 0 ? void 0 : perSeriesMarker.color) !== null && _f !== void 0 ? _f : seriesColor;
452
+ return tslib_1.__assign({ type: "scatter", mode: mode, x: xValues, y: yValues, text: labelValuesForSeries, name: entry.name, hovertemplate: "%{text}<br>X: %{x}<br>Y: %{y}<extra></extra>", line: {
453
+ shape: lineShapeFor_1(scatterStyle_1),
454
+ color: seriesColor,
455
+ width: 2,
456
+ } }, (noMarkers
457
+ ? {}
458
+ : {
459
+ marker: {
460
+ size: markerSize,
461
+ color: markerColor,
462
+ symbol: (0, helpers_1.mapMarkerSymbolToPlotly)(symbol),
463
+ },
464
+ }));
465
+ }
466
+ // Bubble — third dimension scaled into marker diameter.
467
+ var rawSizes = entry.points.map(function (point) { return point.value[2]; });
468
+ var scaledSizes = rawSizes.map(function (value) { return sizeScale_1(value); });
469
+ return {
470
+ type: "scatter",
471
+ mode: "markers",
472
+ x: xValues,
473
+ y: yValues,
474
+ text: labelValuesForSeries,
475
+ customdata: rawSizes,
476
+ name: entry.name,
477
+ hovertemplate: "%{text}<br>X: %{x}<br>Y: %{y}<br>Size: %{customdata}<extra></extra>",
478
+ marker: {
479
+ size: scaledSizes,
480
+ sizemode: "diameter",
481
+ color: seriesColor,
482
+ opacity: 0.7,
483
+ },
484
+ };
485
+ });
486
+ titleFmt = spec.titleTextFormat;
487
+ xAxisFmt = (_y = spec.categoryAxisOptions) === null || _y === void 0 ? void 0 : _y.textFormat;
488
+ yAxisFmt = (_z = spec.valueAxisOptions) === null || _z === void 0 ? void 0 : _z.textFormat;
489
+ legendFmt = (_0 = spec.legend) === null || _0 === void 0 ? void 0 : _0.textFormat;
490
+ bubbleLayout = {
491
+ title: {
492
+ text: title !== null && title !== void 0 ? title : undefined,
493
+ font: {
494
+ family: (_1 = titleFmt === null || titleFmt === void 0 ? void 0 : titleFmt.fontFamily) !== null && _1 !== void 0 ? _1 : "Untitled Sans, apple-system, sans-serif",
495
+ size: (_2 = titleFmt === null || titleFmt === void 0 ? void 0 : titleFmt.fontSize) !== null && _2 !== void 0 ? _2 : 16,
496
+ color: (_3 = titleFmt === null || titleFmt === void 0 ? void 0 : titleFmt.color) !== null && _3 !== void 0 ? _3 : textColor,
497
+ },
498
+ x: 0.02,
499
+ xanchor: "left",
500
+ },
501
+ xaxis: {
502
+ title: {
503
+ text: (_4 = spec.horizontalAxisTitle) !== null && _4 !== void 0 ? _4 : "",
504
+ font: { color: (_5 = xAxisFmt === null || xAxisFmt === void 0 ? void 0 : xAxisFmt.color) !== null && _5 !== void 0 ? _5 : textColor },
505
+ },
506
+ gridcolor: gridColor,
507
+ tickfont: tslib_1.__assign(tslib_1.__assign({ color: (_6 = xAxisFmt === null || xAxisFmt === void 0 ? void 0 : xAxisFmt.color) !== null && _6 !== void 0 ? _6 : textColor }, ((xAxisFmt === null || xAxisFmt === void 0 ? void 0 : xAxisFmt.fontFamily) ? { family: xAxisFmt.fontFamily } : {})), ((xAxisFmt === null || xAxisFmt === void 0 ? void 0 : xAxisFmt.fontSize) ? { size: xAxisFmt.fontSize } : {})),
508
+ type: hasStringX_1 ? "category" : "linear",
509
+ },
510
+ yaxis: {
511
+ title: {
512
+ text: (_7 = spec.verticalAxisTitle) !== null && _7 !== void 0 ? _7 : "",
513
+ font: { color: (_8 = yAxisFmt === null || yAxisFmt === void 0 ? void 0 : yAxisFmt.color) !== null && _8 !== void 0 ? _8 : textColor },
514
+ },
515
+ gridcolor: gridColor,
516
+ tickfont: tslib_1.__assign(tslib_1.__assign({ color: (_9 = yAxisFmt === null || yAxisFmt === void 0 ? void 0 : yAxisFmt.color) !== null && _9 !== void 0 ? _9 : textColor }, ((yAxisFmt === null || yAxisFmt === void 0 ? void 0 : yAxisFmt.fontFamily) ? { family: yAxisFmt.fontFamily } : {})), ((yAxisFmt === null || yAxisFmt === void 0 ? void 0 : yAxisFmt.fontSize) ? { size: yAxisFmt.fontSize } : {})),
517
+ },
518
+ legend: {
519
+ font: tslib_1.__assign(tslib_1.__assign({ color: (_10 = legendFmt === null || legendFmt === void 0 ? void 0 : legendFmt.color) !== null && _10 !== void 0 ? _10 : textColor }, ((legendFmt === null || legendFmt === void 0 ? void 0 : legendFmt.fontFamily) ? { family: legendFmt.fontFamily } : {})), ((legendFmt === null || legendFmt === void 0 ? void 0 : legendFmt.fontSize) ? { size: legendFmt.fontSize } : {})),
520
+ },
521
+ paper_bgcolor: bgColor,
522
+ plot_bgcolor: bgColor,
523
+ showlegend: preparedSeries.length > 1,
524
+ margin: { l: 60, r: 20, t: 50, b: 50 },
525
+ };
526
+ setPlotData(traces_1);
527
+ setLayout(bubbleLayout);
528
+ return [2 /*return*/];
529
+ case 6:
530
+ if (isHierarchy) {
531
+ hierarchyRows = (0, hierarchy_1.extractHierarchyRows)(spec, {
532
+ getDomainValuesFromRange: getDomainValuesFromRange,
533
+ getSeriesValuesFromRange: getSeriesValuesFromRange,
534
+ hiddenDimensionStrategy: spec.hiddenDimensionStrategy,
535
+ });
536
+ headerTitle = (0, hierarchy_1.getHierarchyHeaderTitle)(spec, {
537
+ getDomainValuesFromRange: getDomainValuesFromRange,
538
+ getSeriesValuesFromRange: getSeriesValuesFromRange,
539
+ hiddenDimensionStrategy: spec.hiddenDimensionStrategy,
540
+ });
541
+ hierarchyTitleRef.current = explicitChartTitle !== null && explicitChartTitle !== void 0 ? explicitChartTitle : headerTitle;
542
+ hierarchyData = (0, hierarchy_1.toPlotlyHierarchy)(hierarchyRows);
543
+ seriesName = hierarchyData.labels.length === 1
544
+ ? (_11 = hierarchyData.labels[0]) !== null && _11 !== void 0 ? _11 : ""
545
+ : (_12 = explicitChartTitle !== null && explicitChartTitle !== void 0 ? explicitChartTitle : headerTitle) !== null && _12 !== void 0 ? _12 : "";
546
+ hierarchyTrace = {
547
+ type: chartType,
548
+ labels: hierarchyData.labels,
549
+ parents: hierarchyData.parents,
550
+ values: hierarchyData.values,
551
+ name: seriesName,
552
+ textinfo: "label+value",
553
+ branchvalues: "total",
554
+ };
555
+ layoutForHierarchy = {
556
+ title: {
557
+ text: title !== null && title !== void 0 ? title : undefined,
558
+ font: {
559
+ family: "Untitled Sans, apple-system, sans-serif",
560
+ size: 16,
561
+ color: textColor,
562
+ },
563
+ x: 0.02,
564
+ xanchor: "left",
565
+ },
566
+ font: {
567
+ family: "Untitled Sans, apple-system, sans-serif",
568
+ size: 12,
569
+ color: textColor,
570
+ },
571
+ paper_bgcolor: bgColor,
572
+ plot_bgcolor: bgColor,
573
+ showlegend: false,
574
+ margin: { l: 20, r: 20, t: 50, b: 20 },
575
+ };
576
+ setPlotData([hierarchyTrace]);
577
+ setLayout(layoutForHierarchy);
578
+ return [2 /*return*/];
579
+ }
580
+ hierarchyTitleRef.current = explicitChartTitle;
581
+ if (!isBasicChartSpec(spec)) {
582
+ (0, utils_1.debug)("Unsupported chart type", spec.chartType);
583
+ return [2 /*return*/];
584
+ }
585
+ // ------------------------- Region map -------------------------
586
+ // Filled map / choropleth (`chartType: "regionMap"`, or a payload
587
+ // degraded to another basic type carrying `sourceChartType:
588
+ // "REGION_MAP"`). Plotly ships its own world geometry, so this maps
589
+ // straight onto the built-in `choropleth` trace with
590
+ // `locationmode: "country names"` — plotly does its own (lenient)
591
+ // country-name matching and silently skips labels it can't place.
592
+ if ((0, region_map_1.isRegionMapSpec)(spec)) {
593
+ labels = flattenChartDataValues(spec.domains, getDomainValuesFromRange, spec.hiddenDimensionStrategy, false).map(function (v) { return String(v !== null && v !== void 0 ? v : "").trim(); });
594
+ seriesEntry = (_13 = spec.series) === null || _13 === void 0 ? void 0 : _13[0];
595
+ rawValues_1 = seriesEntry
596
+ ? flattenChartDataValues([seriesEntry], getSeriesValuesFromRange, spec.hiddenDimensionStrategy).map(function (v) { return (typeof v === "number" ? v : Number(v)); })
597
+ : [];
598
+ locations_1 = [];
599
+ z_1 = [];
600
+ labels.forEach(function (label, i) {
601
+ var value = rawValues_1[i];
602
+ if (label && typeof value === "number" && Number.isFinite(value)) {
603
+ locations_1.push(label);
604
+ z_1.push(value);
605
+ }
606
+ });
607
+ ramp_1 = (0, region_map_1.buildSequentialColorRamp)(theme.themeColors.accent1, !!isDarkMode);
608
+ colorscale = ramp_1.map(function (color, i) { return [i / (ramp_1.length - 1), color]; });
609
+ geoScope = (0, region_map_1.resolveGeoScope)(spec.geoScope);
610
+ regionTrace = {
611
+ type: "choropleth",
612
+ locations: locations_1,
613
+ z: z_1,
614
+ locationmode: "country names",
615
+ colorscale: colorscale,
616
+ marker: {
617
+ line: {
618
+ color: isDarkMode ? "rgba(255,255,255,0.3)" : "#FFFFFF",
619
+ width: 0.5,
620
+ },
621
+ },
622
+ colorbar: {
623
+ thickness: 10,
624
+ outlinewidth: 0,
625
+ tickfont: { color: textColor, size: 12 },
626
+ },
627
+ hovertemplate: "%{location}: %{z}<extra></extra>",
628
+ };
629
+ setPlotData([regionTrace]);
630
+ setLayout({
631
+ title: { text: title !== null && title !== void 0 ? title : undefined },
632
+ font: { color: textColor },
633
+ paper_bgcolor: bgColor,
634
+ plot_bgcolor: bgColor,
635
+ showlegend: false,
636
+ geo: {
637
+ scope: (PLOTLY_GEO_SCOPES.has(geoScope)
638
+ ? geoScope
639
+ : region_map_1.WORLD_GEO_SCOPE),
640
+ bgcolor: bgColor,
641
+ showframe: false,
642
+ showcoastlines: false,
643
+ // Regions without data keep a neutral land fill so "no data"
644
+ // reads differently from "small value".
645
+ showland: true,
646
+ landcolor: isDarkMode
647
+ ? "rgba(255,255,255,0.08)"
648
+ : "rgba(0,0,0,0.06)",
649
+ },
650
+ margin: { l: 20, r: 20, t: 50, b: 20 },
651
+ autosize: true,
652
+ });
653
+ return [2 /*return*/];
654
+ }
655
+ // ---------------------------- Radar ----------------------------
656
+ // Plotly renders radar via `scatterpolar` traces: r = the values,
657
+ // theta = the category names (closed by appending the first point).
658
+ if (spec.chartType === "radar") {
659
+ categories = flattenChartDataValues(spec.domains, getDomainValuesFromRange, spec.hiddenDimensionStrategy, false).map(function (v) { return String(v !== null && v !== void 0 ? v : ""); });
660
+ radarStyle = (_14 = spec.radarStyle) !== null && _14 !== void 0 ? _14 : "standard";
661
+ radarTraces = [];
662
+ radarInputs = [];
663
+ try {
664
+ for (_c = tslib_1.__values((_15 = spec.series) !== null && _15 !== void 0 ? _15 : []), _d = _c.next(); !_d.done; _d = _c.next()) {
665
+ seriesEntry = _d.value;
666
+ label = seriesEntry.dataLabel && !(0, utils_1.isAFormula)(seriesEntry.dataLabel)
667
+ ? seriesEntry.dataLabel
668
+ : "";
669
+ values = flattenChartDataValues([seriesEntry], getSeriesValuesFromRange, spec.hiddenDimensionStrategy).map(function (v) { return (typeof v === "number" ? v : Number(v)); });
670
+ radarInputs.push({ name: label, values: values });
671
+ }
672
+ }
673
+ catch (e_2_1) { e_2 = { error: e_2_1 }; }
674
+ finally {
675
+ try {
676
+ if (_d && !_d.done && (_l = _c.return)) _l.call(_c);
677
+ }
678
+ finally { if (e_2) throw e_2.error; }
679
+ }
680
+ indicators = (0, radar_1.buildRadarIndicators)(categories, radarInputs);
681
+ _loop_1 = function (i) {
682
+ var input = radarInputs[i];
683
+ var seriesColor = (_18 = (_17 = (_16 = spec.series) === null || _16 === void 0 ? void 0 : _16[i]) === null || _17 === void 0 ? void 0 : _17.color) !== null && _18 !== void 0 ? _18 : undefined;
684
+ var r = indicators.map(function (_, idx) { var _a; return (_a = input.values[idx]) !== null && _a !== void 0 ? _a : 0; });
685
+ var theta = indicators.map(function (ind) { return ind.name; });
686
+ radarTraces.push(tslib_1.__assign(tslib_1.__assign({ type: "scatterpolar", r: r.length ? tslib_1.__spreadArray(tslib_1.__spreadArray([], tslib_1.__read(r), false), [r[0]], false) : r, theta: theta.length ? tslib_1.__spreadArray(tslib_1.__spreadArray([], tslib_1.__read(theta), false), [theta[0]], false) : theta, name: input.name, mode: radarStyle === "standard" ? "lines" : "lines+markers" }, (radarStyle === "filled" ? { fill: "toself" } : {})), (seriesColor ? { line: { color: seriesColor } } : {})));
687
+ };
688
+ for (i = 0; i < radarInputs.length; i++) {
689
+ _loop_1(i);
690
+ }
691
+ maxR = indicators.reduce(function (m, ind) { return Math.max(m, ind.max); }, 0);
692
+ setPlotData(radarTraces);
693
+ setLayout({
694
+ title: { text: title !== null && title !== void 0 ? title : undefined },
695
+ font: { color: textColor },
696
+ paper_bgcolor: bgColor,
697
+ plot_bgcolor: bgColor,
698
+ showlegend: radarTraces.length > 1,
699
+ polar: {
700
+ radialaxis: {
701
+ visible: true,
702
+ range: [0, maxR > 0 ? maxR : 1],
703
+ },
704
+ },
705
+ margin: { l: 50, r: 50, t: 50, b: 50 },
706
+ autosize: true,
707
+ });
708
+ return [2 /*return*/];
709
+ }
710
+ // ---------------------------- Stock ----------------------------
711
+ // Line-derived stock: one scatter line trace per price role. The
712
+ // V-variants additionally get a volume column sub-pane below the
713
+ // price plot.
714
+ if (spec.chartType === "stock") {
715
+ variant = ((_19 = spec.stockVariant) !== null && _19 !== void 0 ? _19 : "HLC");
716
+ categories = flattenChartDataValues(spec.domains, getDomainValuesFromRange, spec.hiddenDimensionStrategy, false).map(function (v) { return String(v !== null && v !== void 0 ? v : ""); });
717
+ seriesValues = ((_20 = spec.series) !== null && _20 !== void 0 ? _20 : []).map(function (seriesEntry) {
718
+ return flattenChartDataValues([seriesEntry], getSeriesValuesFromRange, spec.hiddenDimensionStrategy).map(function (v) { return (typeof v === "number" ? v : Number(v)); });
719
+ });
720
+ volumePoints_1 = (0, stock_1.toVolumeSeries)(seriesValues, variant);
721
+ hasVolume = ((_21 = volumePoints_1 === null || volumePoints_1 === void 0 ? void 0 : volumePoints_1.length) !== null && _21 !== void 0 ? _21 : 0) > 0;
722
+ buildVolumeTrace = function (xs) {
723
+ return ({
724
+ type: "bar",
725
+ x: xs,
726
+ y: (volumePoints_1 !== null && volumePoints_1 !== void 0 ? volumePoints_1 : []).map(function (p) { return p.value; }),
727
+ name: "Volume",
728
+ yaxis: "y2",
729
+ showlegend: false,
730
+ marker: {
731
+ color: (volumePoints_1 !== null && volumePoints_1 !== void 0 ? volumePoints_1 : []).map(function (p) {
732
+ return p.up ? theme.themeColors.accent1 : theme.themeColors.accent2;
733
+ }),
734
+ },
735
+ });
736
+ };
737
+ volumeLayout = hasVolume
738
+ ? {
739
+ yaxis2: {
740
+ domain: [0, 0.22],
741
+ automargin: true,
742
+ showgrid: false,
743
+ showticklabels: false,
744
+ },
745
+ }
746
+ : {};
747
+ priceYAxisDomain = hasVolume ? { domain: [0.3, 1] } : {};
748
+ // OHLC / VOHLC variants render as a native candlestick; HLC / VHLC
749
+ // (no open) fall through to the line-derived rendering below.
750
+ if (variant === "OHLC" || variant === "VOHLC") {
751
+ roles = (0, stock_1.assignStockRoles)(seriesValues, variant);
752
+ xs_1 = categories.length > 0
753
+ ? categories
754
+ : ((_22 = roles.close) !== null && _22 !== void 0 ? _22 : []).map(function (_, i) { return i + 1; });
755
+ candleTrace = {
756
+ type: "candlestick",
757
+ x: xs_1,
758
+ open: ((_23 = roles.open) !== null && _23 !== void 0 ? _23 : []).map(function (v) { return v !== null && v !== void 0 ? v : null; }),
759
+ high: ((_24 = roles.high) !== null && _24 !== void 0 ? _24 : []).map(function (v) { return v !== null && v !== void 0 ? v : null; }),
760
+ low: ((_25 = roles.low) !== null && _25 !== void 0 ? _25 : []).map(function (v) { return v !== null && v !== void 0 ? v : null; }),
761
+ close: ((_26 = roles.close) !== null && _26 !== void 0 ? _26 : []).map(function (v) { return v !== null && v !== void 0 ? v : null; }),
762
+ increasing: { line: { color: theme.themeColors.accent1 } },
763
+ decreasing: { line: { color: theme.themeColors.accent2 } },
764
+ };
765
+ setPlotData(hasVolume ? [candleTrace, buildVolumeTrace(xs_1)] : [candleTrace]);
766
+ setLayout(tslib_1.__assign(tslib_1.__assign({ title: { text: title !== null && title !== void 0 ? title : undefined }, font: { color: textColor }, paper_bgcolor: bgColor, plot_bgcolor: bgColor, showlegend: false, xaxis: {
767
+ title: { text: (_27 = spec.horizontalAxisTitle) !== null && _27 !== void 0 ? _27 : "" },
768
+ automargin: true,
769
+ showgrid: true,
770
+ gridcolor: gridColor,
771
+ rangeslider: { visible: false },
772
+ }, yaxis: tslib_1.__assign({ title: { text: (_28 = spec.verticalAxisTitle) !== null && _28 !== void 0 ? _28 : "" }, automargin: true, showgrid: true, gridcolor: gridColor }, priceYAxisDomain) }, volumeLayout), { margin: { l: 50, r: 50, t: 50, b: 50 }, autosize: true }));
773
+ return [2 /*return*/];
774
+ }
775
+ lineSeries = (0, stock_1.toLineSeries)(seriesValues, variant);
776
+ stockPalette_1 = [
777
+ theme.themeColors.accent1,
778
+ theme.themeColors.accent2,
779
+ theme.themeColors.accent3,
780
+ theme.themeColors.accent4,
781
+ ];
782
+ xs_2 = categories.length > 0
783
+ ? categories
784
+ : ((_30 = (_29 = lineSeries[0]) === null || _29 === void 0 ? void 0 : _29.values) !== null && _30 !== void 0 ? _30 : []).map(function (_, i) { return i + 1; });
785
+ stockTraces = lineSeries.map(function (s, i) { return ({
786
+ type: "scatter",
787
+ mode: "lines",
788
+ x: xs_2,
789
+ y: s.values.map(function (v) { return (v !== null && v !== void 0 ? v : null); }),
790
+ name: s.name,
791
+ line: { color: stockPalette_1[i % stockPalette_1.length] },
792
+ }); });
793
+ setPlotData(hasVolume ? tslib_1.__spreadArray(tslib_1.__spreadArray([], tslib_1.__read(stockTraces), false), [buildVolumeTrace(xs_2)], false) : stockTraces);
794
+ setLayout(tslib_1.__assign(tslib_1.__assign({ title: { text: title !== null && title !== void 0 ? title : undefined }, font: { color: textColor }, paper_bgcolor: bgColor, plot_bgcolor: bgColor, showlegend: stockTraces.length > 1, xaxis: {
795
+ title: { text: (_31 = spec.horizontalAxisTitle) !== null && _31 !== void 0 ? _31 : "" },
796
+ automargin: true,
797
+ showgrid: true,
798
+ gridcolor: gridColor,
799
+ }, yaxis: tslib_1.__assign({ title: { text: (_32 = spec.verticalAxisTitle) !== null && _32 !== void 0 ? _32 : "" }, automargin: true, showgrid: true, gridcolor: gridColor }, priceYAxisDomain) }, volumeLayout), { margin: { l: 50, r: 50, t: 50, b: 50 }, autosize: true }));
800
+ return [2 /*return*/];
801
+ }
802
+ isStacked = spec.stackedType && spec.stackedType !== "UNSTACKED";
803
+ isHorizontalBarChart = spec.chartType === "bar";
804
+ shouldAggregate = (0, aggregation_1.shouldAggregateSeries)(spec.series);
805
+ primaryDomainSource = (_35 = (_34 = (_33 = spec === null || spec === void 0 ? void 0 : spec.domains) === null || _33 === void 0 ? void 0 : _33[0]) === null || _34 === void 0 ? void 0 : _34.sources) === null || _35 === void 0 ? void 0 : _35[0];
806
+ rawPrimaryDomainValues = primaryDomainSource
807
+ ? (0, aggregation_1.sanitizeDomainValues)((_36 = getDomainValuesFromRange(primaryDomainSource, spec.hiddenDimensionStrategy)) !== null && _36 !== void 0 ? _36 : [])
808
+ : [];
809
+ domainData = (0, aggregation_1.getDomainValuesForAxis)(rawPrimaryDomainValues, shouldAggregate);
810
+ (_37 = spec.domains) === null || _37 === void 0 ? void 0 : _37.forEach(function (domain, domainIndex) {
811
+ domain.sources.forEach(function (sheetRange, sourceIndex) {
812
+ var _a;
813
+ if (domainIndex === 0 && sourceIndex === 0) {
814
+ domainData = (0, aggregation_1.getDomainValuesForAxis)(rawPrimaryDomainValues, shouldAggregate);
815
+ }
816
+ else {
817
+ var rawValues = (0, aggregation_1.sanitizeDomainValues)((_a = getDomainValuesFromRange(sheetRange, spec.hiddenDimensionStrategy)) !== null && _a !== void 0 ? _a : []);
818
+ domainData = (0, aggregation_1.getDomainValuesForAxis)(rawValues, shouldAggregate);
819
+ }
820
+ });
821
+ });
822
+ assignCartesianData = function (categories, values) {
823
+ // Convert undefined to null for Plotly (Datum type accepts null but not undefined)
824
+ var plotlyValues = values.map(function (v) { return v !== null && v !== void 0 ? v : null; });
825
+ // When categories is empty but we have values, generate index-based x values
826
+ // so Plotly can render the chart
827
+ var effectiveCategories = categories.length === 0 && plotlyValues.length > 0
828
+ ? Array.from({ length: plotlyValues.length }, function (_, i) { return i + 1; })
829
+ : categories;
830
+ if (isHorizontalBarChart) {
831
+ return {
832
+ x: plotlyValues,
833
+ y: effectiveCategories,
834
+ orientation: "h",
835
+ };
836
+ }
837
+ return { x: effectiveCategories, y: plotlyValues, orientation: undefined };
838
+ };
839
+ themeColorPalette = [
840
+ theme.themeColors.accent1,
841
+ theme.themeColors.accent2,
842
+ theme.themeColors.accent3,
843
+ theme.themeColors.accent4,
844
+ theme.themeColors.accent5,
845
+ theme.themeColors.accent6,
846
+ ];
847
+ applyTraceColor = function (trace, seriesColor, options) {
848
+ var e_4, _a;
849
+ var _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r;
850
+ var target = trace;
851
+ var chartTypeForStyling = (_b = options === null || options === void 0 ? void 0 : options.effectiveChartType) !== null && _b !== void 0 ? _b : spec.chartType;
852
+ var isBarOrColumn = chartTypeForStyling === "bar" || chartTypeForStyling === "column";
853
+ // Transparent series (Gantt lag offset). Set marker color to
854
+ // `rgba(0,0,0,0)` so the bar layout is preserved but invisible.
855
+ if (options === null || options === void 0 ? void 0 : options.noFill) {
856
+ target.marker = tslib_1.__assign(tslib_1.__assign({}, ((_c = target.marker) !== null && _c !== void 0 ? _c : {})), { color: "rgba(0,0,0,0)", line: tslib_1.__assign(tslib_1.__assign({}, ((_e = (_d = target.marker) === null || _d === void 0 ? void 0 : _d.line) !== null && _e !== void 0 ? _e : {})), { color: "rgba(0,0,0,0)", width: 0 }) });
857
+ return trace;
858
+ }
859
+ // Get effective color - gradient fallback wins, then series color,
860
+ // then theme palette. Plotly cannot paint the real gradient, so the
861
+ // median stop stands in for the whole ramp.
862
+ var effectiveColor = (_g = (_f = options === null || options === void 0 ? void 0 : options.gradientColor) !== null && _f !== void 0 ? _f : seriesColor) !== null && _g !== void 0 ? _g : ((options === null || options === void 0 ? void 0 : options.seriesIndex) !== undefined
863
+ ? themeColorPalette[options.seriesIndex % themeColorPalette.length]
864
+ : undefined);
865
+ // Per-data-point color overrides — Gantt charts use `<c:dPt>` to
866
+ // give every task its own color. Build a per-point color array
867
+ // by category index, falling back to the series color for points
868
+ // without an override.
869
+ if (isBarOrColumn &&
870
+ Array.isArray(options === null || options === void 0 ? void 0 : options.dataPointColors) &&
871
+ (options === null || options === void 0 ? void 0 : options.dataPointColors.length)) {
872
+ var overrides_1 = new Map();
873
+ try {
874
+ for (var _s = tslib_1.__values(options.dataPointColors), _t = _s.next(); !_t.done; _t = _s.next()) {
875
+ var dp = _t.value;
876
+ if (typeof dp.idx === "number" && typeof dp.color === "string") {
877
+ overrides_1.set(dp.idx, dp.color);
878
+ }
879
+ }
880
+ }
881
+ catch (e_4_1) { e_4 = { error: e_4_1 }; }
882
+ finally {
883
+ try {
884
+ if (_t && !_t.done && (_a = _s.return)) _a.call(_s);
885
+ }
886
+ finally { if (e_4) throw e_4.error; }
887
+ }
888
+ var fallback_1 = effectiveColor !== null && effectiveColor !== void 0 ? effectiveColor : "#4285F4";
889
+ var yArray = Array.isArray(target.y)
890
+ ? target.y
891
+ : Array.isArray(target.x)
892
+ ? target.x
893
+ : [];
894
+ var colors = yArray.map(function (_, i) { var _a; return (_a = overrides_1.get(i)) !== null && _a !== void 0 ? _a : fallback_1; });
895
+ target.marker = tslib_1.__assign(tslib_1.__assign({}, ((_h = target.marker) !== null && _h !== void 0 ? _h : {})), { color: colors });
896
+ return trace;
897
+ }
898
+ // Handle invertIfNegative for bar/column charts
899
+ if (isBarOrColumn && (options === null || options === void 0 ? void 0 : options.invertIfNegative) && (options === null || options === void 0 ? void 0 : options.values)) {
900
+ var positiveColor_1 = effectiveColor !== null && effectiveColor !== void 0 ? effectiveColor : "#4285F4";
901
+ var negColor_1 = (_j = options.negativeColor) !== null && _j !== void 0 ? _j : "#FF0000";
902
+ // Create array of colors based on value sign
903
+ var colors = options.values.map(function (v) {
904
+ return typeof v === "number" && v < 0 ? negColor_1 : positiveColor_1;
905
+ });
906
+ target.marker = tslib_1.__assign(tslib_1.__assign({}, ((_k = target.marker) !== null && _k !== void 0 ? _k : {})), { color: colors });
907
+ return trace;
908
+ }
909
+ if (!effectiveColor) {
910
+ return trace;
911
+ }
912
+ if (chartTypeForStyling === "pie") {
913
+ // Don't clobber the distinct per-slice palette the trace was built
914
+ // with (accent1..accent6) with a single repeated color. Only repeat
915
+ // a uniform color when the user explicitly authored a series color;
916
+ // otherwise keep the multi-color palette so each slice stays distinct.
917
+ var existingColors = (_l = target.marker) === null || _l === void 0 ? void 0 : _l.colors;
918
+ if (!seriesColor &&
919
+ Array.isArray(existingColors) &&
920
+ existingColors.length > 1) {
921
+ return trace;
922
+ }
923
+ var labelCount = Array.isArray(target.labels)
924
+ ? target.labels.length
925
+ : Array.isArray(target.y)
926
+ ? target.y.length
927
+ : 0;
928
+ target.marker = tslib_1.__assign(tslib_1.__assign({}, ((_m = target.marker) !== null && _m !== void 0 ? _m : {})), { colors: labelCount > 0
929
+ ? Array.from({ length: labelCount }, function () { return effectiveColor; })
930
+ : (_o = target.marker) === null || _o === void 0 ? void 0 : _o.colors, color: effectiveColor });
931
+ return trace;
932
+ }
933
+ if (isBarOrColumn) {
934
+ target.marker = tslib_1.__assign(tslib_1.__assign({}, ((_p = target.marker) !== null && _p !== void 0 ? _p : {})), { color: effectiveColor });
935
+ return trace;
936
+ }
937
+ target.marker = tslib_1.__assign(tslib_1.__assign({}, ((_q = target.marker) !== null && _q !== void 0 ? _q : {})), { color: effectiveColor });
938
+ target.line = tslib_1.__assign(tslib_1.__assign({}, ((_r = target.line) !== null && _r !== void 0 ? _r : {})), { color: effectiveColor });
939
+ if (target.fill && target.fill !== "none") {
940
+ // Add transparency to area fills so they don't cover other traces
941
+ target.fillcolor = addAlphaToColor(effectiveColor, 0.5);
942
+ }
943
+ return trace;
944
+ };
945
+ hasSecondaryAxis = false;
946
+ isPareto = spec.chartType === "histogram" && (0, histogram_1.isParetoSpec)(spec);
947
+ isOfPie = spec.chartType === "pie" && (0, of_pie_1.isOfPieChartSpec)(spec);
948
+ ofPieHandled = false;
949
+ ofPieExtras = null;
950
+ decorateCartesianTrace = function (trace, series, values, dataLabel) {
951
+ var e_5, _a;
952
+ var _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
953
+ var target = trace;
954
+ // Secondary value axis. Plotly overlays a second y-axis named
955
+ // "y2" and the trace points at it via `yaxis: "y2"`.
956
+ if (series.useSecondaryAxis) {
957
+ target.yaxis = "y2";
958
+ hasSecondaryAxis = true;
959
+ }
960
+ // Error bars — native plotly `error_y` / `error_x`. valueType
961
+ // "custom" reads per-point magnitudes from the spec's plus/minus
962
+ // ranges, resolved through the same extractor the series values
963
+ // use.
964
+ var magnitudes = (0, error_bars_1.computeErrorBars)(values, (0, error_bars_1.resolveCustomErrorBarValues)(series.errorBars, function (range) {
965
+ return getSeriesValuesFromRange(range, spec.hiddenDimensionStrategy);
966
+ }));
967
+ if (magnitudes) {
968
+ var direction = (_c = (_b = series.errorBars) === null || _b === void 0 ? void 0 : _b.direction) !== null && _c !== void 0 ? _c : "y";
969
+ var noEndCap = (_e = (_d = series.errorBars) === null || _d === void 0 ? void 0 : _d.noEndCap) !== null && _e !== void 0 ? _e : false;
970
+ var symmetric = magnitudes.plus.every(function (p, i) { return p === magnitudes.minus[i]; });
971
+ var errorConfig = tslib_1.__assign(tslib_1.__assign(tslib_1.__assign({ type: "data", symmetric: symmetric, array: magnitudes.plus }, (symmetric ? {} : { arrayminus: magnitudes.minus })), { color: (_f = series.color) !== null && _f !== void 0 ? _f : undefined }), (noEndCap ? { width: 0 } : {}));
972
+ if (direction === "x") {
973
+ target.error_x = errorConfig;
974
+ }
975
+ else {
976
+ target.error_y = errorConfig;
977
+ }
978
+ }
979
+ // Trendlines — one overlay scatter trace per spec, reusing the
980
+ // shared regression util.
981
+ var seriesColor = (_g = series.color) !== null && _g !== void 0 ? _g : theme.themeColors.accent1;
982
+ try {
983
+ for (var _m = tslib_1.__values((_h = series.trendlines) !== null && _h !== void 0 ? _h : []), _o = _m.next(); !_o.done; _o = _m.next()) {
984
+ var tl = _o.value;
985
+ var result = (0, trendline_1.computeTrendline)(values, {
986
+ type: tl.type,
987
+ order: tl.order,
988
+ period: tl.period,
989
+ forecastForward: tl.forecastForward,
990
+ forecastBackward: tl.forecastBackward,
991
+ });
992
+ if (!result || result.points.length < 2)
993
+ continue;
994
+ var tlName = (_j = tl.name) !== null && _j !== void 0 ? _j : "".concat(dataLabel ? dataLabel + " " : "").concat((_k = tl.type) !== null && _k !== void 0 ? _k : "linear", " trend");
995
+ // Map the fitted x (category index) back onto the category
996
+ // labels where possible so the line aligns with the data.
997
+ var xs = result.points.map(function (p) {
998
+ return p.x >= 0 && p.x < domainData.length ? domainData[p.x] : p.x;
999
+ });
1000
+ var ys = result.points.map(function (p) { return p.y; });
1001
+ var overlay = tslib_1.__assign({ type: "scatter", mode: "lines", name: tlName, line: {
1002
+ color: (_l = tl.color) !== null && _l !== void 0 ? _l : seriesColor,
1003
+ dash: "dash",
1004
+ width: 2,
1005
+ }, hoverinfo: "skip" }, (series.useSecondaryAxis ? { yaxis: "y2" } : {}));
1006
+ if (isHorizontalBarChart) {
1007
+ overlay.x = ys;
1008
+ overlay.y = xs;
1009
+ overlay.orientation = "h";
1010
+ }
1011
+ else {
1012
+ overlay.x = xs;
1013
+ overlay.y = ys;
1014
+ }
1015
+ traces.push(overlay);
1016
+ }
1017
+ }
1018
+ catch (e_5_1) { e_5 = { error: e_5_1 }; }
1019
+ finally {
1020
+ try {
1021
+ if (_o && !_o.done && (_a = _m.return)) _a.call(_m);
1022
+ }
1023
+ finally { if (e_5) throw e_5.error; }
1024
+ }
1025
+ };
1026
+ seriesIndex = 0;
1027
+ _53.label = 7;
1028
+ case 7:
1029
+ _53.trys.push([7, 14, 15, 16]);
1030
+ _e = tslib_1.__values((_38 = spec.series) !== null && _38 !== void 0 ? _38 : []), _f = _e.next();
1031
+ _53.label = 8;
1032
+ case 8:
1033
+ if (!!_f.done) return [3 /*break*/, 13];
1034
+ series = _f.value;
1035
+ currentSeriesIndex = seriesIndex++;
1036
+ if (!(!(0, utils_1.isNil)(series.dataLabel) && (0, utils_1.isAFormula)(series.dataLabel))) return [3 /*break*/, 10];
1037
+ _h = chart_spec_utils_1.coerceCalculatedLabel;
1038
+ return [4 /*yield*/, onRequestCalculate(series.dataLabel, (_39 = position.sheetId) !== null && _39 !== void 0 ? _39 : sheetId, position.overlayPosition.anchorCell.rowIndex, position.overlayPosition.anchorCell.columnIndex)];
1039
+ case 9:
1040
+ _g = _h.apply(void 0, [_53.sent()]);
1041
+ return [3 /*break*/, 11];
1042
+ case 10:
1043
+ _g = (_40 = series.dataLabel) !== null && _40 !== void 0 ? _40 : "";
1044
+ _53.label = 11;
1045
+ case 11:
1046
+ dataLabel = _g;
1047
+ _loop_2 = function (sheetRange) {
1048
+ var seriesData = getSeriesData(spec, sheetRange, {
1049
+ aggregateEnabled: shouldAggregate,
1050
+ aggregateType: series.aggregateType,
1051
+ rawDomainValues: rawPrimaryDomainValues,
1052
+ orderedDomainValues: domainData,
1053
+ });
1054
+ // Support per-series chart type for combo charts
1055
+ var effectiveChartType = (_41 = series.seriesChartType) !== null && _41 !== void 0 ? _41 : spec.chartType;
1056
+ var seriesPlotlyType = (0, helpers_1.chartTypeToPlotlyType)(effectiveChartType);
1057
+ var seriesTraceStyle = (0, helpers_1.getPlotlyTraceStyle)(effectiveChartType);
1058
+ if (effectiveChartType === "histogram") {
1059
+ var rawValues = "values" in seriesData
1060
+ ? seriesData.values
1061
+ : seriesData;
1062
+ var binCount = spec.binCount;
1063
+ if (isPareto) {
1064
+ // Plotly's native histogram trace bins in axis order and
1065
+ // can't reorder bins, so Pareto pre-bins with the shared
1066
+ // util, sorts descending, and renders a bar trace plus the
1067
+ // cumulative-% line pointed at the y2 overlay axis.
1068
+ var _54 = (0, histogram_1.computePareto)((0, histogram_1.binHistogram)(rawValues, binCount)), labels = _54.labels, counts = _54.counts, cumulativePercents = _54.cumulativePercents;
1069
+ var barTrace = {
1070
+ type: "bar",
1071
+ x: labels,
1072
+ y: counts,
1073
+ name: dataLabel,
1074
+ };
1075
+ applyTraceColor(barTrace, (_42 = series.color) !== null && _42 !== void 0 ? _42 : undefined, {
1076
+ noFill: series.noFill,
1077
+ dataPointColors: series.dataPointColors,
1078
+ seriesIndex: currentSeriesIndex,
1079
+ effectiveChartType: effectiveChartType,
1080
+ });
1081
+ traces.push(barTrace);
1082
+ traces.push({
1083
+ type: "scatter",
1084
+ mode: "lines+markers",
1085
+ x: labels,
1086
+ y: cumulativePercents,
1087
+ name: "Cumulative %",
1088
+ yaxis: "y2",
1089
+ });
1090
+ hasSecondaryAxis = true;
1091
+ }
1092
+ else {
1093
+ var trace = tslib_1.__assign({ type: "histogram", x: rawValues.map(function (v) { return (v !== null && v !== void 0 ? v : null); }), name: dataLabel }, (typeof binCount === "number" && binCount > 0
1094
+ ? { nbinsx: binCount }
1095
+ : {}));
1096
+ applyTraceColor(trace, (_43 = series.color) !== null && _43 !== void 0 ? _43 : undefined, {
1097
+ noFill: series.noFill,
1098
+ dataPointColors: series.dataPointColors,
1099
+ seriesIndex: currentSeriesIndex,
1100
+ effectiveChartType: effectiveChartType,
1101
+ });
1102
+ traces.push(trace);
1103
+ }
1104
+ }
1105
+ else if (effectiveChartType === "boxplot") {
1106
+ var rawValues = "values" in seriesData
1107
+ ? seriesData.values
1108
+ : seriesData;
1109
+ var quartileMethod = spec.quartileMethod;
1110
+ var showOutliers = spec.showOutliers;
1111
+ var showMeanMarker = spec.showMeanMarker === true;
1112
+ // Plotly's box trace computes quartiles/fences itself from
1113
+ // raw values, so a spec-pinned quartile method (or Excel's
1114
+ // "no outliers → whiskers span min/max" semantics) requires
1115
+ // switching to plotly's precomputed-statistics signature
1116
+ // (q1/median/q3/lowerfence/upperfence arrays). When neither
1117
+ // option is set the raw-values trace is kept unchanged.
1118
+ var usePrecomputed = quartileMethod != null || showOutliers === false;
1119
+ var trace = void 0;
1120
+ if (usePrecomputed) {
1121
+ var summary = (0, boxplot_1.computeBoxplotSummary)(rawValues, {
1122
+ quartileMethod: quartileMethod,
1123
+ });
1124
+ if (!summary)
1125
+ return "continue";
1126
+ var hideOutliers = showOutliers === false;
1127
+ trace = tslib_1.__assign(tslib_1.__assign({ type: "box", name: dataLabel,
1128
+ // Precomputed boxes need an explicit category so each
1129
+ // series lands on its own slot (raw mode derives it from
1130
+ // the trace name).
1131
+ x: [dataLabel || "trace ".concat(currentSeriesIndex)], q1: [summary.q1], median: [summary.median], q3: [summary.q3],
1132
+ // Excel: hiding outlier points extends the whiskers to
1133
+ // the full min/max; with outliers shown they stop at the
1134
+ // most extreme points inside the 1.5×IQR fences.
1135
+ lowerfence: [hideOutliers ? summary.min : summary.lowerWhisker], upperfence: [hideOutliers ? summary.max : summary.upperWhisker] }, (hideOutliers
1136
+ ? { boxpoints: false }
1137
+ : {
1138
+ // Sample points ride along so plotly can still draw
1139
+ // the outlier dots against the precomputed fences.
1140
+ y: [rawValues.filter(function (v) { return v != null; })],
1141
+ boxpoints: "outliers",
1142
+ })), (showMeanMarker
1143
+ ? { mean: [summary.mean], boxmean: true }
1144
+ : {}));
1145
+ }
1146
+ else {
1147
+ trace = tslib_1.__assign({ type: "box", y: rawValues.map(function (v) { return (v !== null && v !== void 0 ? v : null); }), name: dataLabel,
1148
+ // Raw mode is used when outliers are visible (today's
1149
+ // default and `showOutliers: true` alike).
1150
+ boxpoints: "outliers" }, (showMeanMarker ? { boxmean: true } : {}));
1151
+ }
1152
+ applyTraceColor(trace, (_44 = series.color) !== null && _44 !== void 0 ? _44 : undefined, {
1153
+ noFill: series.noFill,
1154
+ dataPointColors: series.dataPointColors,
1155
+ seriesIndex: currentSeriesIndex,
1156
+ effectiveChartType: effectiveChartType,
1157
+ });
1158
+ traces.push(trace);
1159
+ }
1160
+ else if (effectiveChartType === "waterfall") {
1161
+ var rawValues = "values" in seriesData
1162
+ ? seriesData.values
1163
+ : seriesData;
1164
+ // Plotly's native waterfall draws connector lines itself and
1165
+ // renders "total" measures from the zero baseline with its
1166
+ // own distinct fill.
1167
+ var totalIndices_1 = new Set((_45 = spec.totalIndices) !== null && _45 !== void 0 ? _45 : []);
1168
+ var trace = {
1169
+ type: "waterfall",
1170
+ x: domainData,
1171
+ y: rawValues.map(function (v) { return (v !== null && v !== void 0 ? v : null); }),
1172
+ measure: rawValues.map(function (_, i) {
1173
+ return totalIndices_1.has(i) ? "total" : "relative";
1174
+ }),
1175
+ name: dataLabel,
1176
+ };
1177
+ applyTraceColor(trace, (_46 = series.color) !== null && _46 !== void 0 ? _46 : undefined, {
1178
+ noFill: series.noFill,
1179
+ dataPointColors: series.dataPointColors,
1180
+ seriesIndex: currentSeriesIndex,
1181
+ effectiveChartType: effectiveChartType,
1182
+ });
1183
+ traces.push(trace);
1184
+ }
1185
+ else if (effectiveChartType === "funnel") {
1186
+ var rawValues = "values" in seriesData
1187
+ ? seriesData.values
1188
+ : seriesData;
1189
+ var trace = {
1190
+ type: "funnel",
1191
+ y: domainData,
1192
+ x: rawValues.map(function (v) { return (v !== null && v !== void 0 ? v : null); }),
1193
+ name: dataLabel,
1194
+ };
1195
+ applyTraceColor(trace, (_47 = series.color) !== null && _47 !== void 0 ? _47 : undefined, {
1196
+ noFill: series.noFill,
1197
+ dataPointColors: series.dataPointColors,
1198
+ seriesIndex: currentSeriesIndex,
1199
+ effectiveChartType: effectiveChartType,
1200
+ });
1201
+ traces.push(trace);
1202
+ }
1203
+ else if (effectiveChartType === "pie" && isOfPie) {
1204
+ // Pie-of-pie / bar-of-pie — split the minor slices into a
1205
+ // secondary pie or stacked bar beside the main pie, replace
1206
+ // them with an aggregated "Other" slice, and join the two
1207
+ // plots with connector-line shapes. Only the first pie series
1208
+ // participates (of-pie is a single-series chart in Excel).
1209
+ if (ofPieHandled)
1210
+ return "continue";
1211
+ ofPieHandled = true;
1212
+ var pieData = seriesData;
1213
+ var _55 = (0, of_pie_1.splitOfPie)(pieData.values, pieData.labels, {
1214
+ splitType: spec.splitType,
1215
+ splitPos: spec.splitPos,
1216
+ }), main_1 = _55.main, secondary = _55.secondary, otherTotal = _55.otherTotal, total = _55.total;
1217
+ var ofPieType = (0, of_pie_1.resolveOfPieType)(spec.ofPieType);
1218
+ var secondScale = (0, of_pie_1.clampSecondPieSize)(spec.secondPieSize) / 100;
1219
+ var halfAngle = (0, of_pie_1.otherSliceHalfAngle)(otherTotal, total);
1220
+ var paletteAt_1 = function (index) {
1221
+ return themeColorPalette[index % themeColorPalette.length];
1222
+ };
1223
+ // Layout in paper coordinates (0-1 across the plot area
1224
+ // inside the margins). Main pie on the left, secondary plot
1225
+ // on the right.
1226
+ var MAIN_DOMAIN_X = [0, 0.55];
1227
+ var CY = 0.5;
1228
+ var SECONDARY_CX = 0.78;
1229
+ var BAR_LEFT = 0.68;
1230
+ var BAR_RIGHT = 0.88;
1231
+ traces.push({
1232
+ type: "pie",
1233
+ values: main_1.map(function (s) { return s.value; }),
1234
+ labels: main_1.map(function (s) { return s.label; }),
1235
+ name: dataLabel,
1236
+ domain: { x: MAIN_DOMAIN_X, y: [0, 1] },
1237
+ sort: false,
1238
+ direction: "clockwise",
1239
+ // Rotate so the "Other" slice's angular midpoint faces the
1240
+ // secondary plot (Excel's layout). Other is the last slice
1241
+ // of a clockwise sweep starting at `rotation`° from 12
1242
+ // o'clock, so its midpoint lands at 3 o'clock when the
1243
+ // sweep starts 90° + halfAngle past the top.
1244
+ rotation: (90 + (halfAngle * 180) / Math.PI) % 360,
1245
+ marker: { colors: main_1.map(function (_, i) { return paletteAt_1(i); }) },
1246
+ });
1247
+ if (secondary.length > 0) {
1248
+ // Paper coords are relative while the pie is circular in
1249
+ // pixels — convert the main pie's pixel radius into
1250
+ // separate x/y paper fractions to compensate for the
1251
+ // aspect ratio. Falls back to fixed fractions when the
1252
+ // container size isn't known yet.
1253
+ var plotW = typeof width === "number" ? Math.max(1, width - 102) : 0;
1254
+ var plotH = typeof height === "number" ? Math.max(1, height - 102) : 0;
1255
+ var hasGeometry = plotW > 1 && plotH > 1;
1256
+ var r = hasGeometry
1257
+ ? Math.min((MAIN_DOMAIN_X[1] - MAIN_DOMAIN_X[0]) * plotW, plotH) / 2
1258
+ : 0;
1259
+ var r2 = r * secondScale;
1260
+ var clampFrac = function (v, min, max) {
1261
+ return Math.min(max, Math.max(min, v));
1262
+ };
1263
+ var rx2 = clampFrac(hasGeometry ? r2 / plotW : 0.14 * secondScale, 0.03, 0.19);
1264
+ var ry2 = clampFrac(hasGeometry ? r2 / plotH : 0.28 * secondScale, 0.05, 0.45);
1265
+ var barHalf = ry2;
1266
+ if (ofPieType === "pie") {
1267
+ traces.push({
1268
+ type: "pie",
1269
+ values: secondary.map(function (s) { return s.value; }),
1270
+ labels: secondary.map(function (s) { return s.label; }),
1271
+ name: dataLabel,
1272
+ domain: {
1273
+ x: [SECONDARY_CX - rx2, SECONDARY_CX + rx2],
1274
+ y: [CY - ry2, CY + ry2],
1275
+ },
1276
+ sort: false,
1277
+ direction: "clockwise",
1278
+ marker: {
1279
+ colors: secondary.map(function (_, i) { return paletteAt_1(main_1.length + i); }),
1280
+ },
1281
+ });
1282
+ }
1283
+ else {
1284
+ // Bar-of-pie — a single-category stacked bar on hidden
1285
+ // secondary axes; one trace per point so each segment
1286
+ // keeps its own color and legend entry.
1287
+ secondary.forEach(function (s, i) {
1288
+ traces.push({
1289
+ type: "bar",
1290
+ x: [""],
1291
+ y: [s.value],
1292
+ name: s.label,
1293
+ xaxis: "x2",
1294
+ yaxis: "y2",
1295
+ marker: { color: paletteAt_1(main_1.length + i) },
1296
+ });
1297
+ });
1298
+ }
1299
+ // Connector lines from the Other slice's edges to the top
1300
+ // and bottom of the secondary plot. Skipped (gracefully)
1301
+ // when the container size isn't known — pure paper-coord
1302
+ // geometry can't compensate for the pixel aspect ratio.
1303
+ var shapes = [];
1304
+ if (hasGeometry) {
1305
+ var connectorColor = isDarkMode
1306
+ ? "rgba(255,255,255,0.45)"
1307
+ : "#999999";
1308
+ var mainCx = (MAIN_DOMAIN_X[0] + MAIN_DOMAIN_X[1]) / 2;
1309
+ var px = mainCx + (r * Math.cos(halfAngle)) / plotW;
1310
+ var pyTop = CY + (r * Math.sin(halfAngle)) / plotH;
1311
+ var pyBottom = CY - (r * Math.sin(halfAngle)) / plotH;
1312
+ var tx = ofPieType === "pie" ? SECONDARY_CX : BAR_LEFT;
1313
+ var half = ofPieType === "pie" ? ry2 : barHalf;
1314
+ var line = {
1315
+ type: "line",
1316
+ xref: "paper",
1317
+ yref: "paper",
1318
+ layer: "below",
1319
+ line: { color: connectorColor, width: 1 },
1320
+ };
1321
+ shapes.push(tslib_1.__assign(tslib_1.__assign({}, line), { x0: px, y0: pyTop, x1: tx, y1: CY + half }), tslib_1.__assign(tslib_1.__assign({}, line), { x0: px, y0: pyBottom, x1: tx, y1: CY - half }));
1322
+ }
1323
+ ofPieExtras = tslib_1.__assign({ shapes: shapes }, (ofPieType === "bar"
1324
+ ? {
1325
+ barmode: "stack",
1326
+ xaxis2: {
1327
+ domain: [BAR_LEFT, BAR_RIGHT],
1328
+ anchor: "y2",
1329
+ visible: false,
1330
+ fixedrange: true,
1331
+ },
1332
+ yaxis2: {
1333
+ domain: [CY - barHalf, CY + barHalf],
1334
+ anchor: "x2",
1335
+ visible: false,
1336
+ fixedrange: true,
1337
+ },
1338
+ }
1339
+ : {}));
1340
+ }
1341
+ }
1342
+ else if (effectiveChartType === "pie") {
1343
+ var pieData = seriesData;
1344
+ var trace = {
1345
+ type: seriesPlotlyType,
1346
+ values: pieData.values,
1347
+ labels: pieData.labels,
1348
+ name: dataLabel,
1349
+ marker: {
1350
+ colors: [
1351
+ theme.themeColors.accent1,
1352
+ theme.themeColors.accent2,
1353
+ theme.themeColors.accent3,
1354
+ theme.themeColors.accent4,
1355
+ theme.themeColors.accent5,
1356
+ theme.themeColors.accent6,
1357
+ ],
1358
+ },
1359
+ };
1360
+ applyTraceColor(trace, (_48 = series.color) !== null && _48 !== void 0 ? _48 : undefined, {
1361
+ noFill: series.noFill,
1362
+ dataPointColors: series.dataPointColors,
1363
+ seriesIndex: currentSeriesIndex,
1364
+ effectiveChartType: effectiveChartType,
1365
+ });
1366
+ traces.push(trace);
1367
+ }
1368
+ else if ("values" in seriesData && "labels" in seriesData) {
1369
+ var _56 = assignCartesianData(domainData, seriesData.values), x = _56.x, y = _56.y, orientation_1 = _56.orientation;
1370
+ var trace = tslib_1.__assign({ type: seriesPlotlyType, x: x, y: y, orientation: orientation_1, name: dataLabel, stackgroup: isStacked ? "one" : undefined }, seriesTraceStyle);
1371
+ applyTraceColor(trace, (_49 = series.color) !== null && _49 !== void 0 ? _49 : undefined, {
1372
+ noFill: series.noFill,
1373
+ dataPointColors: series.dataPointColors,
1374
+ invertIfNegative: series.invertIfNegative,
1375
+ negativeColor: series.negativeColor,
1376
+ values: seriesData.values,
1377
+ seriesIndex: currentSeriesIndex,
1378
+ effectiveChartType: effectiveChartType,
1379
+ gradientColor: (0, gradient_1.gradientToPlotly)(series.gradient),
1380
+ });
1381
+ decorateCartesianTrace(trace, series, seriesData.values, dataLabel);
1382
+ traces.push(trace);
1383
+ }
1384
+ else {
1385
+ var numericValues = seriesData;
1386
+ var _57 = assignCartesianData(domainData, numericValues), x = _57.x, y = _57.y, orientation_2 = _57.orientation;
1387
+ var trace = tslib_1.__assign({ type: seriesPlotlyType, x: x, y: y, orientation: orientation_2, name: dataLabel, stackgroup: isStacked ? "one" : undefined }, seriesTraceStyle);
1388
+ applyTraceColor(trace, (_50 = series.color) !== null && _50 !== void 0 ? _50 : undefined, {
1389
+ noFill: series.noFill,
1390
+ dataPointColors: series.dataPointColors,
1391
+ invertIfNegative: series.invertIfNegative,
1392
+ negativeColor: series.negativeColor,
1393
+ values: numericValues,
1394
+ seriesIndex: currentSeriesIndex,
1395
+ effectiveChartType: effectiveChartType,
1396
+ gradientColor: (0, gradient_1.gradientToPlotly)(series.gradient),
1397
+ });
1398
+ decorateCartesianTrace(trace, series, numericValues, dataLabel);
1399
+ traces.push(trace);
1400
+ }
1401
+ };
1402
+ try {
1403
+ for (_j = (e_3 = void 0, tslib_1.__values(series.sources)), _k = _j.next(); !_k.done; _k = _j.next()) {
1404
+ sheetRange = _k.value;
1405
+ _loop_2(sheetRange);
1406
+ }
1407
+ }
1408
+ catch (e_3_1) { e_3 = { error: e_3_1 }; }
1409
+ finally {
1410
+ try {
1411
+ if (_k && !_k.done && (_o = _j.return)) _o.call(_j);
1412
+ }
1413
+ finally { if (e_3) throw e_3.error; }
1414
+ }
1415
+ _53.label = 12;
1416
+ case 12:
1417
+ _f = _e.next();
1418
+ return [3 /*break*/, 8];
1419
+ case 13: return [3 /*break*/, 16];
1420
+ case 14:
1421
+ e_1_1 = _53.sent();
1422
+ e_1 = { error: e_1_1 };
1423
+ return [3 /*break*/, 16];
1424
+ case 15:
1425
+ try {
1426
+ if (_f && !_f.done && (_m = _e.return)) _m.call(_e);
1427
+ }
1428
+ finally { if (e_1) throw e_1.error; }
1429
+ return [7 /*endfinally*/];
1430
+ case 16:
1431
+ authoredTitleFmt = spec.titleTextFormat;
1432
+ newLayout = tslib_1.__assign(tslib_1.__assign(tslib_1.__assign(tslib_1.__assign(tslib_1.__assign(tslib_1.__assign({ title: {
1433
+ text: title !== null && title !== void 0 ? title : undefined,
1434
+ font: applyTextFormatToFont({
1435
+ family: "Untitled Sans, apple-system, sans-serif",
1436
+ size: 16,
1437
+ color: textColor,
1438
+ }, authoredTitleFmt),
1439
+ x: 0.02, // Small left margin (0.02 = 2% from left edge)
1440
+ xanchor: "left",
1441
+ }, font: {
1442
+ family: "Untitled Sans, apple-system, sans-serif",
1443
+ size: 12,
1444
+ color: textColor,
1445
+ }, paper_bgcolor: bgColor, plot_bgcolor: bgColor, xaxis: applyAxisOverridesPlotly({
1446
+ title: {
1447
+ text: (_51 = spec.horizontalAxisTitle) !== null && _51 !== void 0 ? _51 : "",
1448
+ font: { color: textColor },
1449
+ },
1450
+ automargin: true,
1451
+ showgrid: true,
1452
+ gridcolor: gridColor,
1453
+ visible: (0, helpers_1.showXAxis)(spec === null || spec === void 0 ? void 0 : spec.chartType),
1454
+ type: isHorizontalBarChart ? "linear" : undefined,
1455
+ },
1456
+ // For horizontal bar, OOXML's value axis is the X axis.
1457
+ isHorizontalBarChart
1458
+ ? spec.valueAxisOptions
1459
+ : spec.categoryAxisOptions), yaxis: applyAxisOverridesPlotly({
1460
+ title: {
1461
+ text: (_52 = spec.verticalAxisTitle) !== null && _52 !== void 0 ? _52 : "",
1462
+ font: { color: textColor },
1463
+ },
1464
+ showgrid: !isHorizontalBarChart,
1465
+ gridcolor: gridColor,
1466
+ automargin: true,
1467
+ type: isHorizontalBarChart ? "category" : undefined,
1468
+ }, isHorizontalBarChart
1469
+ ? spec.categoryAxisOptions
1470
+ : spec.valueAxisOptions) }, (hasSecondaryAxis
1471
+ ? {
1472
+ yaxis2: applyAxisOverridesPlotly(tslib_1.__assign({ title: { font: { color: textColor } }, overlaying: "y", side: "right", showgrid: false, automargin: true }, (isPareto
1473
+ ? { range: [0, 100], ticksuffix: "%" }
1474
+ : {})), spec.secondaryValueAxisOptions),
1475
+ }
1476
+ : {})), (function () {
1477
+ var _a = applyLegendOverridesPlotly({ font: { color: textColor } }, spec.legend), legendCfg = _a.legend, showlegend = _a.showlegend;
1478
+ return {
1479
+ showlegend: showlegend === undefined ? true : showlegend,
1480
+ legend: legendCfg,
1481
+ };
1482
+ })()), { margin: {
1483
+ l: 50,
1484
+ r: 50,
1485
+ t: 50,
1486
+ b: 50,
1487
+ }, autosize: true }), ((spec.chartType === "bar" || spec.chartType === "column") && spec.stackedType
1488
+ ? tslib_1.__assign({ barmode: spec.stackedType === "STACKED" ||
1489
+ spec.stackedType === "PERCENT_STACKED"
1490
+ ? "stack"
1491
+ : "group" }, (spec.stackedType === "PERCENT_STACKED"
1492
+ ? { barnorm: "percent" }
1493
+ : {})) : {})), (typeof spec.gapWidth === "number"
1494
+ ? { bargap: Math.max(0, Math.min(0.95, spec.gapWidth / 400)) }
1495
+ : {})), (ofPieExtras
1496
+ ? tslib_1.__assign(tslib_1.__assign(tslib_1.__assign({ shapes: ofPieExtras.shapes }, (ofPieExtras.barmode ? { barmode: ofPieExtras.barmode } : {})), (ofPieExtras.xaxis2 ? { xaxis2: ofPieExtras.xaxis2 } : {})), (ofPieExtras.yaxis2 ? { yaxis2: ofPieExtras.yaxis2 } : {})) : {}));
1497
+ dlOpts = spec.dataLabels;
1498
+ doughnutHole = spec.doughnutHoleSize;
1499
+ formattedTraces = traces.map(function (trace) {
1500
+ var next = applyDataLabelsToTracePlotly(trace, dlOpts, spec.chartType);
1501
+ // Doughnut is a pie trace with `hole` set.
1502
+ if (spec.chartType === "doughnut" && next.type === "pie") {
1503
+ next = tslib_1.__assign(tslib_1.__assign({}, next), { hole: typeof doughnutHole === "number" ? doughnutHole : 0.5 });
1504
+ }
1505
+ return next;
1506
+ });
1507
+ sortedTraces = tslib_1.__spreadArray([], tslib_1.__read(formattedTraces), false).sort(function (a, b) {
1508
+ var aHasFill = a.fill && a.fill !== "none";
1509
+ var bHasFill = b.fill && b.fill !== "none";
1510
+ if (aHasFill && !bHasFill)
1511
+ return -1;
1512
+ if (!aHasFill && bHasFill)
1513
+ return 1;
1514
+ return 0;
1515
+ });
1516
+ setPlotData(sortedTraces);
1517
+ setLayout(newLayout);
1518
+ return [2 /*return*/];
1519
+ }
1520
+ });
1521
+ }); };
1522
+ // Subscribe to datarange
1523
+ (0, spreadsheet_state_1.useSubscribeToSheet)(chart.chartId, chart.spec.dataRange, updateChart);
1524
+ // Update chart on spec changes
1525
+ (0, ui_1.useIsomorphicLayoutEffect)(function () {
1526
+ updateChart();
1527
+ }, [chart.spec, getDomainValuesFromRange, getSeriesValuesFromRange]);
1528
+ // Update theme
1529
+ (0, ui_1.useIsomorphicLayoutEffect)(function () {
1530
+ updateChart();
1531
+ }, [theme, title, isDarkMode]);
1532
+ // Resize chart on width/height changes
1533
+ (0, ui_1.useIsomorphicLayoutEffect)(function () {
1534
+ setLayout(function (prev) { return (tslib_1.__assign(tslib_1.__assign({}, prev), { width: width - 2, height: height - 2 })); });
1535
+ // Of-pie composites derive their connector-line shapes and
1536
+ // secondary-plot domains from the container's pixel aspect ratio —
1537
+ // rebuild them for the new size.
1538
+ if (spec.chartType === "pie" && (0, of_pie_1.isOfPieChartSpec)(spec)) {
1539
+ updateChart();
1540
+ }
1541
+ }, [width, height]);
1542
+ // Chrome bug - redraw chart when visibility changes
1543
+ (0, ui_1.useOnVisibilityChange)(function (state) {
1544
+ if (state === "visible") {
1545
+ updateChart();
1546
+ }
1547
+ });
1548
+ var config = {
1549
+ responsive: true,
1550
+ // Static so a body drag falls through to the EmbedDraggable move handler
1551
+ // (Excel/Sheets behavior) instead of triggering Plotly's zoom-box.
1552
+ // staticPlot also drops the modebar and the `.plot-container .draglayer`
1553
+ // element the move's cancel selector keys off of.
1554
+ displayModeBar: false,
1555
+ displaylogo: false,
1556
+ staticPlot: true,
1557
+ };
1558
+ // Excel's "Rounded Corners" chart frame (`<c:roundedCorners val="1"/>`
1559
+ // at the chartSpace root). Default per OOXML §21.2.2.183 is square,
1560
+ // so only opt in when the workbook explicitly set the flag.
1561
+ var roundedCornersStyle = spec.roundedCorners
1562
+ ? { borderRadius: 8, overflow: "hidden" }
1563
+ : undefined;
1564
+ return (react_1.default.createElement("div", { className: "flex flex-1", style: roundedCornersStyle },
1565
+ isSelected ? (react_1.default.createElement(ui_1.DropdownMenu, null,
1566
+ react_1.default.createElement(ui_1.DropdownMenuTrigger, { asChild: true },
1567
+ react_1.default.createElement(ui_1.IconButton, { className: "absolute right-1 top-1 z-10" },
1568
+ react_1.default.createElement(icons_1.DotsVerticalIcon, null))),
1569
+ react_1.default.createElement(ui_1.DropdownMenuPortal, null,
1570
+ react_1.default.createElement(ui_1.DropdownMenuContent, { align: "start", onCloseAutoFocus: function (event) {
1571
+ event.preventDefault();
1572
+ if (shouldFocusSheetRef.current) {
1573
+ focusSheet === null || focusSheet === void 0 ? void 0 : focusSheet();
1574
+ }
1575
+ }, onInteractOutside: function () {
1576
+ shouldFocusSheetRef.current = false;
1577
+ } },
1578
+ readonly ? null : (react_1.default.createElement(ui_1.DropdownMenuItem, { onClick: function () { return onRequestEdit === null || onRequestEdit === void 0 ? void 0 : onRequestEdit(chart); } }, "Edit chart")),
1579
+ readonly ? null : (react_1.default.createElement(ui_1.DropdownMenuItem, { onClick: function () {
1580
+ shouldFocusSheetRef.current = true;
1581
+ onDeleteChart === null || onDeleteChart === void 0 ? void 0 : onDeleteChart(chart.chartId);
1582
+ } }, "Delete chart")))))) : null,
1583
+ react_1.default.createElement("div", { className: "flex-1 rnc-plotly-chart-container" },
1584
+ react_1.default.createElement(react_plotly_js_1.default, { ref: plotRef, data: plotData, layout: layout, config: config, style: { width: "100%", height: "100%" } }))));
1585
+ };
1586
+ exports.BasicChart = BasicChart;