highcharts 12.0.2 → 12.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (335) hide show
  1. package/bower.json +1 -1
  2. package/es-modules/Accessibility/Options/A11yDefaults.js +2 -0
  3. package/es-modules/Core/Color/Color.js +5 -12
  4. package/es-modules/Core/Defaults.js +0 -8
  5. package/es-modules/Core/Globals.js +1 -1
  6. package/es-modules/Core/Pointer.js +3 -1
  7. package/es-modules/Core/Renderer/HTML/HTMLElement.js +1 -3
  8. package/es-modules/Core/Renderer/SVG/SVGElement.js +4 -2
  9. package/es-modules/Core/Renderer/SVG/SVGLabel.js +11 -12
  10. package/es-modules/Core/Series/DataLabel.js +1 -0
  11. package/es-modules/Core/Series/Series.js +13 -15
  12. package/es-modules/Core/Templating.js +20 -16
  13. package/es-modules/Core/Time.js +21 -10
  14. package/es-modules/Core/Utilities.js +1 -1
  15. package/es-modules/Data/Converters/CSVConverter.js +1 -0
  16. package/es-modules/Data/Converters/DataConverter.js +31 -0
  17. package/es-modules/Data/Converters/GoogleSheetsConverter.js +1 -0
  18. package/es-modules/Data/Converters/HTMLTableConverter.js +1 -0
  19. package/es-modules/Data/Converters/JSONConverter.js +1 -0
  20. package/es-modules/Extensions/Boost/BoostSeries.js +13 -7
  21. package/es-modules/Extensions/DragPanes/AxisResizer.js +1 -1
  22. package/es-modules/Extensions/Exporting/Exporting.js +16 -8
  23. package/es-modules/Extensions/SeriesLabel/SeriesLabelDefaults.js +7 -2
  24. package/es-modules/Series/Bubble/BubbleSeries.js +24 -0
  25. package/es-modules/Series/Organization/OrganizationSeriesDefaults.js +3 -1
  26. package/es-modules/Series/Timeline/TimelineSeriesDefaults.js +3 -1
  27. package/es-modules/Series/Treegraph/TreegraphSeriesDefaults.js +3 -1
  28. package/es-modules/Series/Treemap/TreemapPoint.js +7 -2
  29. package/es-modules/Series/Treemap/TreemapSeries.js +154 -53
  30. package/es-modules/Series/Treemap/TreemapSeriesDefaults.js +126 -4
  31. package/es-modules/Stock/Indicators/VBP/VBPIndicator.js +1 -0
  32. package/es-modules/Stock/RangeSelector/RangeSelector.js +75 -71
  33. package/es-modules/Stock/RangeSelector/RangeSelectorDefaults.js +10 -4
  34. package/es-modules/masters/indicators/indicators-all.src.js +4 -0
  35. package/es-modules/tsconfig.tsbuildinfo +1 -1
  36. package/highcharts-3d.js +2 -2
  37. package/highcharts-3d.src.js +1 -1
  38. package/highcharts-gantt.js +5 -5
  39. package/highcharts-gantt.src.js +174 -164
  40. package/highcharts-more.js +2 -2
  41. package/highcharts-more.src.js +25 -1
  42. package/highcharts.d.ts +301 -764
  43. package/highcharts.js +3 -3
  44. package/highcharts.src.d.ts +301 -764
  45. package/highcharts.src.js +84 -84
  46. package/highmaps.js +5 -5
  47. package/highmaps.src.js +111 -87
  48. package/highstock.js +5 -5
  49. package/highstock.src.js +174 -164
  50. package/indicators/acceleration-bands.js +2 -2
  51. package/indicators/acceleration-bands.src.js +1 -1
  52. package/indicators/accumulation-distribution.js +2 -2
  53. package/indicators/accumulation-distribution.src.js +1 -1
  54. package/indicators/ao.js +2 -2
  55. package/indicators/ao.src.js +1 -1
  56. package/indicators/apo.js +2 -2
  57. package/indicators/apo.src.js +1 -1
  58. package/indicators/aroon-oscillator.js +2 -2
  59. package/indicators/aroon-oscillator.src.js +1 -1
  60. package/indicators/aroon.js +2 -2
  61. package/indicators/aroon.src.js +1 -1
  62. package/indicators/atr.js +2 -2
  63. package/indicators/atr.src.js +1 -1
  64. package/indicators/bollinger-bands.js +2 -2
  65. package/indicators/bollinger-bands.src.js +1 -1
  66. package/indicators/cci.js +2 -2
  67. package/indicators/cci.src.js +1 -1
  68. package/indicators/chaikin.js +2 -2
  69. package/indicators/chaikin.src.js +1 -1
  70. package/indicators/cmf.js +2 -2
  71. package/indicators/cmf.src.js +1 -1
  72. package/indicators/cmo.js +2 -2
  73. package/indicators/cmo.src.js +1 -1
  74. package/indicators/dema.js +2 -2
  75. package/indicators/dema.src.js +1 -1
  76. package/indicators/disparity-index.js +2 -2
  77. package/indicators/disparity-index.src.js +1 -1
  78. package/indicators/dmi.js +2 -2
  79. package/indicators/dmi.src.js +1 -1
  80. package/indicators/dpo.js +2 -2
  81. package/indicators/dpo.src.js +1 -1
  82. package/indicators/ema.js +1 -1
  83. package/indicators/ichimoku-kinko-hyo.js +2 -2
  84. package/indicators/ichimoku-kinko-hyo.src.js +1 -1
  85. package/indicators/indicators-all.js +2 -2
  86. package/indicators/indicators-all.src.js +6 -1
  87. package/indicators/indicators.js +2 -2
  88. package/indicators/indicators.src.js +1 -1
  89. package/indicators/keltner-channels.js +2 -2
  90. package/indicators/keltner-channels.src.js +1 -1
  91. package/indicators/klinger.js +2 -2
  92. package/indicators/klinger.src.js +1 -1
  93. package/indicators/macd.js +2 -2
  94. package/indicators/macd.src.js +1 -1
  95. package/indicators/mfi.js +2 -2
  96. package/indicators/mfi.src.js +1 -1
  97. package/indicators/momentum.js +2 -2
  98. package/indicators/momentum.src.js +1 -1
  99. package/indicators/natr.js +2 -2
  100. package/indicators/natr.src.js +1 -1
  101. package/indicators/obv.js +2 -2
  102. package/indicators/obv.src.js +1 -1
  103. package/indicators/pivot-points.js +2 -2
  104. package/indicators/pivot-points.src.js +1 -1
  105. package/indicators/ppo.js +2 -2
  106. package/indicators/ppo.src.js +1 -1
  107. package/indicators/price-channel.js +2 -2
  108. package/indicators/price-channel.src.js +1 -1
  109. package/indicators/price-envelopes.js +2 -2
  110. package/indicators/price-envelopes.src.js +1 -1
  111. package/indicators/psar.js +2 -2
  112. package/indicators/psar.src.js +1 -1
  113. package/indicators/regressions.js +2 -2
  114. package/indicators/regressions.src.js +1 -1
  115. package/indicators/roc.js +2 -2
  116. package/indicators/roc.src.js +1 -1
  117. package/indicators/rsi.js +2 -2
  118. package/indicators/rsi.src.js +1 -1
  119. package/indicators/slow-stochastic.js +2 -2
  120. package/indicators/slow-stochastic.src.js +1 -1
  121. package/indicators/stochastic.js +2 -2
  122. package/indicators/stochastic.src.js +1 -1
  123. package/indicators/supertrend.js +2 -2
  124. package/indicators/supertrend.src.js +1 -1
  125. package/indicators/tema.js +2 -2
  126. package/indicators/tema.src.js +1 -1
  127. package/indicators/trendline.js +2 -2
  128. package/indicators/trendline.src.js +1 -1
  129. package/indicators/trix.js +2 -2
  130. package/indicators/trix.src.js +1 -1
  131. package/indicators/volume-by-price.js +2 -2
  132. package/indicators/volume-by-price.src.js +2 -1
  133. package/indicators/vwap.js +2 -2
  134. package/indicators/vwap.src.js +1 -1
  135. package/indicators/williams-r.js +2 -2
  136. package/indicators/williams-r.src.js +1 -1
  137. package/indicators/wma.js +2 -2
  138. package/indicators/wma.src.js +1 -1
  139. package/indicators/zigzag.js +2 -2
  140. package/indicators/zigzag.src.js +1 -1
  141. package/modules/accessibility.js +2 -2
  142. package/modules/accessibility.src.js +3 -1
  143. package/modules/annotations-advanced.js +3 -3
  144. package/modules/annotations-advanced.src.js +4 -4
  145. package/modules/annotations.js +2 -2
  146. package/modules/annotations.src.js +3 -3
  147. package/modules/arc-diagram.js +2 -2
  148. package/modules/arc-diagram.src.js +1 -1
  149. package/modules/arrow-symbols.js +2 -2
  150. package/modules/arrow-symbols.src.js +1 -1
  151. package/modules/boost-canvas.js +2 -2
  152. package/modules/boost-canvas.src.js +14 -11
  153. package/modules/boost.js +2 -2
  154. package/modules/boost.src.js +14 -11
  155. package/modules/broken-axis.js +2 -2
  156. package/modules/broken-axis.src.js +1 -1
  157. package/modules/bullet.js +2 -2
  158. package/modules/bullet.src.js +1 -1
  159. package/modules/coloraxis.js +2 -2
  160. package/modules/coloraxis.src.js +1 -1
  161. package/modules/current-date-indicator.js +2 -2
  162. package/modules/current-date-indicator.src.js +1 -1
  163. package/modules/cylinder.js +2 -2
  164. package/modules/cylinder.src.js +1 -1
  165. package/modules/data-tools.js +2 -2
  166. package/modules/data-tools.src.js +36 -1
  167. package/modules/data.js +2 -2
  168. package/modules/data.src.js +1 -1
  169. package/modules/datagrouping.js +2 -2
  170. package/modules/datagrouping.src.js +1 -1
  171. package/modules/debugger.js +2 -2
  172. package/modules/debugger.src.js +1 -1
  173. package/modules/dependency-wheel.js +2 -2
  174. package/modules/dependency-wheel.src.js +1 -1
  175. package/modules/dotplot.js +2 -2
  176. package/modules/dotplot.src.js +1 -1
  177. package/modules/drag-panes.js +2 -2
  178. package/modules/drag-panes.src.js +2 -2
  179. package/modules/draggable-points.js +2 -2
  180. package/modules/draggable-points.src.js +1 -1
  181. package/modules/drilldown.js +2 -2
  182. package/modules/drilldown.src.js +1 -1
  183. package/modules/dumbbell.js +2 -2
  184. package/modules/dumbbell.src.js +1 -1
  185. package/modules/export-data.js +2 -2
  186. package/modules/export-data.src.js +1 -1
  187. package/modules/exporting.js +2 -2
  188. package/modules/exporting.src.js +17 -9
  189. package/modules/flowmap.js +2 -2
  190. package/modules/flowmap.src.js +1 -1
  191. package/modules/full-screen.js +2 -2
  192. package/modules/full-screen.src.js +1 -1
  193. package/modules/funnel.js +2 -2
  194. package/modules/funnel.src.js +1 -1
  195. package/modules/funnel3d.js +2 -2
  196. package/modules/funnel3d.src.js +1 -1
  197. package/modules/gantt.js +5 -5
  198. package/modules/gantt.src.js +89 -79
  199. package/modules/geoheatmap.js +2 -2
  200. package/modules/geoheatmap.src.js +1 -1
  201. package/modules/grid-axis.js +2 -2
  202. package/modules/grid-axis.src.js +1 -1
  203. package/modules/heatmap.js +3 -3
  204. package/modules/heatmap.src.js +2 -2
  205. package/modules/heikinashi.js +2 -2
  206. package/modules/heikinashi.src.js +1 -1
  207. package/modules/histogram-bellcurve.js +2 -2
  208. package/modules/histogram-bellcurve.src.js +1 -1
  209. package/modules/hollowcandlestick.js +2 -2
  210. package/modules/hollowcandlestick.src.js +1 -1
  211. package/modules/item-series.js +2 -2
  212. package/modules/item-series.src.js +1 -1
  213. package/modules/lollipop.js +2 -2
  214. package/modules/lollipop.src.js +1 -1
  215. package/modules/map.js +4 -4
  216. package/modules/map.src.js +26 -2
  217. package/modules/marker-clusters.js +2 -2
  218. package/modules/marker-clusters.src.js +1 -1
  219. package/modules/mouse-wheel-zoom.js +2 -2
  220. package/modules/mouse-wheel-zoom.src.js +1 -1
  221. package/modules/navigator.js +2 -2
  222. package/modules/navigator.src.js +1 -1
  223. package/modules/networkgraph.js +2 -2
  224. package/modules/networkgraph.src.js +1 -1
  225. package/modules/no-data-to-display.js +2 -2
  226. package/modules/no-data-to-display.src.js +1 -1
  227. package/modules/offline-exporting.js +2 -2
  228. package/modules/offline-exporting.src.js +18 -10
  229. package/modules/organization.js +2 -2
  230. package/modules/organization.src.js +4 -2
  231. package/modules/overlapping-datalabels.js +2 -2
  232. package/modules/overlapping-datalabels.src.js +1 -1
  233. package/modules/parallel-coordinates.js +2 -2
  234. package/modules/parallel-coordinates.src.js +1 -1
  235. package/modules/pareto.js +2 -2
  236. package/modules/pareto.src.js +1 -1
  237. package/modules/pathfinder.js +2 -2
  238. package/modules/pathfinder.src.js +1 -1
  239. package/modules/pattern-fill.js +2 -2
  240. package/modules/pattern-fill.src.js +1 -1
  241. package/modules/pictorial.js +2 -2
  242. package/modules/pictorial.src.js +1 -1
  243. package/modules/pointandfigure.js +2 -2
  244. package/modules/pointandfigure.src.js +1 -1
  245. package/modules/price-indicator.js +2 -2
  246. package/modules/price-indicator.src.js +1 -1
  247. package/modules/pyramid3d.js +2 -2
  248. package/modules/pyramid3d.src.js +1 -1
  249. package/modules/renko.js +2 -2
  250. package/modules/renko.src.js +1 -1
  251. package/modules/sankey.js +2 -2
  252. package/modules/sankey.src.js +1 -1
  253. package/modules/series-label.js +2 -2
  254. package/modules/series-label.src.js +8 -3
  255. package/modules/series-on-point.js +2 -2
  256. package/modules/series-on-point.src.js +1 -1
  257. package/modules/solid-gauge.js +2 -2
  258. package/modules/solid-gauge.src.js +1 -1
  259. package/modules/sonification.js +2 -2
  260. package/modules/sonification.src.js +1 -1
  261. package/modules/static-scale.js +2 -2
  262. package/modules/static-scale.src.js +1 -1
  263. package/modules/stock-tools.js +2 -2
  264. package/modules/stock-tools.src.js +3 -3
  265. package/modules/stock.js +6 -6
  266. package/modules/stock.src.js +89 -79
  267. package/modules/streamgraph.js +2 -2
  268. package/modules/streamgraph.src.js +1 -1
  269. package/modules/sunburst.js +2 -2
  270. package/modules/sunburst.src.js +290 -62
  271. package/modules/textpath.js +2 -2
  272. package/modules/textpath.src.js +1 -1
  273. package/modules/tiledwebmap.js +3 -3
  274. package/modules/tiledwebmap.src.js +1 -1
  275. package/modules/tilemap.js +2 -2
  276. package/modules/tilemap.src.js +1 -1
  277. package/modules/timeline.js +2 -2
  278. package/modules/timeline.src.js +4 -2
  279. package/modules/treegraph.js +2 -2
  280. package/modules/treegraph.src.js +4 -2
  281. package/modules/treegrid.js +2 -2
  282. package/modules/treegrid.src.js +1 -1
  283. package/modules/treemap.js +2 -2
  284. package/modules/treemap.src.js +288 -60
  285. package/modules/variable-pie.js +2 -2
  286. package/modules/variable-pie.src.js +1 -1
  287. package/modules/variwide.js +2 -2
  288. package/modules/variwide.src.js +1 -1
  289. package/modules/vector.js +2 -2
  290. package/modules/vector.src.js +1 -1
  291. package/modules/venn.js +2 -2
  292. package/modules/venn.src.js +1 -1
  293. package/modules/windbarb.js +2 -2
  294. package/modules/windbarb.src.js +1 -1
  295. package/modules/wordcloud.js +2 -2
  296. package/modules/wordcloud.src.js +1 -1
  297. package/modules/xrange.js +2 -2
  298. package/modules/xrange.src.js +1 -1
  299. package/options/treegraph.d.ts +559 -70
  300. package/options/treegraph.src.d.ts +559 -70
  301. package/options/treemap.d.ts +314 -160
  302. package/options/treemap.src.d.ts +314 -160
  303. package/options/vbp.d.ts +1 -1
  304. package/options/vbp.src.d.ts +1 -1
  305. package/package.json +1 -1
  306. package/standalone-navigator.js +3 -3
  307. package/standalone-navigator.src.js +85 -85
  308. package/themes/avocado.js +2 -2
  309. package/themes/avocado.src.js +1 -1
  310. package/themes/brand-dark.js +2 -2
  311. package/themes/brand-dark.src.js +1 -1
  312. package/themes/brand-light.js +2 -2
  313. package/themes/brand-light.src.js +1 -1
  314. package/themes/dark-blue.js +2 -2
  315. package/themes/dark-blue.src.js +1 -1
  316. package/themes/dark-green.js +2 -2
  317. package/themes/dark-green.src.js +1 -1
  318. package/themes/dark-unica.js +2 -2
  319. package/themes/dark-unica.src.js +1 -1
  320. package/themes/gray.js +2 -2
  321. package/themes/gray.src.js +1 -1
  322. package/themes/grid-light.js +2 -2
  323. package/themes/grid-light.src.js +1 -1
  324. package/themes/grid.js +2 -2
  325. package/themes/grid.src.js +1 -1
  326. package/themes/high-contrast-dark.js +2 -2
  327. package/themes/high-contrast-dark.src.js +1 -1
  328. package/themes/high-contrast-light.js +2 -2
  329. package/themes/high-contrast-light.src.js +1 -1
  330. package/themes/sand-signika.js +2 -2
  331. package/themes/sand-signika.src.js +1 -1
  332. package/themes/skies.js +2 -2
  333. package/themes/skies.src.js +1 -1
  334. package/themes/sunset.js +2 -2
  335. package/themes/sunset.src.js +1 -1
