@fluentui/react-charts 9.2.3 → 9.2.4

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 (194) hide show
  1. package/CHANGELOG.md +49 -10
  2. package/dist/index.d.ts +98 -5
  3. package/lib/components/AreaChart/AreaChart.js +3 -3
  4. package/lib/components/AreaChart/AreaChart.js.map +1 -1
  5. package/lib/components/AreaChart/useAreaChartStyles.styles.js +2 -2
  6. package/lib/components/AreaChart/useAreaChartStyles.styles.js.map +1 -1
  7. package/lib/components/AreaChart/useAreaChartStyles.styles.raw.js +3 -15
  8. package/lib/components/AreaChart/useAreaChartStyles.styles.raw.js.map +1 -1
  9. package/lib/components/ChartTable/ChartTable.js +89 -6
  10. package/lib/components/ChartTable/ChartTable.js.map +1 -1
  11. package/lib/components/CommonComponents/CartesianChart.js +38 -34
  12. package/lib/components/CommonComponents/CartesianChart.js.map +1 -1
  13. package/lib/components/CommonComponents/CartesianChart.types.js.map +1 -1
  14. package/lib/components/CommonComponents/useCartesianChartStyles.styles.js +17 -14
  15. package/lib/components/CommonComponents/useCartesianChartStyles.styles.js.map +1 -1
  16. package/lib/components/CommonComponents/useCartesianChartStyles.styles.raw.js +6 -33
  17. package/lib/components/CommonComponents/useCartesianChartStyles.styles.raw.js.map +1 -1
  18. package/lib/components/DeclarativeChart/DeclarativeChart.js +55 -16
  19. package/lib/components/DeclarativeChart/DeclarativeChart.js.map +1 -1
  20. package/lib/components/DeclarativeChart/PlotlyColorAdapter.js +19 -0
  21. package/lib/components/DeclarativeChart/PlotlyColorAdapter.js.map +1 -1
  22. package/lib/components/DeclarativeChart/PlotlySchemaAdapter.js +1058 -291
  23. package/lib/components/DeclarativeChart/PlotlySchemaAdapter.js.map +1 -1
  24. package/lib/components/DonutChart/Arc/useArcStyles.styles.js +8 -3
  25. package/lib/components/DonutChart/Arc/useArcStyles.styles.js.map +1 -1
  26. package/lib/components/DonutChart/Arc/useArcStyles.styles.raw.js +6 -2
  27. package/lib/components/DonutChart/Arc/useArcStyles.styles.raw.js.map +1 -1
  28. package/lib/components/DonutChart/DonutChart.js +6 -1
  29. package/lib/components/DonutChart/DonutChart.js.map +1 -1
  30. package/lib/components/DonutChart/DonutChart.types.js.map +1 -1
  31. package/lib/components/DonutChart/useDonutChartStyles.styles.js +21 -4
  32. package/lib/components/DonutChart/useDonutChartStyles.styles.js.map +1 -1
  33. package/lib/components/DonutChart/useDonutChartStyles.styles.raw.js +8 -4
  34. package/lib/components/DonutChart/useDonutChartStyles.styles.raw.js.map +1 -1
  35. package/lib/components/FunnelChart/FunnelChart.js +4 -2
  36. package/lib/components/FunnelChart/FunnelChart.js.map +1 -1
  37. package/lib/components/FunnelChart/funnelGeometry.js.map +1 -1
  38. package/lib/components/GaugeChart/GaugeChart.js +1 -2
  39. package/lib/components/GaugeChart/GaugeChart.js.map +1 -1
  40. package/lib/components/GroupedVerticalBarChart/GroupedVerticalBarChart.js +2 -2
  41. package/lib/components/GroupedVerticalBarChart/GroupedVerticalBarChart.js.map +1 -1
  42. package/lib/components/GroupedVerticalBarChart/useGroupedVerticalBarChartStyles.styles.js +4 -17
  43. package/lib/components/GroupedVerticalBarChart/useGroupedVerticalBarChartStyles.styles.js.map +1 -1
  44. package/lib/components/GroupedVerticalBarChart/useGroupedVerticalBarChartStyles.styles.raw.js +4 -21
  45. package/lib/components/GroupedVerticalBarChart/useGroupedVerticalBarChartStyles.styles.raw.js.map +1 -1
  46. package/lib/components/HorizontalBarChart/HorizontalBarChart.js +1 -1
  47. package/lib/components/HorizontalBarChart/HorizontalBarChart.js.map +1 -1
  48. package/lib/components/HorizontalBarChart/useHorizontalBarChartStyles.styles.js +7 -3
  49. package/lib/components/HorizontalBarChart/useHorizontalBarChartStyles.styles.js.map +1 -1
  50. package/lib/components/HorizontalBarChart/useHorizontalBarChartStyles.styles.raw.js +5 -2
  51. package/lib/components/HorizontalBarChart/useHorizontalBarChartStyles.styles.raw.js.map +1 -1
  52. package/lib/components/LineChart/LineChart.js +271 -271
  53. package/lib/components/LineChart/LineChart.js.map +1 -1
  54. package/lib/components/LineChart/LineChart.types.js.map +1 -1
  55. package/lib/components/LineChart/useLineChartStyles.styles.js +23 -10
  56. package/lib/components/LineChart/useLineChartStyles.styles.js.map +1 -1
  57. package/lib/components/LineChart/useLineChartStyles.styles.raw.js +4 -21
  58. package/lib/components/LineChart/useLineChartStyles.styles.raw.js.map +1 -1
  59. package/lib/components/ResponsiveContainer/withResponsiveContainer.js.map +1 -1
  60. package/lib/components/SankeyChart/SankeyChart.js.map +1 -1
  61. package/lib/components/SankeyChart/useSankeyChartStyles.styles.js +12 -25
  62. package/lib/components/SankeyChart/useSankeyChartStyles.styles.js.map +1 -1
  63. package/lib/components/SankeyChart/useSankeyChartStyles.styles.raw.js +2 -12
  64. package/lib/components/SankeyChart/useSankeyChartStyles.styles.raw.js.map +1 -1
  65. package/lib/components/ScatterChart/ScatterChart.js +114 -75
  66. package/lib/components/ScatterChart/ScatterChart.js.map +1 -1
  67. package/lib/components/ScatterChart/ScatterChart.types.js.map +1 -1
  68. package/lib/components/ScatterChart/useScatterChartStyles.styles.js +11 -7
  69. package/lib/components/ScatterChart/useScatterChartStyles.styles.js.map +1 -1
  70. package/lib/components/ScatterChart/useScatterChartStyles.styles.raw.js +4 -22
  71. package/lib/components/ScatterChart/useScatterChartStyles.styles.raw.js.map +1 -1
  72. package/lib/components/VerticalBarChart/VerticalBarChart.js +2 -2
  73. package/lib/components/VerticalBarChart/VerticalBarChart.js.map +1 -1
  74. package/lib/components/VerticalBarChart/useVerticalBarChartStyles.styles.js +8 -6
  75. package/lib/components/VerticalBarChart/useVerticalBarChartStyles.styles.js.map +1 -1
  76. package/lib/components/VerticalBarChart/useVerticalBarChartStyles.styles.raw.js +5 -19
  77. package/lib/components/VerticalBarChart/useVerticalBarChartStyles.styles.raw.js.map +1 -1
  78. package/lib/components/VerticalStackedBarChart/VerticalStackedBarChart.js +2 -2
  79. package/lib/components/VerticalStackedBarChart/VerticalStackedBarChart.js.map +1 -1
  80. package/lib/components/VerticalStackedBarChart/useVerticalStackedBarChartStyles.styles.js +7 -6
  81. package/lib/components/VerticalStackedBarChart/useVerticalStackedBarChartStyles.styles.js.map +1 -1
  82. package/lib/components/VerticalStackedBarChart/useVerticalStackedBarChartStyles.styles.raw.js +4 -19
  83. package/lib/components/VerticalStackedBarChart/useVerticalStackedBarChartStyles.styles.raw.js.map +1 -1
  84. package/lib/types/DataPoint.js +3 -1
  85. package/lib/types/DataPoint.js.map +1 -1
  86. package/lib/utilities/Common.styles.js +47 -0
  87. package/lib/utilities/Common.styles.js.map +1 -0
  88. package/lib/utilities/Common.styles.raw.js +47 -0
  89. package/lib/utilities/Common.styles.raw.js.map +1 -0
  90. package/lib/utilities/SVGTooltipText.js.map +1 -1
  91. package/lib/utilities/image-export-utils.js.map +1 -1
  92. package/lib/utilities/index.js +1 -0
  93. package/lib/utilities/index.js.map +1 -1
  94. package/lib/utilities/scatterpolar-utils.js +52 -0
  95. package/lib/utilities/scatterpolar-utils.js.map +1 -0
  96. package/lib/utilities/utilities.js +309 -142
  97. package/lib/utilities/utilities.js.map +1 -1
  98. package/lib/utilities/vbc-utils.js.map +1 -1
  99. package/lib-commonjs/components/AreaChart/AreaChart.js +2 -2
  100. package/lib-commonjs/components/AreaChart/AreaChart.js.map +1 -1
  101. package/lib-commonjs/components/AreaChart/useAreaChartStyles.styles.js.map +1 -1
  102. package/lib-commonjs/components/AreaChart/useAreaChartStyles.styles.raw.js +2 -14
  103. package/lib-commonjs/components/AreaChart/useAreaChartStyles.styles.raw.js.map +1 -1
  104. package/lib-commonjs/components/ChartTable/ChartTable.js +89 -6
  105. package/lib-commonjs/components/ChartTable/ChartTable.js.map +1 -1
  106. package/lib-commonjs/components/CommonComponents/CartesianChart.js +38 -34
  107. package/lib-commonjs/components/CommonComponents/CartesianChart.js.map +1 -1
  108. package/lib-commonjs/components/CommonComponents/CartesianChart.types.js.map +1 -1
  109. package/lib-commonjs/components/CommonComponents/useCartesianChartStyles.styles.js +15 -13
  110. package/lib-commonjs/components/CommonComponents/useCartesianChartStyles.styles.js.map +1 -1
  111. package/lib-commonjs/components/CommonComponents/useCartesianChartStyles.styles.raw.js +4 -32
  112. package/lib-commonjs/components/CommonComponents/useCartesianChartStyles.styles.raw.js.map +1 -1
  113. package/lib-commonjs/components/DeclarativeChart/DeclarativeChart.js +58 -19
  114. package/lib-commonjs/components/DeclarativeChart/DeclarativeChart.js.map +1 -1
  115. package/lib-commonjs/components/DeclarativeChart/PlotlyColorAdapter.js +22 -0
  116. package/lib-commonjs/components/DeclarativeChart/PlotlyColorAdapter.js.map +1 -1
  117. package/lib-commonjs/components/DeclarativeChart/PlotlySchemaAdapter.js +1070 -291
  118. package/lib-commonjs/components/DeclarativeChart/PlotlySchemaAdapter.js.map +1 -1
  119. package/lib-commonjs/components/DonutChart/Arc/useArcStyles.styles.js +12 -3
  120. package/lib-commonjs/components/DonutChart/Arc/useArcStyles.styles.js.map +1 -1
  121. package/lib-commonjs/components/DonutChart/Arc/useArcStyles.styles.raw.js +6 -2
  122. package/lib-commonjs/components/DonutChart/Arc/useArcStyles.styles.raw.js.map +1 -1
  123. package/lib-commonjs/components/DonutChart/DonutChart.js +6 -1
  124. package/lib-commonjs/components/DonutChart/DonutChart.js.map +1 -1
  125. package/lib-commonjs/components/DonutChart/DonutChart.types.js.map +1 -1
  126. package/lib-commonjs/components/DonutChart/useDonutChartStyles.styles.js +32 -4
  127. package/lib-commonjs/components/DonutChart/useDonutChartStyles.styles.js.map +1 -1
  128. package/lib-commonjs/components/DonutChart/useDonutChartStyles.styles.raw.js +8 -4
  129. package/lib-commonjs/components/DonutChart/useDonutChartStyles.styles.raw.js.map +1 -1
  130. package/lib-commonjs/components/FunnelChart/FunnelChart.js +4 -2
  131. package/lib-commonjs/components/FunnelChart/FunnelChart.js.map +1 -1
  132. package/lib-commonjs/components/FunnelChart/funnelGeometry.js.map +1 -1
  133. package/lib-commonjs/components/GaugeChart/GaugeChart.js +1 -2
  134. package/lib-commonjs/components/GaugeChart/GaugeChart.js.map +1 -1
  135. package/lib-commonjs/components/GroupedVerticalBarChart/GroupedVerticalBarChart.js +2 -2
  136. package/lib-commonjs/components/GroupedVerticalBarChart/GroupedVerticalBarChart.js.map +1 -1
  137. package/lib-commonjs/components/GroupedVerticalBarChart/useGroupedVerticalBarChartStyles.styles.js +2 -19
  138. package/lib-commonjs/components/GroupedVerticalBarChart/useGroupedVerticalBarChartStyles.styles.js.map +1 -1
  139. package/lib-commonjs/components/GroupedVerticalBarChart/useGroupedVerticalBarChartStyles.styles.raw.js +3 -20
  140. package/lib-commonjs/components/GroupedVerticalBarChart/useGroupedVerticalBarChartStyles.styles.raw.js.map +1 -1
  141. package/lib-commonjs/components/HorizontalBarChart/HorizontalBarChart.js +1 -1
  142. package/lib-commonjs/components/HorizontalBarChart/HorizontalBarChart.js.map +1 -1
  143. package/lib-commonjs/components/HorizontalBarChart/useHorizontalBarChartStyles.styles.js +10 -3
  144. package/lib-commonjs/components/HorizontalBarChart/useHorizontalBarChartStyles.styles.js.map +1 -1
  145. package/lib-commonjs/components/HorizontalBarChart/useHorizontalBarChartStyles.styles.raw.js +5 -2
  146. package/lib-commonjs/components/HorizontalBarChart/useHorizontalBarChartStyles.styles.raw.js.map +1 -1
  147. package/lib-commonjs/components/LineChart/LineChart.js +269 -269
  148. package/lib-commonjs/components/LineChart/LineChart.js.map +1 -1
  149. package/lib-commonjs/components/LineChart/LineChart.types.js.map +1 -1
  150. package/lib-commonjs/components/LineChart/useLineChartStyles.styles.js +30 -9
  151. package/lib-commonjs/components/LineChart/useLineChartStyles.styles.js.map +1 -1
  152. package/lib-commonjs/components/LineChart/useLineChartStyles.styles.raw.js +2 -20
  153. package/lib-commonjs/components/LineChart/useLineChartStyles.styles.raw.js.map +1 -1
  154. package/lib-commonjs/components/ResponsiveContainer/withResponsiveContainer.js.map +1 -1
  155. package/lib-commonjs/components/SankeyChart/SankeyChart.js.map +1 -1
  156. package/lib-commonjs/components/SankeyChart/useSankeyChartStyles.styles.js +23 -33
  157. package/lib-commonjs/components/SankeyChart/useSankeyChartStyles.styles.js.map +1 -1
  158. package/lib-commonjs/components/SankeyChart/useSankeyChartStyles.styles.raw.js +1 -12
  159. package/lib-commonjs/components/SankeyChart/useSankeyChartStyles.styles.raw.js.map +1 -1
  160. package/lib-commonjs/components/ScatterChart/ScatterChart.js +112 -73
  161. package/lib-commonjs/components/ScatterChart/ScatterChart.js.map +1 -1
  162. package/lib-commonjs/components/ScatterChart/ScatterChart.types.js.map +1 -1
  163. package/lib-commonjs/components/ScatterChart/useScatterChartStyles.styles.js +13 -7
  164. package/lib-commonjs/components/ScatterChart/useScatterChartStyles.styles.js.map +1 -1
  165. package/lib-commonjs/components/ScatterChart/useScatterChartStyles.styles.raw.js +2 -20
  166. package/lib-commonjs/components/ScatterChart/useScatterChartStyles.styles.raw.js.map +1 -1
  167. package/lib-commonjs/components/VerticalBarChart/VerticalBarChart.js +1 -1
  168. package/lib-commonjs/components/VerticalBarChart/VerticalBarChart.js.map +1 -1
  169. package/lib-commonjs/components/VerticalBarChart/useVerticalBarChartStyles.styles.js +5 -3
  170. package/lib-commonjs/components/VerticalBarChart/useVerticalBarChartStyles.styles.js.map +1 -1
  171. package/lib-commonjs/components/VerticalBarChart/useVerticalBarChartStyles.styles.raw.js +3 -17
  172. package/lib-commonjs/components/VerticalBarChart/useVerticalBarChartStyles.styles.raw.js.map +1 -1
  173. package/lib-commonjs/components/VerticalStackedBarChart/VerticalStackedBarChart.js +1 -1
  174. package/lib-commonjs/components/VerticalStackedBarChart/VerticalStackedBarChart.js.map +1 -1
  175. package/lib-commonjs/components/VerticalStackedBarChart/useVerticalStackedBarChartStyles.styles.js +5 -3
  176. package/lib-commonjs/components/VerticalStackedBarChart/useVerticalStackedBarChartStyles.styles.js.map +1 -1
  177. package/lib-commonjs/components/VerticalStackedBarChart/useVerticalStackedBarChartStyles.styles.raw.js +3 -18
  178. package/lib-commonjs/components/VerticalStackedBarChart/useVerticalStackedBarChartStyles.styles.raw.js.map +1 -1
  179. package/lib-commonjs/types/DataPoint.js +3 -1
  180. package/lib-commonjs/types/DataPoint.js.map +1 -1
  181. package/lib-commonjs/utilities/Common.styles.js +71 -0
  182. package/lib-commonjs/utilities/Common.styles.js.map +1 -0
  183. package/lib-commonjs/utilities/Common.styles.raw.js +71 -0
  184. package/lib-commonjs/utilities/Common.styles.raw.js.map +1 -0
  185. package/lib-commonjs/utilities/SVGTooltipText.js.map +1 -1
  186. package/lib-commonjs/utilities/image-export-utils.js.map +1 -1
  187. package/lib-commonjs/utilities/index.js +1 -0
  188. package/lib-commonjs/utilities/index.js.map +1 -1
  189. package/lib-commonjs/utilities/scatterpolar-utils.js +67 -0
  190. package/lib-commonjs/utilities/scatterpolar-utils.js.map +1 -0
  191. package/lib-commonjs/utilities/utilities.js +322 -133
  192. package/lib-commonjs/utilities/utilities.js.map +1 -1
  193. package/lib-commonjs/utilities/vbc-utils.js.map +1 -1
  194. package/package.json +9 -9