package/bower.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "highcharts",
3
- "version": "12.0.2",
3
+ "version": "12.1.1",
4
4
  "main": "highcharts.js",
5
5
  "license": "https://www.highcharts.com/license",
6
6
  "types": "highcharts.d.ts"
@@ -266,6 +266,8 @@ const Options = {
266
266
  /**
267
267
  * When a series contains more points than this, we no longer expose
268
268
  * information about individual points to screen readers.
269
+ * Note that the keyboard navigation remains functional, but points
270
+ * won't have accessible descriptions unless handled separately.
269
271
  *
270
272
  * Set to `false` to disable.
271
273
  *
@@ -192,18 +192,11 @@ class Color {
192
192
  }
193
193
  // Check for has alpha, because rgba colors perform worse due to
194
194
  // lack of support in WebKit.
195
- const hasAlpha = (toRgba[3] !== 1 || fromRgba[3] !== 1);
196
- return (hasAlpha ? 'rgba(' : 'rgb(') +
197
- Math.round(toRgba[0] + (fromRgba[0] - toRgba[0]) * (1 - pos)) +
198
- ',' +
199
- Math.round(toRgba[1] + (fromRgba[1] - toRgba[1]) * (1 - pos)) +
200
- ',' +
201
- Math.round(toRgba[2] + (fromRgba[2] - toRgba[2]) * (1 - pos)) +
202
- (hasAlpha ?
203
- (',' +
204
- (toRgba[3] + (fromRgba[3] - toRgba[3]) * (1 - pos))) :
205
- '') +
206
- ')';
195
+ const hasAlpha = (toRgba[3] !== 1 || fromRgba[3] !== 1), channel = (to, i) => to + (fromRgba[i] - to) * (1 - pos), rgba = toRgba.slice(0, 3).map(channel).map(Math.round);
196
+ if (hasAlpha) {
197
+ rgba.push(channel(toRgba[3], 3));
198
+ }
199
+ return (hasAlpha ? 'rgba(' : 'rgb(') + rgba.join(',') + ')';
207
200
  }
208
201
  }
209
202
  /* *
@@ -2621,14 +2621,6 @@ const defaultOptions = {
2621
2621
  text: 'Highcharts.com'
2622
2622
  }
2623
2623
  };
2624
- /* eslint-disable spaced-comment */
2625
- /*= if (!build.classic) { =*/
2626
- // Legacy build for styled mode, set the styledMode option to true by default.
2627
- defaultOptions.chart.styledMode = true;
2628
- /*= } else { =*/
2629
- defaultOptions.chart.styledMode = false;
2630
- /*= } =*/
2631
- '';
2632
2624
  const defaultTime = new Time(defaultOptions.time);
2633
2625
  /**
2634
2626
  * Get the updated default options. Until 3.0.7, merely exposing defaultOptions
@@ -29,7 +29,7 @@ var Globals;
29
29
  {}), // eslint-disable-line node/no-unsupported-features/es-builtins
30
30
  Globals.doc = Globals.win.document, Globals.svg = (Globals.doc &&
31
31
  Globals.doc.createElementNS &&
32
- !!Globals.doc.createElementNS(Globals.SVG_NS, 'svg').createSVGRect), Globals.userAgent = (Globals.win.navigator && Globals.win.navigator.userAgent) || '', Globals.isChrome = Globals.win.chrome, Globals.isFirefox = Globals.userAgent.indexOf('Firefox') !== -1, Globals.isMS = /(edge|msie|trident)/i.test(Globals.userAgent) && !Globals.win.opera, Globals.isSafari = !Globals.isChrome && Globals.userAgent.indexOf('Safari') !== -1, Globals.isTouchDevice = /(Mobile|Android|Windows Phone)/.test(Globals.userAgent), Globals.isWebKit = Globals.userAgent.indexOf('AppleWebKit') !== -1, Globals.deg2rad = Math.PI * 2 / 360, Globals.marginNames = [
32
+ !!Globals.doc.createElementNS(Globals.SVG_NS, 'svg').createSVGRect), Globals.pageLang = Globals.doc?.body.closest('[lang]')?.lang, Globals.userAgent = (Globals.win.navigator && Globals.win.navigator.userAgent) || '', Globals.isChrome = Globals.win.chrome, Globals.isFirefox = Globals.userAgent.indexOf('Firefox') !== -1, Globals.isMS = /(edge|msie|trident)/i.test(Globals.userAgent) && !Globals.win.opera, Globals.isSafari = !Globals.isChrome && Globals.userAgent.indexOf('Safari') !== -1, Globals.isTouchDevice = /(Mobile|Android|Windows Phone)/.test(Globals.userAgent), Globals.isWebKit = Globals.userAgent.indexOf('AppleWebKit') !== -1, Globals.deg2rad = Math.PI * 2 / 360, Globals.marginNames = [
33
33
  'plotTop',
34
34
  'marginRight',
35
35
  'marginBottom',
@@ -1363,7 +1363,9 @@ class Pointer {
1363
1363
  hoverChart !== chart) {
1364
1364
  const relatedTargetObj = { relatedTarget: chart.container };
1365
1365
  if (e && !e?.relatedTarget) {
1366
- e = { ...relatedTargetObj, ...e };
1366
+ // #17192, Non-enumerable properties of "e" are dropped with
1367
+ // spreading (...e). Using Object.assign ensures integrity.
1368
+ Object.assign({}, e, relatedTargetObj);
1367
1369
  }
1368
1370
  hoverChart.pointer?.onContainerMouseLeave(e || relatedTargetObj);
1369
1371
  }
@@ -251,7 +251,7 @@ class HTMLElement extends SVGElement {
251
251
  textWidth,
252
252
  this.textAlign
253
253
  ].join(','), parentPadding = (this.parentGroup?.padding * -1) || 0;
254
- let baseline, hasBoxWidthChanged = false;
254
+ let baseline;
255
255
  // Update textWidth. Use the memoized textPxLength if possible, to
256
256
  // avoid the getTextPxLength function using elem.offsetWidth.
257
257
  // Calling offsetWidth affects rendering time as it forces layout
@@ -274,10 +274,8 @@ class HTMLElement extends SVGElement {
274
274
  whiteSpace: whiteSpace || 'normal' // #3331
275
275
  });
276
276
  this.oldTextWidth = textWidth;
277
- hasBoxWidthChanged = true; // #8159
278
277
  }
279
278
  }
280
- this.hasBoxWidthChanged = hasBoxWidthChanged; // #8159
281
279
  // Do the calculations and DOM access only if properties changed
282
280
  if (currentTextTransform !== this.cTT) {
283
281
  baseline = renderer.fontMetrics(element).b;
@@ -213,7 +213,7 @@ class SVGElement {
213
213
  * @return {Highcharts.SVGElement} Returns the SVGElement for chaining.
214
214
  */
215
215
  align(alignOptions, alignByTranslate, alignTo, redraw = true) {
216
- const attribs = {}, renderer = this.renderer, alignedObjects = renderer.alignedObjects, initialAlignment = Boolean(alignOptions);
216
+ const renderer = this.renderer, alignedObjects = renderer.alignedObjects, initialAlignment = Boolean(alignOptions);
217
217
  // First call on instanciate
218
218
  if (alignOptions) {
219
219
  this.alignOptions = alignOptions;
@@ -245,7 +245,9 @@ class SVGElement {
245
245
  // Default: top align
246
246
  y = (alignToBox.y || 0) + (alignOptions.y || 0) +
247
247
  ((alignToBox.height || 0) - (alignOptions.height || 0)) *
248
- getAlignFactor(alignOptions.verticalAlign);
248
+ getAlignFactor(alignOptions.verticalAlign), attribs = {
249
+ 'text-align': alignOptions?.align
250
+ };
249
251
  attribs[alignByTranslate ? 'translateX' : 'x'] = Math.round(x);
250
252
  attribs[alignByTranslate ? 'translateY' : 'y'] = Math.round(y);
251
253
  // Animate only if already placed
@@ -71,6 +71,7 @@ class SVGLabel extends SVGElement {
71
71
  * */
72
72
  alignSetter(value) {
73
73
  const alignFactor = getAlignFactor(value);
74
+ this.textAlign = value;
74
75
  if (alignFactor !== this.alignFactor) {
75
76
  this.alignFactor = alignFactor;
76
77
  // Bounding box exists, means we're dynamically changing
@@ -245,7 +246,10 @@ class SVGLabel extends SVGElement {
245
246
  this.boxAttr(key, value);
246
247
  }
247
248
  'text-alignSetter'(value) {
248
- this.textAlign = value;
249
+ // The text-align variety is for the pre-animation getter. The code
250
+ // should be unified to either textAlign or text-align.
251
+ this.textAlign = this['text-align'] = value;
252
+ this.updateTextPadding();
249
253
  }
250
254
  textSetter(text) {
251
255
  if (typeof text !== 'undefined') {
@@ -315,24 +319,19 @@ class SVGLabel extends SVGElement {
315
319
  * is changed.
316
320
  */
317
321
  updateTextPadding() {
318
- const text = this.text;
322
+ const text = this.text, textAlign = text.styles.textAlign || this.textAlign;
319
323
  if (!text.textPath) {
320
324
  this.updateBoxSize();
321
325
  // Determine y based on the baseline
322
326
  const textY = this.baseline ? 0 : this.baselineOffset, textX = (this.paddingLeft ?? this.padding) +
323
327
  // Compensate for alignment
324
- ((defined(this.widthSetting) && this.bBox) ?
325
- getAlignFactor(this.textAlign) *
326
- (this.widthSetting - this.bBox.width) :
327
- 0);
328
+ getAlignFactor(textAlign) * (this.widthSetting ?? this.bBox.width);
328
329
  // Update if anything changed
329
330
  if (textX !== text.x || textY !== text.y) {
330
- text.attr('x', textX);
331
- // #8159 - prevent misplaced data labels in treemap
332
- // (useHTML: true)
333
- if (text.hasBoxWidthChanged) {
334
- this.bBox = text.getBBox(true);
335
- }
331
+ text.attr({
332
+ align: textAlign,
333
+ x: textX
334
+ });
336
335
  if (typeof textY !== 'undefined') {
337
336
  text.attr('y', textY);
338
337
  }
@@ -111,6 +111,7 @@ var DataLabel;
111
111
  dataLabel.alignAttr.y += getAlignFactor(options.verticalAlign) *
112
112
  (unrotatedbBox.height - bBox.height);
113
113
  dataLabel[dataLabel.placed ? 'animate' : 'attr']({
114
+ 'text-align': dataLabel.alignAttr['text-align'] || 'center',
114
115
  x: dataLabel.alignAttr.x +
115
116
  (bBox.width - unrotatedbBox.width) / 2,
116
117
  y: dataLabel.alignAttr.y +
@@ -2394,9 +2394,14 @@ class Series {
2394
2394
  * @private
2395
2395
  * @function Highcharts.Series#searchKDTree
2396
2396
  */
2397
- searchKDTree(point, compareX, e) {
2397
+ searchKDTree(point, compareX, e, suppliedPointEvaluator, suppliedBSideCheckEvaluator) {
2398
2398
  const series = this, [kdX, kdY] = this.kdAxisArray, kdComparer = compareX ? 'distX' : 'dist', kdDimensions = (series.options.findNearestPointBy || '')
2399
- .indexOf('y') > -1 ? 2 : 1, useRadius = !!series.isBubble;
2399
+ .indexOf('y') > -1 ? 2 : 1, useRadius = !!series.isBubble, pointEvaluator = suppliedPointEvaluator || ((p1, p2, comparisonProp) => [
2400
+ (p1[comparisonProp] || 0) < (p2[comparisonProp] || 0) ?
2401
+ p1 :
2402
+ p2,
2403
+ false
2404
+ ]), bSideCheckEvaluator = suppliedBSideCheckEvaluator || ((a, b) => a < b);
2400
2405
  /**
2401
2406
  * Set the one and two dimensional distance on the point object.
2402
2407
  * @private
@@ -2411,28 +2416,21 @@ class Series {
2411
2416
  */
2412
2417
  function doSearch(search, tree, depth, dimensions) {
2413
2418
  const point = tree.point, axis = series.kdAxisArray[depth % dimensions];
2414
- let nPoint1, nPoint2, ret = point;
2419
+ let ret = point, flip = false;
2415
2420
  setDistance(search, point);
2416
2421
  // Pick side based on distance to splitting point
2417
2422
  const tdist = (search[axis] || 0) - (point[axis] || 0) +
2418
2423
  (useRadius ? (point.marker?.radius || 0) : 0), sideA = tdist < 0 ? 'left' : 'right', sideB = tdist < 0 ? 'right' : 'left';
2419
2424
  // End of tree
2420
2425
  if (tree[sideA]) {
2421
- nPoint1 = doSearch(search, tree[sideA], depth + 1, dimensions);
2422
- ret = (nPoint1[kdComparer] <
2423
- ret[kdComparer] ?
2424
- nPoint1 :
2425
- point);
2426
+ [ret, flip] = pointEvaluator(point, doSearch(search, tree[sideA], depth + 1, dimensions), kdComparer);
2426
2427
  }
2427
2428
  if (tree[sideB]) {
2429
+ const sqrtTDist = Math.sqrt(tdist * tdist), retDist = ret[kdComparer];
2428
2430
  // Compare distance to current best to splitting point to decide
2429
- // whether to check side B or not
2430
- if (Math.sqrt(tdist * tdist) < ret[kdComparer]) {
2431
- nPoint2 = doSearch(search, tree[sideB], depth + 1, dimensions);
2432
- ret = (nPoint2[kdComparer] <
2433
- ret[kdComparer] ?
2434
- nPoint2 :
2435
- ret);
2431
+ // whether to check side B or no
2432
+ if (bSideCheckEvaluator(sqrtTDist, retDist, flip)) {
2433
+ ret = pointEvaluator(ret, doSearch(search, tree[sideB], depth + 1, dimensions), kdComparer)[0];
2436
2434
  }
2437
2435
  }
2438
2436
  return ret;
@@ -11,9 +11,9 @@
11
11
  import D from './Defaults.js';
12
12
  const { defaultOptions, defaultTime } = D;
13
13
  import G from './Globals.js';
14
- const { doc } = G;
14
+ const { pageLang } = G;
15
15
  import U from './Utilities.js';
16
- const { extend, getNestedProperty, isArray, isNumber, isObject, pick, ucfirst } = U;
16
+ const { extend, getNestedProperty, isArray, isNumber, isObject, isString, pick, ucfirst } = U;
17
17
  const helpers = {
18
18
  // Built-in helpers
19
19
  add: (a, b) => a + b,
@@ -48,6 +48,8 @@ const numberFormatCache = {};
48
48
  * Functions
49
49
  *
50
50
  * */
51
+ // Internal convenience function
52
+ const isQuotedString = (str) => /^["'].+["']$/.test(str);
51
53
  /**
52
54
  * Formats a JavaScript date timestamp (milliseconds since Jan 1st 1970) into a
53
55
  * human readable date string. The format is a subset of the formats for PHP's
@@ -125,11 +127,11 @@ function dateFormat(format, timestamp, upperCaseFirst) {
125
127
  * The formatted string.
126
128
  */
127
129
  function format(str = '', ctx, chart) {
128
- const regex = /\{([\p{L}\d:\.,;\-\/<>\[\]%_@"'’= #\(\)]+)\}/gu,
130
+ const regex = /\{([\p{L}\d:\.,;\-\/<>\[\]%_@+"'’= #\(\)]+)\}/gu,
129
131
  // The sub expression regex is the same as the top expression regex,
130
132
  // but except parens and block helpers (#), and surrounded by parens
131
133
  // instead of curly brackets.
132
- subRegex = /\(([\p{L}\d:\.,;\-\/<>\[\]%_@"'= ]+)\)/gu, matches = [], floatRegex = /f$/, decRegex = /\.(\d)/, lang = chart?.options.lang || defaultOptions.lang, time = chart && chart.time || defaultTime, numberFormatter = chart && chart.numberFormatter || numberFormat;
134
+ subRegex = /\(([\p{L}\d:\.,;\-\/<>\[\]%_@+"'= ]+)\)/gu, matches = [], floatRegex = /f$/, decRegex = /\.(\d)/, lang = chart?.options.lang || defaultOptions.lang, time = chart && chart.time || defaultTime, numberFormatter = chart && chart.numberFormatter || numberFormat;
133
135
  /*
134
136
  * Get a literal or variable value inside a template expression. May be
135
137
  * extended with other types like string or null if needed, but keep it
@@ -147,7 +149,7 @@ function format(str = '', ctx, chart) {
147
149
  if ((n = Number(key)).toString() === key) {
148
150
  return n;
149
151
  }
150
- if (/^["'].+["']$/.test(key)) {
152
+ if (isQuotedString(key)) {
151
153
  return key.slice(1, -1);
152
154
  }
153
155
  // Variables and constants
@@ -260,7 +262,8 @@ function format(str = '', ctx, chart) {
260
262
  // Simple variable replacement
261
263
  }
262
264
  else {
263
- const valueAndFormat = expression.split(':');
265
+ const valueAndFormat = isQuotedString(expression) ?
266
+ [expression] : expression.split(':');
264
267
  replacement = resolveProperty(valueAndFormat.shift() || '');
265
268
  // Format the replacement
266
269
  if (valueAndFormat.length && typeof replacement === 'number') {
@@ -273,13 +276,14 @@ function format(str = '', ctx, chart) {
273
276
  }
274
277
  else {
275
278
  replacement = time.dateFormat(segment, replacement);
276
- // Use string literal in order to be preserved in the outer
277
- // expression
278
- if (hasSub) {
279
- replacement = `"${replacement}"`;
280
- }
281
279
  }
282
280
  }
281
+ // Use string literal in order to be preserved in the outer
282
+ // expression
283
+ subRegex.lastIndex = 0;
284
+ if (subRegex.test(match.find) && isString(replacement)) {
285
+ replacement = `"${replacement}"`;
286
+ }
283
287
  }
284
288
  str = str.replace(match.find, pick(replacement, ''));
285
289
  });
@@ -360,16 +364,16 @@ function numberFormat(number, decimals, decimalPoint, thousandsSep) {
360
364
  }
361
365
  const hasSeparators = thousandsSep || decimalPoint, locale = hasSeparators ?
362
366
  'en' :
363
- (this?.locale ||
364
- lang.locale ||
365
- doc.body.closest('[lang]')?.lang), cacheKey = JSON.stringify(options) + locale, nf = numberFormatCache[cacheKey] ?? (numberFormatCache[cacheKey] = new Intl.NumberFormat(locale, options));
367
+ (this?.locale || lang.locale || pageLang), cacheKey = JSON.stringify(options) + locale, nf = numberFormatCache[cacheKey] ?? (numberFormatCache[cacheKey] = new Intl.NumberFormat(locale, options));
366
368
  ret = nf.format(number);
367
369
  // If thousandsSep or decimalPoint are set, fall back to using English
368
370
  // format with string replacement for the separators.
369
371
  if (hasSeparators) {
370
372
  ret = ret
371
- .replace(/\,/g, thousandsSep ?? ',')
372
- .replace('.', decimalPoint ?? '.');
373
+ // Preliminary step to avoid re-swapping (#22402)
374
+ .replace(/([,\.])/g, '_$1')
375
+ .replace(/_\,/g, thousandsSep ?? ',')
376
+ .replace('_.', decimalPoint ?? '.');
373
377
  }
374
378
  if (
375
379
  // Remove signed zero (#20564)
@@ -9,7 +9,7 @@
9
9
  * */
10
10
  'use strict';
11
11
  import H from './Globals.js';
12
- const { win } = H;
12
+ const { pageLang, win } = H;
13
13
  import U from './Utilities.js';
14
14
  const { defined, error, extend, isNumber, isObject, isString, merge, objectEach, pad, splat, timeUnits, ucfirst } = U;
15
15
  /* *
@@ -36,9 +36,17 @@ const spanishWeekdayIndex = (weekday) => ['D', 'L', 'M', 'X', 'J', 'V', 'S'].ind
36
36
  * `Highcharts.setOptions`, or individually for each Chart item through the
37
37
  * [time](https://api.highcharts.com/highcharts/time) options set.
38
38
  *
39
- * The Time object is available from {@link Highcharts.Chart#time},
40
- * which refers to `Highcharts.time` if no individual time settings are
41
- * applied.
39
+ * The Time object is available from {@link Highcharts.Chart#time}, which refers
40
+ * to `Highcharts.time` unless individual time settings are applied for each
41
+ * chart.
42
+ *
43
+ * When configuring time settings for individual chart instances, be aware that
44
+ * using `Highcharts.dateFormat` or `Highcharts.time.dateFormat` within
45
+ * formatter callbacks relies on the global time object, which applies the
46
+ * global language and time zone settings. To ensure charts with local time
47
+ * settings function correctly, use `chart.time.dateFormat? instead. However,
48
+ * the recommended best practice is to use `setOptions` to define global time
49
+ * settings unless specific configurations are needed for each chart.
42
50
  *
43
51
  * @example
44
52
  * // Apply time settings globally
@@ -76,8 +84,8 @@ const spanishWeekdayIndex = (weekday) => ['D', 'L', 'M', 'X', 'J', 'V', 'S'].ind
76
84
  * @class
77
85
  * @name Highcharts.Time
78
86
  *
79
- * @param {Highcharts.TimeOptions} [options]
80
- * Time options as defined in [chart.options.time](/highcharts/time).
87
+ * @param {Highcharts.TimeOptions} [options] Time options as defined in
88
+ * [chart.options.time](/highcharts/time).
81
89
  */
82
90
  class Time {
83
91
  /* *
@@ -91,7 +99,9 @@ class Time {
91
99
  * Properties
92
100
  *
93
101
  * */
94
- this.options = {};
102
+ this.options = {
103
+ timezone: 'UTC'
104
+ };
95
105
  this.variableTimezone = false;
96
106
  this.Date = win.Date;
97
107
  this.update(options);
@@ -113,12 +123,13 @@ class Time {
113
123
  *
114
124
  */
115
125
  update(options = {}) {
116
- let timezone = options.timezone ?? 'UTC';
117
126
  this.dTLCache = {};
118
127
  this.options = options = merge(true, this.options, options);
119
128
  const { timezoneOffset, useUTC } = options;
120
129
  // Allow using a different Date class
121
130
  this.Date = options.Date || win.Date || Date;
131
+ // Assign the time zone. Handle the legacy, deprecated `useUTC` option.
132
+ let timezone = options.timezone;
122
133
  if (defined(useUTC)) {
123
134
  timezone = useUTC ? 'UTC' : void 0;
124
135
  }
@@ -194,7 +205,7 @@ class Time {
194
205
  /**
195
206
  * Shorthand to get a cached `Intl.DateTimeFormat` instance.
196
207
  */
197
- dateTimeFormat(options, timestamp, locale = this.options.locale) {
208
+ dateTimeFormat(options, timestamp, locale = this.options.locale || pageLang) {
198
209
  const cacheKey = JSON.stringify(options) + locale;
199
210
  if (isString(options)) {
200
211
  options = this.str2dtf(options);
@@ -561,7 +572,7 @@ class Time {
561
572
  }
562
573
  else if (isObject(format)) {
563
574
  const tzHours = (this.getTimezoneOffset(timestamp) || 0) /
564
- (60000 * 60), timeZone = this.options.timezone || ('Etc/GMT' + (tzHours >= 0 ? '+' : '') + tzHours), { prefix = '', suffix = '' } = format;
575
+ (60000 * 60), timeZone = this.timezone || ('Etc/GMT' + (tzHours >= 0 ? '+' : '') + tzHours), { prefix = '', suffix = '' } = format;
565
576
  format = prefix + this.dateTimeFormat(extend({ timeZone }, format), timestamp) + suffix;
566
577
  }
567
578
  // Optionally sentence-case the string and return
@@ -1094,7 +1094,7 @@ function getNestedProperty(path, parent) {
1094
1094
  }
1095
1095
  return thisProp ?? parent;
1096
1096
  }
1097
- const child = parent[pathElement];
1097
+ const child = parent[pathElement.replace(/[\\'"]/g, '')];
1098
1098
  // Filter on the child
1099
1099
  if (!defined(child) ||
1100
1100
  typeof child === 'function' ||
@@ -432,6 +432,7 @@ CSVConverter.defaultOptions = {
432
432
  ...DataConverter.defaultOptions,
433
433
  lineDelimiter: '\n'
434
434
  };
435
+ DataConverter.registerType('CSV', CSVConverter);
435
436
  /* *
436
437
  *
437
438
  * Default Export
@@ -12,6 +12,7 @@
12
12
  * - Gøran Slettemark
13
13
  * - Torstein Hønsi
14
14
  * - Wojciech Chmiel
15
+ * - Jomar Hønsi
15
16
  *
16
17
  * */
17
18
  'use strict';
@@ -560,11 +561,41 @@ DataConverter.defaultOptions = {
560
561
  * Declarations
561
562
  *
562
563
  * */
564
+ /* *
565
+ *
566
+ * Constants
567
+ *
568
+ * */
569
+ /**
570
+ * Registry as a record object with connector names and their class.
571
+ */
572
+ DataConverter.types = {};
563
573
  /* *
564
574
  *
565
575
  * Functions
566
576
  *
567
577
  * */
578
+ /**
579
+ * Adds a converter class to the registry.
580
+ *
581
+ * @private
582
+ *
583
+ * @param {string} key
584
+ * Registry key of the converter class.
585
+ *
586
+ * @param {DataConverterTypes} DataConverterClass
587
+ * Connector class (aka class constructor) to register.
588
+ *
589
+ * @return {boolean}
590
+ * Returns true, if the registration was successful. False is returned, if
591
+ * their is already a converter registered with this key.
592
+ */
593
+ function registerType(key, DataConverterClass) {
594
+ return (!!key &&
595
+ !DataConverter.types[key] &&
596
+ !!(DataConverter.types[key] = DataConverterClass));
597
+ }
598
+ DataConverter.registerType = registerType;
568
599
  /**
569
600
  * Converts an array of columns to a table instance. Second dimension of the
570
601
  * array are the row cells.
@@ -127,6 +127,7 @@ class GoogleSheetsConverter extends DataConverter {
127
127
  GoogleSheetsConverter.defaultOptions = {
128
128
  ...DataConverter.defaultOptions
129
129
  };
130
+ DataConverter.registerType('GoogleSheets', GoogleSheetsConverter);
130
131
  /* *
131
132
  *
132
133
  * Default Export
@@ -352,6 +352,7 @@ HTMLTableConverter.defaultOptions = {
352
352
  useRowspanHeaders: true,
353
353
  useMultiLevelHeaders: true
354
354
  };
355
+ DataConverter.registerType('HTMLTable', HTMLTableConverter);
355
356
  /* *
356
357
  *
357
358
  * Default Export
@@ -173,6 +173,7 @@ JSONConverter.defaultOptions = {
173
173
  data: [],
174
174
  orientation: 'rows'
175
175
  };
176
+ DataConverter.registerType('JSON', JSONConverter);
176
177
  /* *
177
178
  *
178
179
  * Default Export
@@ -547,10 +547,17 @@ function getPoint(series, boostPoint) {
547
547
  if (boostPoint instanceof PointClass) {
548
548
  return boostPoint;
549
549
  }
550
- const xData = ((series.getColumn('x').length ? series.getColumn('x') : void 0) ||
550
+ const isScatter = series.is('scatter'), xData = ((isScatter && series.getColumn('x', true).length ?
551
+ series.getColumn('x', true) :
552
+ void 0) ||
553
+ (series.getColumn('x').length ? series.getColumn('x') : void 0) ||
551
554
  seriesOptions.xData ||
552
555
  series.getColumn('x', true) ||
553
- false), point = new PointClass(series, (isArray(series.options.data) ? series.options.data : [])[boostPoint.i], xData ? xData[boostPoint.i] : void 0);
556
+ false), yData = (series.getColumn('y', true) ||
557
+ seriesOptions.yData ||
558
+ false), point = new PointClass(series, (isScatter && xData && yData) ?
559
+ [xData[boostPoint.i], yData[boostPoint.i]] :
560
+ (isArray(series.options.data) ? series.options.data : [])[boostPoint.i], xData ? xData[boostPoint.i] : void 0);
554
561
  point.category = pick(xAxis.categories ?
555
562
  xAxis.categories[point.x] :
556
563
  point.x, // @todo simplify
@@ -569,7 +576,6 @@ function getPoint(series, boostPoint) {
569
576
  * @private
570
577
  */
571
578
  function scatterProcessData(force) {
572
- var _a, _b, _c, _d;
573
579
  const series = this, { options, xAxis, yAxis } = series;
574
580
  // Process only on changes
575
581
  if (!series.isDirty &&
@@ -636,12 +642,12 @@ function scatterProcessData(force) {
636
642
  }
637
643
  }
638
644
  if (xRangeNeeded) {
639
- (_a = xAxis.options).max ?? (_a.max = xDataMax);
640
- (_b = xAxis.options).min ?? (_b.min = xDataMin);
645
+ xAxis.dataMax = Math.max(xDataMax, xAxis.dataMax || 0);
646
+ xAxis.dataMin = Math.min(xDataMin, xAxis.dataMin || 0);
641
647
  }
642
648
  if (yRangeNeeded) {
643
- (_c = yAxis.options).max ?? (_c.max = yDataMax);
644
- (_d = yAxis.options).min ?? (_d.min = yDataMin);
649
+ yAxis.dataMax = Math.max(yDataMax, yAxis.dataMax || 0);
650
+ yAxis.dataMin = Math.min(yDataMin, yAxis.dataMin || 0);
645
651
  }
646
652
  // Set properties as base processData
647
653
  series.cropped = cropped;
@@ -214,7 +214,7 @@ class AxisResizer {
214
214
  }
215
215
  top = axis.top;
216
216
  const minLength = Math.round(relativeLength(axisOptions.minLength || NaN, plotHeight)), maxLength = Math.round(relativeLength(axisOptions.maxLength || NaN, plotHeight));
217
- if (!isFirst) {
217
+ if (!isFirst && axesGroup === nextAxes) {
218
218
  // Try to change height first. yDelta could had changed
219
219
  yDelta = chartY - resizer.lastPos;
220
220
  // Normalize height to option limits
@@ -22,7 +22,7 @@ import G from '../../Core/Globals.js';
22
22
  const { doc, SVG_NS, win } = G;
23
23
  import HU from '../../Core/HttpUtilities.js';
24
24
  import U from '../../Core/Utilities.js';
25
- const { addEvent, css, createElement, discardElement, extend, find, fireEvent, isObject, merge, objectEach, pick, removeEvent, uniqueKey } = U;
25
+ const { addEvent, css, createElement, discardElement, extend, find, fireEvent, isObject, merge, objectEach, pick, removeEvent, splat, uniqueKey } = U;
26
26
  /* *
27
27
  *
28
28
  * Composition
@@ -757,15 +757,23 @@ var Exporting;
757
757
  }
758
758
  // Reflect axis extremes in the export (#5924)
759
759
  chart.axes.forEach(function (axis) {
760
- const axisCopy = find(chartCopy.axes, function (copy) {
761
- return copy.options.internalKey ===
762
- axis.userOptions.internalKey;
763
- }), extremes = axis.getExtremes(), userMin = extremes.userMin, userMax = extremes.userMax;
764
- if (axisCopy &&
765
- ((typeof userMin !== 'undefined' &&
760
+ const axisCopy = find(chartCopy.axes, (copy) => copy.options.internalKey === axis.userOptions.internalKey);
761
+ if (axisCopy) {
762
+ const extremes = axis.getExtremes(),
763
+ // Make sure min and max overrides in the
764
+ // `exporting.chartOptions.xAxis` settings are reflected.
765
+ // These should override user-set extremes via zooming,
766
+ // scrollbar etc (#7873).
767
+ exportOverride = splat(chartOptions?.[axis.coll] || {})[0], userMin = 'min' in exportOverride ?
768
+ exportOverride.min :
769
+ extremes.userMin, userMax = 'max' in exportOverride ?
770
+ exportOverride.max :
771
+ extremes.userMax;
772
+ if (((typeof userMin !== 'undefined' &&
766
773
  userMin !== axisCopy.min) || (typeof userMax !== 'undefined' &&
767
774
  userMax !== axisCopy.max))) {
768
- axisCopy.setExtremes(userMin, userMax, true, false);
775
+ axisCopy.setExtremes(userMin ?? void 0, userMax ?? void 0, true, false);
776
+ }
769
777
  }
770
778
  });
771
779
  // Get the SVG from the container's innerHTML
@@ -79,7 +79,9 @@ const SeriesLabelDefaults = {
79
79
  * small areas get a smaller font size. The default applies this
80
80
  * effect to area-like series but not line-like series.
81
81
  *
82
- * @type {number|null}
82
+ * @sample highcharts/demo/streamgraph
83
+ * Min and max font size on a streamgraph
84
+ * @type {number|null}
83
85
  */
84
86
  minFontSize: null,
85
87
  /**
@@ -87,7 +89,10 @@ const SeriesLabelDefaults = {
87
89
  * small areas get a smaller font size. The default applies this
88
90
  * effect to area-like series but not line-like series.
89
91
  *
90
- * @type {number|null}
92
+ * @sample highcharts/demo/streamgraph
93
+ * Min and max font size on a streamgraph
94
+ *
95
+ * @type {number|null}
91
96
  */
92
97
  maxFontSize: null,
93
98
  /**