@@ -1,6 +1,6 @@
1
1
  import { axisRight as d3AxisRight, axisBottom as d3AxisBottom, axisLeft as d3AxisLeft } from 'd3-axis';
2
2
  import { max as d3Max, min as d3Min, ticks as d3Ticks, nice as d3nice, sum as d3Sum, mean as d3Mean, median as d3Median } from 'd3-array';
3
- import { scaleLinear as d3ScaleLinear, scaleBand as d3ScaleBand, scaleUtc as d3ScaleUtc, scaleTime as d3ScaleTime } from 'd3-scale';
3
+ import { scaleLinear as d3ScaleLinear, scaleBand as d3ScaleBand, scaleUtc as d3ScaleUtc, scaleTime as d3ScaleTime, scaleLog as d3ScaleLog } from 'd3-scale';
4
4
  import { select as d3Select, selectAll as d3SelectAll } from 'd3-selection';
5
5
  import { format as d3Format } from 'd3-format';
6
6
  import { timeFormat as d3TimeFormat, timeFormatLocale as d3TimeFormatLocale, utcFormat as d3UtcFormat } from 'd3-time-format';
@@ -8,9 +8,10 @@ import { timeSecond as d3TimeSecond, timeMinute as d3TimeMinute, timeHour as d3T
8
8
  import { curveLinear as d3CurveLinear, curveNatural as d3CurveNatural, curveStep as d3CurveStep, curveStepAfter as d3CurveStepAfter, curveStepBefore as d3CurveStepBefore } from 'd3-shape';
9
9
  import { formatPrefix as d3FormatPrefix } from 'd3-format';
10
10
  import { useFluent_unstable as useFluent } from '@fluentui/react-shared-contexts';
11
- import { formatDateToLocaleString, formatToLocaleString, getMultiLevelDateTimeFormatOptions } from '@fluentui/chart-utilities';
11
+ import { formatDateToLocaleString, formatToLocaleString, getMultiLevelDateTimeFormatOptions, isInvalidValue, isNumber } from '@fluentui/chart-utilities';
12
12
  export const MIN_DOMAIN_MARGIN = 8;
13
13
  export const MIN_DONUT_RADIUS = 1;
14
+ export const DEFAULT_DATE_STRING = '2000-01-01';
14
15
  export var ChartTypes = /*#__PURE__*/ function(ChartTypes) {
15
16
  ChartTypes[ChartTypes["AreaChart"] = 0] = "AreaChart";
16
17
  ChartTypes[ChartTypes["LineChart"] = 1] = "LineChart";
@@ -63,9 +64,9 @@ function yAxisTickFormatterInternal(value, limitWidth = false) {
63
64
  * Create Numeric X axis
64
65
  * @export
65
66
  * @param {IXAxisParams} xAxisParams
66
- */ export function createNumericXAxis(xAxisParams, tickParams, chartType, culture) {
67
- const { domainNRangeValues, showRoundOffXTickValues = false, xAxistickSize = 6, tickPadding = 10, xAxisCount, xAxisElement, hideTickOverlap, calcMaxLabelWidth } = xAxisParams;
68
- const xAxisScale = d3ScaleLinear().domain([
67
+ */ export function createNumericXAxis(xAxisParams, tickParams, chartType, culture, scaleType) {
68
+ const { domainNRangeValues, showRoundOffXTickValues = false, xAxistickSize = 6, tickPadding = 10, xAxisCount, xAxisElement, hideTickOverlap, calcMaxLabelWidth, tickStep, tick0 } = xAxisParams;
69
+ const xAxisScale = createNumericScale(scaleType).domain([
69
70
  domainNRangeValues.dStartValue,
70
71
  domainNRangeValues.dEndValue
71
72
  ]).range([
@@ -74,33 +75,38 @@ function yAxisTickFormatterInternal(value, limitWidth = false) {
74
75
  ]);
75
76
  showRoundOffXTickValues && xAxisScale.nice();
76
77
  let tickCount = xAxisCount !== null && xAxisCount !== void 0 ? xAxisCount : 6;
77
- const tickFormat = (domainValue, _index)=>{
78
+ const tickFormat = (domainValue, _index, defaultFormat)=>{
78
79
  if (tickParams.tickFormat) {
79
80
  return d3Format(tickParams.tickFormat)(domainValue);
80
81
  }
81
82
  const xAxisValue = typeof domainValue === 'number' ? domainValue : domainValue.valueOf();
82
- return formatToLocaleString(xAxisValue, culture);
83
+ return (defaultFormat === null || defaultFormat === void 0 ? void 0 : defaultFormat(xAxisValue)) === '' ? '' : formatToLocaleString(xAxisValue, culture);
83
84
  };
84
85
  if (hideTickOverlap && typeof xAxisCount === 'undefined') {
85
- const longestLabelWidth = calcMaxLabelWidth(xAxisScale.ticks().map(tickFormat)) + 20;
86
+ const longestLabelWidth = calcMaxLabelWidth(xAxisScale.ticks().map((v, i)=>tickFormat(v, i))) + 20;
86
87
  const [start, end] = xAxisScale.range();
87
88
  tickCount = Math.min(Math.max(1, Math.floor(Math.abs(end - start) / longestLabelWidth)), 10);
88
89
  }
89
- const xAxis = d3AxisBottom(xAxisScale).tickSize(xAxistickSize).tickPadding(tickPadding).ticks(tickCount).tickFormat(tickFormat);
90
+ const xAxis = d3AxisBottom(xAxisScale).tickSize(xAxistickSize).tickPadding(tickPadding).ticks(tickCount).tickFormat((v, i)=>tickFormat(v, i, xAxisScale.tickFormat(tickCount)));
90
91
  if ([
91
92
  6,
92
93
  8
93
94
  ].includes(chartType)) {
94
95
  xAxis.tickSizeInner(-(xAxisParams.containerHeight - xAxisParams.margins.top));
95
96
  }
97
+ let customTickValues;
96
98
  if (tickParams.tickValues) {
97
- xAxis.tickValues(tickParams.tickValues);
99
+ customTickValues = tickParams.tickValues;
100
+ } else if (tickStep) {
101
+ customTickValues = generateNumericTicks(scaleType, tickStep, tick0, xAxisScale.domain());
102
+ }
103
+ if (customTickValues) {
104
+ xAxis.tickValues(customTickValues);
98
105
  }
99
106
  if (xAxisElement) {
100
107
  d3Select(xAxisElement).call(xAxis).selectAll('text').attr('aria-hidden', 'true');
101
108
  }
102
- var _tickParams_tickValues;
103
- const tickValues = ((_tickParams_tickValues = tickParams.tickValues) !== null && _tickParams_tickValues !== void 0 ? _tickParams_tickValues : xAxisScale.ticks(tickCount)).map(xAxis.tickFormat());
109
+ const tickValues = (customTickValues !== null && customTickValues !== void 0 ? customTickValues : xAxisScale.ticks(tickCount)).map(xAxis.tickFormat());
104
110
  return {
105
111
  xScale: xAxisScale,
106
112
  tickValues
@@ -296,7 +302,7 @@ export function getDateFormatLevel(date, useUTC) {
296
302
  * @param {IXAxisParams} xAxisParams
297
303
  * @param {ITickParams} tickParams
298
304
  */ export function createDateXAxis(xAxisParams, tickParams, culture, options, timeFormatLocale, customDateTimeFormatter, useUTC, chartType) {
299
- const { domainNRangeValues, xAxisElement, tickPadding = 6, xAxistickSize = 6, xAxisCount, calcMaxLabelWidth } = xAxisParams;
305
+ const { domainNRangeValues, xAxisElement, tickPadding = 6, xAxistickSize = 6, xAxisCount, calcMaxLabelWidth, tickStep, tick0 } = xAxisParams;
300
306
  const isUtcSet = useUTC === true || useUTC === 'utc';
301
307
  const xAxisScale = isUtcSet ? d3ScaleUtc() : d3ScaleTime();
302
308
  xAxisScale.domain([
@@ -347,12 +353,19 @@ export function getDateFormatLevel(date, useUTC) {
347
353
  ].includes(chartType)) {
348
354
  xAxis.tickSizeInner(-(xAxisParams.containerHeight - xAxisParams.margins.top));
349
355
  }
350
- tickParams.tickValues ? xAxis.tickValues(tickParams.tickValues) : '';
356
+ let customTickValues;
357
+ if (tickParams.tickValues) {
358
+ customTickValues = tickParams.tickValues;
359
+ } else if (tickStep) {
360
+ customTickValues = generateDateTicks(tickStep, tick0, xAxisScale.domain(), useUTC);
361
+ }
362
+ if (customTickValues) {
363
+ xAxis.tickValues(customTickValues);
364
+ }
351
365
  if (xAxisElement) {
352
366
  d3Select(xAxisElement).call(xAxis).selectAll('text').attr('aria-hidden', 'true');
353
367
  }
354
- var _tickParams_tickValues;
355
- const tickValues = ((_tickParams_tickValues = tickParams.tickValues) !== null && _tickParams_tickValues !== void 0 ? _tickParams_tickValues : xAxisScale.ticks(tickCount)).map(xAxis.tickFormat());
368
+ const tickValues = (customTickValues !== null && customTickValues !== void 0 ? customTickValues : xAxisScale.ticks(tickCount)).map(xAxis.tickFormat());
356
369
  return {
357
370
  xScale: xAxisScale,
358
371
  tickValues
@@ -484,7 +497,7 @@ export function createYAxisForHorizontalBarChartWithAxis(yAxisParams, isRtl) {
484
497
  const { yMinMaxValues = {
485
498
  startValue: 0,
486
499
  endValue: 0
487
- }, yAxisElement = null, yMaxValue = 0, yMinValue = 0, containerHeight, margins, tickPadding = 12, maxOfYVal = 0, yAxisTickFormat, yAxisTickCount = 4 } = yAxisParams;
500
+ }, yAxisElement = null, yMaxValue = 0, yMinValue = 0, containerHeight, margins, tickPadding = 12, maxOfYVal = 0, yAxisTickFormat, yAxisTickCount = 4, tickValues, tickStep, tick0 } = yAxisParams;
488
501
  // maxOfYVal coming from horizontal bar chart with axis (Calculation done at base file)
489
502
  const tempVal = maxOfYVal || yMinMaxValues.endValue;
490
503
  const finalYmax = tempVal > yMaxValue ? tempVal : yMaxValue;
@@ -499,14 +512,23 @@ export function createYAxisForHorizontalBarChartWithAxis(yAxisParams, isRtl) {
499
512
  const axis = isRtl ? d3AxisRight(yAxisScale) : d3AxisLeft(yAxisScale);
500
513
  const yAxis = axis.tickPadding(tickPadding).ticks(yAxisTickCount);
501
514
  yAxisTickFormat ? yAxis.tickFormat(yAxisTickFormat) : yAxis.tickFormat(defaultYAxisTickFormatter);
515
+ let customTickValues;
516
+ if (tickValues) {
517
+ customTickValues = tickValues;
518
+ } else if (tickStep) {
519
+ customTickValues = generateNumericTicks(undefined, tickStep, tick0, yAxisScale.domain());
520
+ }
521
+ if (customTickValues) {
522
+ yAxis.tickValues(customTickValues);
523
+ }
502
524
  yAxisElement ? d3Select(yAxisElement).call(yAxis).selectAll('text').attr('aria-hidden', 'true') : '';
503
525
  return yAxisScale;
504
526
  }
505
- export function createNumericYAxis(yAxisParams, isRtl, axisData, isIntegralDataset, chartType, useSecondaryYScale = false, roundedTicks = false) {
527
+ export function createNumericYAxis(yAxisParams, isRtl, axisData, isIntegralDataset, chartType, useSecondaryYScale = false, roundedTicks = false, scaleType) {
506
528
  const { yMinMaxValues = {
507
529
  startValue: 0,
508
530
  endValue: 0
509
- }, yAxisElement = null, yMaxValue = 0, yMinValue = 0, containerHeight, containerWidth, margins, tickPadding = 12, maxOfYVal = 0, yAxisTickFormat, yAxisTickCount = 4, eventAnnotationProps, eventLabelHeight } = yAxisParams;
531
+ }, yAxisElement = null, yMaxValue = 0, yMinValue = 0, containerHeight, containerWidth, margins, tickPadding = 12, maxOfYVal = 0, yAxisTickFormat, yAxisTickCount = 4, eventAnnotationProps, eventLabelHeight, tickValues, tickStep, tick0 } = yAxisParams;
510
532
  // maxOfYVal coming from only area chart and Grouped vertical bar chart(Calculation done at base file)
511
533
  const tempVal = maxOfYVal || yMinMaxValues.endValue || 0;
512
534
  const finalYmax = tempVal > yMaxValue ? tempVal : yMaxValue;
@@ -519,18 +541,53 @@ export function createNumericYAxis(yAxisParams, isRtl, axisData, isIntegralDatas
519
541
  yMin = yMin - yPadding;
520
542
  yMax = yMax + yPadding;
521
543
  }
522
- const yAxisScale = d3ScaleLinear().domain([
544
+ let scaleDomain = [
523
545
  domainValues[0],
524
- yMax
525
- ]).range([
546
+ domainValues[domainValues.length - 1]
547
+ ];
548
+ if (scaleType === 'log') {
549
+ let domainStart = yMinMaxValues.startValue;
550
+ let domainEnd = yMinMaxValues.endValue;
551
+ if (yMinValue > 0) {
552
+ domainStart = Math.min(domainStart, yMinValue);
553
+ }
554
+ if (yMaxValue > 0) {
555
+ domainEnd = Math.max(domainEnd, yMaxValue);
556
+ }
557
+ scaleDomain = [
558
+ domainStart,
559
+ domainEnd
560
+ ];
561
+ }
562
+ const yAxisScale = createNumericScale(scaleType).domain(scaleDomain).range([
526
563
  containerHeight - margins.bottom,
527
564
  margins.top + (eventAnnotationProps ? eventLabelHeight : 0)
528
565
  ]);
529
566
  const axis = !isRtl && useSecondaryYScale || isRtl && !useSecondaryYScale ? d3AxisRight(yAxisScale) : d3AxisLeft(yAxisScale);
530
- const yAxis = axis.tickPadding(tickPadding).tickValues(domainValues).tickSizeInner(-(containerWidth - margins.left - margins.right));
531
- yAxisTickFormat ? yAxis.tickFormat(yAxisTickFormat) : yAxis.tickFormat(defaultYAxisTickFormatter);
567
+ const yAxis = axis.tickPadding(tickPadding).tickSizeInner(-(containerWidth - margins.left - margins.right));
568
+ let customTickValues;
569
+ if (tickValues) {
570
+ customTickValues = tickValues;
571
+ } else if (tickStep) {
572
+ customTickValues = generateNumericTicks(scaleType, tickStep, tick0, yAxisScale.domain());
573
+ }
574
+ if (customTickValues) {
575
+ yAxis.tickValues(customTickValues);
576
+ axisData.yAxisDomainValues = customTickValues;
577
+ } else {
578
+ if (scaleType === 'log') {
579
+ axisData.yAxisDomainValues = yAxisScale.ticks();
580
+ } else {
581
+ yAxis.tickValues(domainValues);
582
+ axisData.yAxisDomainValues = domainValues;
583
+ }
584
+ }
585
+ const tickFormat = (domainValue, index, defaultFormat)=>{
586
+ const value = typeof domainValue === 'number' ? domainValue : domainValue.valueOf();
587
+ return (defaultFormat === null || defaultFormat === void 0 ? void 0 : defaultFormat(value)) === '' ? '' : defaultYAxisTickFormatter(value);
588
+ };
589
+ yAxisTickFormat ? yAxis.tickFormat(yAxisTickFormat) : yAxis.tickFormat((v, i)=>tickFormat(v, i, yAxisScale.tickFormat(yAxisTickCount)));
532
590
  yAxisElement ? d3Select(yAxisElement).call(yAxis).selectAll('text').attr('aria-hidden', 'true') : '';
533
- axisData.yAxisDomainValues = domainValues;
534
591
  return yAxisScale;
535
592
  }
536
593
  /**
@@ -806,7 +863,7 @@ export function tooltipOfAxislabels(axistooltipProps) {
806
863
  return null;
807
864
  }
808
865
  const div = d3Select('body').append('div').attr('id', id).attr('class', tooltipCls).style('opacity', 0);
809
- const aa = axis.selectAll('#BaseSpan')._groups[0];
866
+ const aa = axis.selectAll('[id^="BaseSpan-"]')._groups[0];
810
867
  const baseSpanLength = aa && Object.keys(aa).length;
811
868
  const originalDataArray = [];
812
869
  for(let i = 0; i < baseSpanLength; i++){
@@ -850,59 +907,24 @@ export function tooltipOfAxislabels(axistooltipProps) {
850
907
  * @param {number} width
851
908
  * @param {boolean} isRTL
852
909
  * @returns {IDomainNRange}
853
- */ export function domainRangeOfNumericForAreaChart(points, margins, width, isRTL) {
854
- const xMin = d3Min(points, (point)=>{
855
- return d3Min(point.data, (item)=>item.x);
856
- });
857
- const xMax = d3Max(points, (point)=>{
858
- return d3Max(point.data, (item)=>{
859
- return item.x;
860
- });
861
- });
862
- const rStartValue = margins.left;
863
- const rEndValue = width - margins.right;
864
- return isRTL ? {
865
- dStartValue: xMax,
866
- dEndValue: xMin,
867
- rStartValue,
868
- rEndValue
869
- } : {
870
- dStartValue: xMin,
871
- dEndValue: xMax,
872
- rStartValue,
873
- rEndValue
874
- };
875
- }
876
- /**
877
- * Calculates Domain and range values for Numeric X axis for scatter chart.
878
- * @export
879
- * @param {LineChartPoints[]} points
880
- * @param {IMargins} margins
881
- * @param {number} width
882
- * @param {boolean} isRTL
883
- * @returns {IDomainNRange}
884
- */ export function domainRangeOfNumericForScatterChart(points, margins, width, isRTL) {
885
- let xMin = d3Min(points, (point)=>{
886
- return d3Min(point.data, (item)=>item.x);
887
- });
888
- let xMax = d3Max(points, (point)=>{
889
- return d3Max(point.data, (item)=>{
890
- return item.x;
891
- });
892
- });
893
- const xPadding = (xMax - xMin) * 0.1;
894
- xMin = xMin - xPadding;
895
- xMax = xMax + xPadding;
910
+ */ export function domainRangeOfNumericForAreaLineScatterCharts(points, margins, width, isRTL, scaleType, hasMarkersMode) {
911
+ const isScatterPolar = isScatterPolarSeries(points);
912
+ let [xMin, xMax] = getScatterXDomainExtent(points, scaleType);
913
+ if (hasMarkersMode) {
914
+ const xPadding = getDomainPaddingForMarkers(xMin, xMax, scaleType);
915
+ xMin = xMin - xPadding.start;
916
+ xMax = xMax + xPadding.end;
917
+ }
896
918
  const rStartValue = margins.left;
897
919
  const rEndValue = width - margins.right;
898
920
  return isRTL ? {
899
- dStartValue: xMax,
900
- dEndValue: xMin,
921
+ dStartValue: isScatterPolar ? 1 : xMax,
922
+ dEndValue: isScatterPolar ? -1 : xMin,
901
923
  rStartValue,
902
924
  rEndValue
903
925
  } : {
904
- dStartValue: xMin,
905
- dEndValue: xMax,
926
+ dStartValue: isScatterPolar ? -1 : xMin,
927
+ dEndValue: isScatterPolar ? 1 : xMax,
906
928
  rStartValue,
907
929
  rEndValue
908
930
  };
@@ -1030,22 +1052,15 @@ export function tooltipOfAxislabels(axistooltipProps) {
1030
1052
  * @param {boolean} isRTL
1031
1053
  * @param {Date[] | number[]} tickValues
1032
1054
  * @returns {IDomainNRange}
1033
- */ export function domainRangeOfDateForAreaLineVerticalBarChart(points, margins, width, isRTL, tickValues = [], chartType, barWidth) {
1055
+ */ export function domainRangeOfDateForAreaLineScatterVerticalBarCharts(points, margins, width, isRTL, tickValues = [], chartType, barWidth, hasMarkersMode) {
1034
1056
  let sDate;
1035
1057
  let lDate;
1036
- if (chartType === 0 || chartType === 1) {
1037
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
1038
- sDate = d3Min(points, (point)=>{
1039
- return d3Min(point.data, (item)=>{
1040
- return item.x;
1041
- });
1042
- });
1043
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
1044
- lDate = d3Max(points, (point)=>{
1045
- return d3Max(point.data, (item)=>{
1046
- return item.x;
1047
- });
1048
- });
1058
+ if ([
1059
+ 0,
1060
+ 1,
1061
+ 7
1062
+ ].includes(chartType)) {
1063
+ [sDate, lDate] = getScatterXDomainExtent(points);
1049
1064
  // Need to draw graph with given small and large date
1050
1065
  // (Which Involves customization of date axis tick values)
1051
1066
  // That may be Either from given graph data or from prop 'tickValues' date values.
@@ -1063,6 +1078,11 @@ export function tooltipOfAxislabels(axistooltipProps) {
1063
1078
  sDate = d3Min(points, (point)=>point.x);
1064
1079
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
1065
1080
  lDate = d3Max(points, (point)=>point.x);
1081
+ if (hasMarkersMode || chartType === 7) {
1082
+ const xPadding = getDomainPaddingForMarkers(sDate.getTime(), lDate.getTime());
1083
+ sDate = new Date(sDate.getTime() - xPadding.start);
1084
+ lDate = new Date(lDate.getTime() + xPadding.end);
1085
+ }
1066
1086
  }
1067
1087
  const rStartValue = margins.left;
1068
1088
  const rEndValue = width - margins.right;
@@ -1078,59 +1098,6 @@ export function tooltipOfAxislabels(axistooltipProps) {
1078
1098
  rEndValue
1079
1099
  };
1080
1100
  }
1081
- /**
1082
- * Calculates Domain and range values for Date X axis for scatter chart.
1083
- * @export
1084
- * @param {LineChartPoints[]} points
1085
- * @param {IMargins} margins
1086
- * @param {number} width
1087
- * @param {boolean} isRTL
1088
- * @param {Date[] | number[]} tickValues
1089
- * @returns {IDomainNRange}
1090
- */ export function domainRangeOfDateForScatterChart(points, margins, width, isRTL, tickValues = []) {
1091
- let sDate;
1092
- let lDate;
1093
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
1094
- sDate = d3Min(points, (point)=>{
1095
- return d3Min(point.data, (item)=>{
1096
- return item.x;
1097
- });
1098
- });
1099
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
1100
- lDate = d3Max(points, (point)=>{
1101
- return d3Max(point.data, (item)=>{
1102
- return item.x;
1103
- });
1104
- });
1105
- const xPadding = (lDate.getTime() - sDate.getTime()) * 0.1;
1106
- sDate = new Date(sDate.getTime() - xPadding);
1107
- lDate = new Date(lDate.getTime() + xPadding);
1108
- // Need to draw graph with given small and large date
1109
- // (Which Involves customization of date axis tick values)
1110
- // That may be Either from given graph data or from prop 'tickValues' date values.
1111
- // So, Finding smallest and largest dates
1112
- sDate = d3Min([
1113
- ...tickValues,
1114
- sDate
1115
- ]);
1116
- lDate = d3Max([
1117
- ...tickValues,
1118
- lDate
1119
- ]);
1120
- const rStartValue = margins.left;
1121
- const rEndValue = width - margins.right;
1122
- return isRTL ? {
1123
- dStartValue: lDate,
1124
- dEndValue: sDate,
1125
- rStartValue,
1126
- rEndValue
1127
- } : {
1128
- dStartValue: sDate,
1129
- dEndValue: lDate,
1130
- rStartValue,
1131
- rEndValue
1132
- };
1133
- }
1134
1101
  /**
1135
1102
  * Calculate domain and range values to the Vertical bar chart - For Numeric axis
1136
1103
  * @export
@@ -1162,12 +1129,14 @@ export function tooltipOfAxislabels(axistooltipProps) {
1162
1129
  * @export
1163
1130
  * @param {LineChartPoints[]} points
1164
1131
  * @returns {{ startValue: number; endValue: number }}
1165
- */ export function findNumericMinMaxOfY(points, yAxisType, useSecondaryYScale) {
1132
+ */ export function findNumericMinMaxOfY(points, yAxisType, useSecondaryYScale, scaleType) {
1166
1133
  const values = [];
1167
1134
  points.forEach((point)=>{
1168
1135
  if (!useSecondaryYScale === !point.useSecondaryYScale) {
1169
1136
  point.data.forEach((data)=>{
1170
- values.push(data.y);
1137
+ if (isValidDomainValue(data.y, scaleType)) {
1138
+ values.push(data.y);
1139
+ }
1171
1140
  });
1172
1141
  }
1173
1142
  });
@@ -1593,3 +1562,201 @@ export const createMeasurementSpan = (text, className, parentElement)=>{
1593
1562
  measurementSpan.textContent = `${text}`;
1594
1563
  return measurementSpan;
1595
1564
  };
1565
+ /**
1566
+ * Utility function to check if an array of points is scatterpolar
1567
+ * @param points - Array of chart points
1568
+ * @returns true if any point has lineOptions.mode as 'scatterpolar'
1569
+ */ export function isScatterPolarSeries(points) {
1570
+ return points.some(// eslint-disable-next-line @typescript-eslint/no-explicit-any
1571
+ (item)=>{
1572
+ var _item_lineOptions;
1573
+ return typeof ((_item_lineOptions = item.lineOptions) === null || _item_lineOptions === void 0 ? void 0 : _item_lineOptions.mode) === 'string' && item.lineOptions.mode === 'scatterpolar';
1574
+ });
1575
+ }
1576
+ /**
1577
+ * Utility function to check if an array of points contains mode as 'text' only
1578
+ * @param points - Array of chart points
1579
+ * @returns true if any point has lineOptions.mode as 'text'
1580
+ */ export function isTextMode(points) {
1581
+ return points.some(// eslint-disable-next-line @typescript-eslint/no-explicit-any
1582
+ (item)=>{
1583
+ var _item_lineOptions;
1584
+ return typeof ((_item_lineOptions = item.lineOptions) === null || _item_lineOptions === void 0 ? void 0 : _item_lineOptions.mode) === 'string' && item.lineOptions.mode === 'text';
1585
+ });
1586
+ }
1587
+ // TODO: Refactor to encapsulate the complete numeric scale creation logic here, including setting domain and range.
1588
+ const createNumericScale = (scaleType)=>{
1589
+ if (scaleType === 'log') {
1590
+ return d3ScaleLog();
1591
+ } else {
1592
+ return d3ScaleLinear();
1593
+ }
1594
+ };
1595
+ export const getDomainPaddingForMarkers = (minVal, maxVal, scaleType)=>{
1596
+ if (scaleType === 'log') {
1597
+ return {
1598
+ start: minVal * 0.5,
1599
+ end: maxVal
1600
+ };
1601
+ }
1602
+ const defaultPadding = (maxVal - minVal) * 0.1;
1603
+ return {
1604
+ start: defaultPadding,
1605
+ end: defaultPadding
1606
+ };
1607
+ };
1608
+ /**
1609
+ * Determines whether a value is valid for inclusion in the scale domain.
1610
+ * For log scales, ensures the value is strictly positive to prevent undefined scale behavior.
1611
+ */ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1612
+ export const isValidDomainValue = (value, scaleType)=>{
1613
+ return typeof value !== 'number' || scaleType !== 'log' || value > 0;
1614
+ };
1615
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1616
+ export const isPlottable = (x, y)=>{
1617
+ return !isInvalidValue(x) && !isInvalidValue(y);
1618
+ };
1619
+ export const getScatterXDomainExtent = (points, scaleType)=>{
1620
+ const isValidDataPointForScale = (item)=>isValidDomainValue(item.x, scaleType);
1621
+ const xMin = d3Min(points, (point)=>{
1622
+ return d3Min(point.data.filter(isValidDataPointForScale), (item)=>item.x);
1623
+ });
1624
+ const xMax = d3Max(points, (point)=>{
1625
+ return d3Max(point.data.filter(isValidDataPointForScale), (item)=>{
1626
+ return item.x;
1627
+ });
1628
+ });
1629
+ return [
1630
+ xMin,
1631
+ xMax
1632
+ ];
1633
+ };
1634
+ export const getRangeForScatterMarkerSize = ({ data, xScale, yScalePrimary, yScaleSecondary, useSecondaryYScale, xScaleType, yScaleType: primaryYScaleType, secondaryYScaleType })=>{
1635
+ // Note: This function is executed after the scale is created, so the actual padding can be
1636
+ // obtained by calculating the difference between the respective minimums or maximums of the
1637
+ // scale domain and the data. However, doing so often causes the marker size to scale up
1638
+ // unnecessarily when the scale uses a wider domain than required (due to the use of D3's nice
1639
+ // function or our own tick value calculations).
1640
+ // A better approach could be to treat the marker size as a fixed pixel value and adjust the
1641
+ // scale domain with sufficient padding to accommodate the maximum marker size—instead of doing
1642
+ // it the other way around (i.e., adjusting the scale domain first with padding and then scaling
1643
+ // the markers to fit inside the plot area).
1644
+ const [xMin, xMax] = getScatterXDomainExtent(data, xScaleType);
1645
+ const xPadding = getDomainPaddingForMarkers(+xMin, +xMax, xScaleType);
1646
+ const scaleXMin = xMin instanceof Date ? new Date(+xMin - xPadding.start) : xMin - xPadding.start;
1647
+ const scaleXMax = xMax instanceof Date ? new Date(+xMax + xPadding.end) : xMax + xPadding.end;
1648
+ const extraXPixels = Math.min(Math.abs(xScale(xMin) - xScale(scaleXMin)), Math.abs(xScale(scaleXMax) - xScale(xMax)));
1649
+ const yScaleType = useSecondaryYScale ? secondaryYScaleType : primaryYScaleType;
1650
+ const { startValue: yMin, endValue: yMax } = findNumericMinMaxOfY(data, undefined, useSecondaryYScale, yScaleType);
1651
+ const yPadding = getDomainPaddingForMarkers(yMin, yMax, yScaleType);
1652
+ const scaleYMin = yMin - yPadding.start;
1653
+ const scaleYMax = yMax + yPadding.end;
1654
+ const yScale = useSecondaryYScale ? yScaleSecondary : yScalePrimary;
1655
+ const extraYPixels = Math.min(Math.abs(yScale(scaleYMin) - yScale(yMin)), Math.abs(yScale(yMax) - yScale(scaleYMax)));
1656
+ return Math.min(extraXPixels, extraYPixels);
1657
+ };
1658
+ export const generateLinearTicks = (tick0, tickStep, scaleDomain)=>{
1659
+ const domainMin = d3Min(scaleDomain);
1660
+ const domainMax = d3Max(scaleDomain);
1661
+ const precision = Math.max(calculatePrecision(tick0), calculatePrecision(tickStep));
1662
+ const start = Math.ceil(precisionRound((domainMin - tick0) / tickStep, precision));
1663
+ const end = Math.floor(precisionRound((domainMax - tick0) / tickStep, precision));
1664
+ const ticks = [];
1665
+ for(let i = start; i <= end; i++){
1666
+ ticks.push(precisionRound(tick0 + i * tickStep, precision));
1667
+ }
1668
+ return ticks;
1669
+ };
1670
+ export const generateMonthlyTicks = (tick0, tickStepInMonths, scaleDomain, useUTC)=>{
1671
+ const domainMin = +d3Min(scaleDomain);
1672
+ const domainMax = +d3Max(scaleDomain);
1673
+ const getMonth = (d)=>useUTC ? d.getUTCMonth() : d.getMonth();
1674
+ const setMonth = (d, month)=>useUTC ? new Date(d.setUTCMonth(month)) : new Date(d.setMonth(month));
1675
+ // Find the earliest tick <= domainMin
1676
+ let start = 0;
1677
+ for(let firstTick = new Date(+tick0); +firstTick > domainMin;){
1678
+ firstTick = setMonth(firstTick, getMonth(firstTick) - tickStepInMonths);
1679
+ start -= tickStepInMonths;
1680
+ }
1681
+ const baseMonth = getMonth(tick0);
1682
+ const ticks = [];
1683
+ // Generate ticks forward until domainMax
1684
+ for(let i = start;; i += tickStepInMonths){
1685
+ let tickDate = setMonth(new Date(+tick0), baseMonth + i);
1686
+ // Handle month rollover (e.g., Jan 31 + 1 month → Mar 3 instead of Feb)
1687
+ if (getMonth(tickDate) !== ((baseMonth + i) % 12 + 12) % 12) {
1688
+ tickDate = useUTC ? new Date(tickDate.setUTCDate(0)) : new Date(tickDate.setDate(0));
1689
+ }
1690
+ if (+tickDate > domainMax) {
1691
+ break;
1692
+ }
1693
+ if (+tickDate >= domainMin) {
1694
+ ticks.push(tickDate);
1695
+ }
1696
+ }
1697
+ return ticks;
1698
+ };
1699
+ const generateNumericTicks = (scaleType, tickStep, tick0, scaleDomain)=>{
1700
+ const refTick = typeof tick0 === 'number' ? tick0 : 0;
1701
+ if (scaleType === 'log') {
1702
+ if (typeof tickStep === 'number' && tickStep > 0) {
1703
+ return generateLinearTicks(refTick, tickStep, scaleDomain.map((d)=>Math.log10(d))).map((t)=>Math.pow(10, t));
1704
+ }
1705
+ if (typeof tickStep === 'string') {
1706
+ const prefix = tickStep[0];
1707
+ const num = isNumber(tickStep.slice(1)) ? Number(tickStep.slice(1)) : 0;
1708
+ if (prefix === 'L' && num > 0) {
1709
+ return generateLinearTicks(refTick, num, scaleDomain);
1710
+ }
1711
+ }
1712
+ return;
1713
+ }
1714
+ if (typeof tickStep === 'number' && tickStep > 0) {
1715
+ return generateLinearTicks(refTick, tickStep, scaleDomain);
1716
+ }
1717
+ };
1718
+ const generateDateTicks = (tickStep, tick0, scaleDomain, useUTC)=>{
1719
+ const refTick = tick0 instanceof Date ? tick0 : new Date(DEFAULT_DATE_STRING);
1720
+ if (typeof tickStep === 'number' && tickStep > 0) {
1721
+ return generateLinearTicks(+refTick, tickStep, scaleDomain.map((d)=>+d)).map((t)=>new Date(t));
1722
+ }
1723
+ if (typeof tickStep === 'string') {
1724
+ const prefix = tickStep[0];
1725
+ const num = isNumber(tickStep.slice(1)) ? Number(tickStep.slice(1)) : 0;
1726
+ if (prefix === 'M' && num > 0 && num === Math.round(num)) {
1727
+ return generateMonthlyTicks(refTick, num, scaleDomain, useUTC);
1728
+ }
1729
+ }
1730
+ };
1731
+ /**
1732
+ * Calculates a number's precision based on the number of trailing
1733
+ * zeros if the number does not have a decimal indicated by a negative
1734
+ * precision. Otherwise, it calculates the number of digits after
1735
+ * the decimal point indicated by a positive precision.
1736
+ * @param value - the value to determine the precision of
1737
+ */ export function calculatePrecision(value) {
1738
+ /**
1739
+ * Group 1:
1740
+ * [1-9]([0]+$) matches trailing zeros
1741
+ * Group 2:
1742
+ * \.([0-9]*) matches all digits after a decimal point.
1743
+ */ const groups = /[1-9]([0]+$)|\.([0-9]*)/.exec(String(value));
1744
+ if (!groups) {
1745
+ return 0;
1746
+ }
1747
+ if (groups[1]) {
1748
+ return -groups[1].length;
1749
+ }
1750
+ if (groups[2]) {
1751
+ return groups[2].length;
1752
+ }
1753
+ return 0;
1754
+ }
1755
+ /**
1756
+ * Rounds a number to a certain level of precision. Accepts negative precision.
1757
+ * @param value - The value that is being rounded.
1758
+ * @param precision - The number of decimal places to round the number to
1759
+ */ export function precisionRound(value, precision, base = 10) {
1760
+ const exp = Math.pow(base, precision);
1761
+ return Math.round(value * exp) / exp;
1762
+ }