@kubit-ui-web/react-charts 1.4.0 → 1.5.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 (106) hide show
  1. package/dist/cjs/charts/barChart/fragments/barChartPath.d.ts.map +1 -1
  2. package/dist/cjs/charts/barChart/fragments/barChartPath.js +12 -7
  3. package/dist/cjs/charts/barChart/fragments/barChartSeparator.d.ts.map +1 -1
  4. package/dist/cjs/charts/barChart/fragments/barChartSeparator.js +20 -8
  5. package/dist/cjs/charts/constants/chartDefaults.d.ts +20 -0
  6. package/dist/cjs/charts/constants/chartDefaults.d.ts.map +1 -1
  7. package/dist/cjs/charts/constants/chartDefaults.js +20 -0
  8. package/dist/cjs/charts/lineChart/fragments/lineChartPath.d.ts.map +1 -1
  9. package/dist/cjs/charts/lineChart/fragments/lineChartPath.js +23 -12
  10. package/dist/cjs/charts/lineChart/fragments/lineChartProjection.d.ts.map +1 -1
  11. package/dist/cjs/charts/lineChart/fragments/lineChartProjection.js +10 -7
  12. package/dist/cjs/charts/lineChart/fragments/lineChartSeparator.d.ts.map +1 -1
  13. package/dist/cjs/charts/lineChart/fragments/lineChartSeparator.js +20 -8
  14. package/dist/cjs/charts/pieChart/context/buildPieContextValue.d.ts +3 -1
  15. package/dist/cjs/charts/pieChart/context/buildPieContextValue.d.ts.map +1 -1
  16. package/dist/cjs/charts/pieChart/context/buildPieContextValue.js +15 -3
  17. package/dist/cjs/charts/pieChart/fragments/pieChartPath.d.ts.map +1 -1
  18. package/dist/cjs/charts/pieChart/fragments/pieChartPath.js +31 -3
  19. package/dist/cjs/charts/pieChart/fragments/pieChartSegment.d.ts.map +1 -1
  20. package/dist/cjs/charts/pieChart/fragments/pieChartSegment.js +58 -1
  21. package/dist/cjs/charts/pieChart/pieChart.type.d.ts +7 -0
  22. package/dist/cjs/charts/pieChart/pieChart.type.d.ts.map +1 -1
  23. package/dist/cjs/charts/pieChart/pieChartStructure.d.ts.map +1 -1
  24. package/dist/cjs/charts/pieChart/pieChartStructure.js +12 -2
  25. package/dist/cjs/types/errors.type.d.ts +3 -0
  26. package/dist/cjs/types/errors.type.d.ts.map +1 -1
  27. package/dist/cjs/types/errors.type.js +4 -0
  28. package/dist/cjs/utils/buildErrors/buildErrors.d.ts +11 -0
  29. package/dist/cjs/utils/buildErrors/buildErrors.d.ts.map +1 -1
  30. package/dist/cjs/utils/buildErrors/buildErrors.js +5 -0
  31. package/dist/cjs/utils/buildErrors/charts/buildPieChartErrors.d.ts +37 -0
  32. package/dist/cjs/utils/buildErrors/charts/buildPieChartErrors.d.ts.map +1 -0
  33. package/dist/cjs/utils/buildErrors/charts/buildPieChartErrors.js +36 -0
  34. package/dist/cjs/utils/buildErrors/constants/errorMessages/pieChartErrorMessages.d.ts +13 -0
  35. package/dist/cjs/utils/buildErrors/constants/errorMessages/pieChartErrorMessages.d.ts.map +1 -0
  36. package/dist/cjs/utils/buildErrors/constants/errorMessages/pieChartErrorMessages.js +20 -0
  37. package/dist/cjs/utils/buildErrors/constants/errors/pieChartErrors.d.ts +14 -0
  38. package/dist/cjs/utils/buildErrors/constants/errors/pieChartErrors.d.ts.map +1 -0
  39. package/dist/cjs/utils/buildErrors/constants/errors/pieChartErrors.js +25 -0
  40. package/dist/esm/charts/barChart/fragments/barChartPath.d.ts.map +1 -1
  41. package/dist/esm/charts/barChart/fragments/barChartPath.js +12 -7
  42. package/dist/esm/charts/barChart/fragments/barChartSeparator.d.ts.map +1 -1
  43. package/dist/esm/charts/barChart/fragments/barChartSeparator.js +20 -8
  44. package/dist/esm/charts/constants/chartDefaults.d.ts +20 -0
  45. package/dist/esm/charts/constants/chartDefaults.d.ts.map +1 -1
  46. package/dist/esm/charts/constants/chartDefaults.js +20 -0
  47. package/dist/esm/charts/lineChart/fragments/lineChartPath.d.ts.map +1 -1
  48. package/dist/esm/charts/lineChart/fragments/lineChartPath.js +23 -12
  49. package/dist/esm/charts/lineChart/fragments/lineChartProjection.d.ts.map +1 -1
  50. package/dist/esm/charts/lineChart/fragments/lineChartProjection.js +10 -7
  51. package/dist/esm/charts/lineChart/fragments/lineChartSeparator.d.ts.map +1 -1
  52. package/dist/esm/charts/lineChart/fragments/lineChartSeparator.js +20 -8
  53. package/dist/esm/charts/pieChart/context/buildPieContextValue.d.ts +3 -1
  54. package/dist/esm/charts/pieChart/context/buildPieContextValue.d.ts.map +1 -1
  55. package/dist/esm/charts/pieChart/context/buildPieContextValue.js +15 -3
  56. package/dist/esm/charts/pieChart/fragments/pieChartPath.d.ts.map +1 -1
  57. package/dist/esm/charts/pieChart/fragments/pieChartPath.js +31 -3
  58. package/dist/esm/charts/pieChart/fragments/pieChartSegment.d.ts.map +1 -1
  59. package/dist/esm/charts/pieChart/fragments/pieChartSegment.js +58 -1
  60. package/dist/esm/charts/pieChart/pieChart.type.d.ts +7 -0
  61. package/dist/esm/charts/pieChart/pieChart.type.d.ts.map +1 -1
  62. package/dist/esm/charts/pieChart/pieChartStructure.d.ts.map +1 -1
  63. package/dist/esm/charts/pieChart/pieChartStructure.js +12 -2
  64. package/dist/esm/types/errors.type.d.ts +3 -0
  65. package/dist/esm/types/errors.type.d.ts.map +1 -1
  66. package/dist/esm/types/errors.type.js +4 -0
  67. package/dist/esm/utils/buildErrors/buildErrors.d.ts +11 -0
  68. package/dist/esm/utils/buildErrors/buildErrors.d.ts.map +1 -1
  69. package/dist/esm/utils/buildErrors/buildErrors.js +5 -0
  70. package/dist/esm/utils/buildErrors/charts/buildPieChartErrors.d.ts +37 -0
  71. package/dist/esm/utils/buildErrors/charts/buildPieChartErrors.d.ts.map +1 -0
  72. package/dist/esm/utils/buildErrors/charts/buildPieChartErrors.js +36 -0
  73. package/dist/esm/utils/buildErrors/constants/errorMessages/pieChartErrorMessages.d.ts +13 -0
  74. package/dist/esm/utils/buildErrors/constants/errorMessages/pieChartErrorMessages.d.ts.map +1 -0
  75. package/dist/esm/utils/buildErrors/constants/errorMessages/pieChartErrorMessages.js +20 -0
  76. package/dist/esm/utils/buildErrors/constants/errors/pieChartErrors.d.ts +14 -0
  77. package/dist/esm/utils/buildErrors/constants/errors/pieChartErrors.d.ts.map +1 -0
  78. package/dist/esm/utils/buildErrors/constants/errors/pieChartErrors.js +25 -0
  79. package/dist/kubit-ui-web-react-charts.cjs.js +1 -1
  80. package/dist/kubit-ui-web-react-charts.es.js +1 -1
  81. package/dist/kubit-ui-web-react-charts.umd.js +1 -1
  82. package/dist/types/charts/barChart/fragments/barChartPath.d.ts.map +1 -1
  83. package/dist/types/charts/barChart/fragments/barChartSeparator.d.ts.map +1 -1
  84. package/dist/types/charts/constants/chartDefaults.d.ts +20 -0
  85. package/dist/types/charts/constants/chartDefaults.d.ts.map +1 -1
  86. package/dist/types/charts/lineChart/fragments/lineChartPath.d.ts.map +1 -1
  87. package/dist/types/charts/lineChart/fragments/lineChartProjection.d.ts.map +1 -1
  88. package/dist/types/charts/lineChart/fragments/lineChartSeparator.d.ts.map +1 -1
  89. package/dist/types/charts/pieChart/context/buildPieContextValue.d.ts +3 -1
  90. package/dist/types/charts/pieChart/context/buildPieContextValue.d.ts.map +1 -1
  91. package/dist/types/charts/pieChart/fragments/pieChartPath.d.ts.map +1 -1
  92. package/dist/types/charts/pieChart/fragments/pieChartSegment.d.ts.map +1 -1
  93. package/dist/types/charts/pieChart/pieChart.type.d.ts +7 -0
  94. package/dist/types/charts/pieChart/pieChart.type.d.ts.map +1 -1
  95. package/dist/types/charts/pieChart/pieChartStructure.d.ts.map +1 -1
  96. package/dist/types/types/errors.type.d.ts +3 -0
  97. package/dist/types/types/errors.type.d.ts.map +1 -1
  98. package/dist/types/utils/buildErrors/buildErrors.d.ts +11 -0
  99. package/dist/types/utils/buildErrors/buildErrors.d.ts.map +1 -1
  100. package/dist/types/utils/buildErrors/charts/buildPieChartErrors.d.ts +37 -0
  101. package/dist/types/utils/buildErrors/charts/buildPieChartErrors.d.ts.map +1 -0
  102. package/dist/types/utils/buildErrors/constants/errorMessages/pieChartErrorMessages.d.ts +13 -0
  103. package/dist/types/utils/buildErrors/constants/errorMessages/pieChartErrorMessages.d.ts.map +1 -0
  104. package/dist/types/utils/buildErrors/constants/errors/pieChartErrors.d.ts +14 -0
  105. package/dist/types/utils/buildErrors/constants/errors/pieChartErrors.d.ts.map +1 -0
  106. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"barChartPath.d.ts","sourceRoot":"","sources":["../../../../../src/charts/barChart/fragments/barChartPath.tsx"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAG1D;;;;;GAKG;AAEH,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,CA8EpD,CAAC"}
1
+ {"version":3,"file":"barChartPath.d.ts","sourceRoot":"","sources":["../../../../../src/charts/barChart/fragments/barChartPath.tsx"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAG1D;;;;;GAKG;AAEH,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,CAkFpD,CAAC"}
@@ -22,31 +22,36 @@ export const BarChartPath = ({ barConfig, dataIdx, dataKey, order, ...props }) =
22
22
  const dataItem = context.data[dataIdx];
23
23
  const xData = dataItem?.[xKey];
24
24
  const yData = dataItem?.[yKey];
25
+ // Extract values for stable dependencies
26
+ const firstDataItem = context.data[0];
27
+ const hasDataKey = firstDataItem
28
+ ? Object.prototype.hasOwnProperty.call(firstDataItem, dataKey)
29
+ : false;
30
+ const hasData = context.data.length > 0;
31
+ const numericYData = Number(yData);
25
32
  // Path error validations - only validates the data for this specific bar
26
33
  useEffect(() => {
27
34
  // Validate dataKey exists in dataset
28
- if (context.data.length > 0 &&
29
- !Object.prototype.hasOwnProperty.call(context.data[0], dataKey)) {
35
+ if (hasData && !hasDataKey) {
30
36
  addError?.('BAR_CHART_PATH_ERROR', {
31
37
  error: buildDataKeyNotFoundError(dataKey),
32
38
  });
33
39
  return; // Stop validation if dataKey doesn't exist
34
40
  }
35
41
  // Validate bar value is numeric
36
- const numericValue = Number(yData);
37
- if (isNaN(numericValue)) {
42
+ if (isNaN(numericYData)) {
38
43
  addError?.('BAR_CHART_PATH_ERROR', {
39
44
  error: buildBarValueError(yData, dataKey),
40
45
  });
41
46
  return;
42
47
  }
43
48
  // Validate negative values
44
- if (numericValue < 0) {
49
+ if (numericYData < 0) {
45
50
  addError?.('BAR_CHART_PATH_ERROR', {
46
- error: buildBarNegativeValueError(numericValue, dataKey),
51
+ error: buildBarNegativeValueError(numericYData, dataKey),
47
52
  });
48
53
  }
49
- }, [addError, context.data, dataKey, yData]);
54
+ }, [dataKey, hasData, hasDataKey, numericYData, yData]);
50
55
  const xPoint = getPoints(xTickValues, [String(xData)], true)[0];
51
56
  const yPoint = getPoints(yTickValues, [String(yData)])[0];
52
57
  const points = isVertical
@@ -1 +1 @@
1
- {"version":3,"file":"barChartSeparator.d.ts","sourceRoot":"","sources":["../../../../../src/charts/barChart/fragments/barChartSeparator.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,EAA4C,MAAM,OAAO,CAAC;AAY1E,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAG/D,eAAO,MAAM,iBAAiB,EAAE,EAAE,CAAC,sBAAsB,CA0FxD,CAAC"}
1
+ {"version":3,"file":"barChartSeparator.d.ts","sourceRoot":"","sources":["../../../../../src/charts/barChart/fragments/barChartSeparator.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,EAA4C,MAAM,OAAO,CAAC;AAY1E,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAG/D,eAAO,MAAM,iBAAiB,EAAE,EAAE,CAAC,sBAAsB,CA0GxD,CAAC"}
@@ -5,13 +5,26 @@ import { getPoints } from '../../../utils/getPoints/getPoints';
5
5
  import { BarChartContext } from '../context/barChartContext';
6
6
  export const BarChartSeparator = ({ areaSeparator, dataTestId, rightSeparator, topSeparator, xBreakAxis, yBreakAxis, }) => {
7
7
  const { addError, crossXAxis, crossYAxis, xAxisCoordinates, yAxisCoordinates } = useContext(BarChartContext);
8
+ // Extract tick values for stable dependencies
9
+ const xTickValues = xAxisCoordinates.tickValues;
10
+ const yTickValues = yAxisCoordinates.tickValues;
11
+ // Pre-calculate numeric values for dependencies
12
+ const xBreakNumeric = xBreakAxis !== undefined
13
+ ? typeof xBreakAxis === 'string'
14
+ ? parseFloat(xBreakAxis)
15
+ : xBreakAxis
16
+ : undefined;
17
+ const yBreakNumeric = yBreakAxis !== undefined
18
+ ? typeof yBreakAxis === 'string'
19
+ ? parseFloat(yBreakAxis)
20
+ : yBreakAxis
21
+ : undefined;
8
22
  // Separator error validations
9
23
  useEffect(() => {
10
24
  // xBreakAxis validation
11
25
  if (xBreakAxis !== undefined) {
12
- const xValues = xAxisCoordinates.tickValues.map(tick => tick.value);
13
- const xBreakNumeric = typeof xBreakAxis === 'string' ? parseFloat(xBreakAxis) : xBreakAxis;
14
- if (isNaN(xBreakNumeric)) {
26
+ const xValues = xTickValues.map(tick => tick.value);
27
+ if (xBreakNumeric === undefined || isNaN(xBreakNumeric)) {
15
28
  addError?.('BAR_CHART_SEPARATOR_ERROR', {
16
29
  error: buildSeparatorXBreakAxisError(xBreakAxis),
17
30
  });
@@ -28,9 +41,8 @@ export const BarChartSeparator = ({ areaSeparator, dataTestId, rightSeparator, t
28
41
  }
29
42
  // yBreakAxis validation
30
43
  if (yBreakAxis !== undefined) {
31
- const yValues = yAxisCoordinates.tickValues.map(tick => tick.value);
32
- const yBreakNumeric = typeof yBreakAxis === 'string' ? parseFloat(yBreakAxis) : yBreakAxis;
33
- if (isNaN(yBreakNumeric)) {
44
+ const yValues = yTickValues.map(tick => tick.value);
45
+ if (yBreakNumeric === undefined || isNaN(yBreakNumeric)) {
34
46
  addError?.('BAR_CHART_SEPARATOR_ERROR', {
35
47
  error: buildSeparatorYBreakAxisError(yBreakAxis),
36
48
  });
@@ -45,7 +57,7 @@ export const BarChartSeparator = ({ areaSeparator, dataTestId, rightSeparator, t
45
57
  }
46
58
  }
47
59
  }
48
- }, [xBreakAxis, yBreakAxis, xAxisCoordinates.tickValues, yAxisCoordinates.tickValues, addError]);
60
+ }, [xBreakAxis, xBreakNumeric, xTickValues, yBreakAxis, yBreakNumeric, yTickValues]);
49
61
  if (!topSeparator && !rightSeparator && !areaSeparator) {
50
62
  return _jsx(_Fragment, {});
51
63
  }
@@ -64,7 +76,7 @@ export const BarChartSeparator = ({ areaSeparator, dataTestId, rightSeparator, t
64
76
  error: buildError(BuildError.LINE_CHART_SEPARATOR_INVALID_COORDINATES),
65
77
  });
66
78
  }
67
- }, [xStart, xEnd, yStart, yEnd, addError]);
79
+ }, [xStart, xEnd, yStart, yEnd]);
68
80
  const squarePath = `M${xStart} ${yStart} H ${xEnd} V ${yEnd} H ${xStart} Z`;
69
81
  const lineTop = `M${xStart} ${yEnd} H ${xEnd}`;
70
82
  const lineRight = `M${xEnd} ${yStart} V ${yEnd}`;
@@ -74,4 +74,24 @@ export declare const LINE_CHART_FALLBACK_DATA: {
74
74
  /** Second Y value for line chart fallback data */
75
75
  readonly FALLBACK_Y_SECOND: 1;
76
76
  };
77
+ /**
78
+ * Pie Chart specific default configuration values
79
+ */
80
+ export declare const PIE_CHART_DEFAULTS: {
81
+ /** Default radius percentage when not specified */
82
+ readonly DEFAULT_RADIUS_PERCENTAGE: 50;
83
+ /** Minimum number of segments required for a valid pie chart */
84
+ readonly MIN_SEGMENTS: 1;
85
+ };
86
+ /**
87
+ * Pie Chart specific fallback data points used when pie chart data is invalid or empty
88
+ */
89
+ export declare const PIE_CHART_FALLBACK_DATA: {
90
+ /** Generic data key for fallback data */
91
+ readonly FALLBACK_DATA_KEY: "fallbackSegments";
92
+ /** Default segment name for fallback data */
93
+ readonly FALLBACK_SEGMENT_NAME: "fallback";
94
+ /** Default segment value for fallback data */
95
+ readonly FALLBACK_SEGMENT_VALUE: 100;
96
+ };
77
97
  //# sourceMappingURL=chartDefaults.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"chartDefaults.d.ts","sourceRoot":"","sources":["../../../../src/charts/constants/chartDefaults.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;GAEG;AACH,eAAO,MAAM,qBAAqB;IAChC,4DAA4D;;IAE5D,0DAA0D;;CAElD,CAAC;AAEX;;GAEG;AACH,eAAO,MAAM,eAAe;IAC1B,8DAA8D;;IAE9D,+DAA+D;;CAEvD,CAAC;AAEX;;GAEG;AACH,eAAO,MAAM,sBAAsB;IACjC,yDAAyD;;CAEjD,CAAC;AAEX;;GAEG;AACH,eAAO,MAAM,mBAAmB;IAC9B,2DAA2D;;CAEnD,CAAC;AAEX;;GAEG;AACH,eAAO,MAAM,oBAAoB;IAC/B,8DAA8D;;IAE9D,+DAA+D;;CAEvD,CAAC;AAEX;;GAEG;AACH,eAAO,MAAM,kBAAkB;IAC7B,wDAAwD;;CAEhD,CAAC;AAEX;;GAEG;AACH,eAAO,MAAM,uBAAuB;IAClC,+CAA+C;;IAE/C,qEAAqE;;CAE7D,CAAC;AAEX;;GAEG;AACH,eAAO,MAAM,wBAAwB;IACnC,iDAAiD;;IAEjD,kDAAkD;;IAElD,iDAAiD;;IAEjD,kDAAkD;;CAE1C,CAAC"}
1
+ {"version":3,"file":"chartDefaults.d.ts","sourceRoot":"","sources":["../../../../src/charts/constants/chartDefaults.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;GAEG;AACH,eAAO,MAAM,qBAAqB;IAChC,4DAA4D;;IAE5D,0DAA0D;;CAElD,CAAC;AAEX;;GAEG;AACH,eAAO,MAAM,eAAe;IAC1B,8DAA8D;;IAE9D,+DAA+D;;CAEvD,CAAC;AAEX;;GAEG;AACH,eAAO,MAAM,sBAAsB;IACjC,yDAAyD;;CAEjD,CAAC;AAEX;;GAEG;AACH,eAAO,MAAM,mBAAmB;IAC9B,2DAA2D;;CAEnD,CAAC;AAEX;;GAEG;AACH,eAAO,MAAM,oBAAoB;IAC/B,8DAA8D;;IAE9D,+DAA+D;;CAEvD,CAAC;AAEX;;GAEG;AACH,eAAO,MAAM,kBAAkB;IAC7B,wDAAwD;;CAEhD,CAAC;AAEX;;GAEG;AACH,eAAO,MAAM,uBAAuB;IAClC,+CAA+C;;IAE/C,qEAAqE;;CAE7D,CAAC;AAEX;;GAEG;AACH,eAAO,MAAM,wBAAwB;IACnC,iDAAiD;;IAEjD,kDAAkD;;IAElD,iDAAiD;;IAEjD,kDAAkD;;CAE1C,CAAC;AAEX;;GAEG;AACH,eAAO,MAAM,kBAAkB;IAC7B,mDAAmD;;IAEnD,gEAAgE;;CAExD,CAAC;AAEX;;GAEG;AACH,eAAO,MAAM,uBAAuB;IAClC,yCAAyC;;IAEzC,6CAA6C;;IAE7C,8CAA8C;;CAEtC,CAAC"}
@@ -74,3 +74,23 @@ export const LINE_CHART_FALLBACK_DATA = {
74
74
  /** Second Y value for line chart fallback data */
75
75
  FALLBACK_Y_SECOND: 1,
76
76
  };
77
+ /**
78
+ * Pie Chart specific default configuration values
79
+ */
80
+ export const PIE_CHART_DEFAULTS = {
81
+ /** Default radius percentage when not specified */
82
+ DEFAULT_RADIUS_PERCENTAGE: 50,
83
+ /** Minimum number of segments required for a valid pie chart */
84
+ MIN_SEGMENTS: 1,
85
+ };
86
+ /**
87
+ * Pie Chart specific fallback data points used when pie chart data is invalid or empty
88
+ */
89
+ export const PIE_CHART_FALLBACK_DATA = {
90
+ /** Generic data key for fallback data */
91
+ FALLBACK_DATA_KEY: 'fallbackSegments',
92
+ /** Default segment name for fallback data */
93
+ FALLBACK_SEGMENT_NAME: 'fallback',
94
+ /** Default segment value for fallback data */
95
+ FALLBACK_SEGMENT_VALUE: 100,
96
+ };
@@ -1 +1 @@
1
- {"version":3,"file":"lineChartPath.d.ts","sourceRoot":"","sources":["../../../../../src/charts/lineChart/fragments/lineChartPath.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,EAAoD,MAAM,OAAO,CAAC;AAWlF,OAAO,KAAK,EAAc,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAIxE,OAAO,qBAAqB,CAAC;AAO7B,eAAO,MAAM,aAAa,EAAE,EAAE,CAAC,kBAAkB,CAwLhD,CAAC"}
1
+ {"version":3,"file":"lineChartPath.d.ts","sourceRoot":"","sources":["../../../../../src/charts/lineChart/fragments/lineChartPath.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,EAAoD,MAAM,OAAO,CAAC;AAWlF,OAAO,KAAK,EAAc,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAIxE,OAAO,qBAAqB,CAAC;AAO7B,eAAO,MAAM,aAAa,EAAE,EAAE,CAAC,kBAAkB,CAoMhD,CAAC"}
@@ -19,38 +19,45 @@ const getAxisData = (data, key) => {
19
19
  export const LineChartPath = ({ ariaLabel, closestClick, curved, getNodeFocusInfo, getNodesCoords, indicatorConfig, lineProjection, onClick, ...props }) => {
20
20
  // recovery the context values
21
21
  const { addError, xAxisCoordinates, yAxisCoordinates, ...context } = useContext(LineChartContext);
22
+ // Extract stable values for dependencies
23
+ const dataKey = props.dataKey;
24
+ const hasData = context.data.length > 0;
25
+ const firstDataItem = context.data[0];
26
+ const hasDataKey = firstDataItem
27
+ ? Object.prototype.hasOwnProperty.call(firstDataItem, dataKey)
28
+ : false;
29
+ const dataLength = context.data.length;
22
30
  // Path error validations
23
31
  useEffect(() => {
24
32
  // Invalid dataKey validation
25
- if (!props.dataKey || typeof props.dataKey !== 'string') {
33
+ if (!dataKey || typeof dataKey !== 'string') {
26
34
  addError?.('LINE_CHART_PATH_ERROR', {
27
35
  error: buildError(BuildError.LINE_CHART_PATH_INVALID_DATAKEY),
28
36
  });
29
37
  return;
30
38
  }
31
39
  // Check if dataKey exists in dataset
32
- if (context.data.length > 0 &&
33
- !Object.prototype.hasOwnProperty.call(context.data[0], props.dataKey)) {
40
+ if (hasData && !hasDataKey) {
34
41
  addError?.('LINE_CHART_PATH_ERROR', {
35
- error: buildDataKeyNotFoundError(props.dataKey),
42
+ error: buildDataKeyNotFoundError(dataKey),
36
43
  });
37
44
  return;
38
45
  }
39
46
  // Curved path calculation errors
40
- if (curved && context.data.length < 2) {
47
+ if (curved && dataLength < 2) {
41
48
  addError?.('LINE_CHART_PATH_ERROR', {
42
49
  error: buildError(BuildError.LINE_CHART_PATH_INSUFFICIENT_POINTS),
43
50
  });
44
51
  return;
45
52
  }
46
53
  // Path rendering errors - validate coordinates
47
- const yData = getAxisData(context.data, props.dataKey);
54
+ const yData = getAxisData(context.data, dataKey);
48
55
  if (yData.length > 0 && yData.every(val => val === null || val === undefined)) {
49
56
  addError?.('LINE_CHART_PATH_ERROR', {
50
57
  error: buildError(BuildError.LINE_CHART_PATH_ALL_VALUES_NULL),
51
58
  });
52
59
  }
53
- }, [props.dataKey, curved, context.data, addError]);
60
+ }, [addError, curved, dataKey, dataLength, hasData, hasDataKey, context.data]);
54
61
  // the node indicator logic
55
62
  const { indicatorRef, pathRef } = useIndicator(context.xCursor, !!indicatorConfig);
56
63
  const showIndicator = !!indicatorConfig && context.xCursor !== -Infinity;
@@ -58,14 +65,18 @@ export const LineChartPath = ({ ariaLabel, closestClick, curved, getNodeFocusInf
58
65
  const pressedRef = useRef(null);
59
66
  // the projection line logic
60
67
  const { autoClick, lineIndicator, ...nodeIndicatorConfig } = indicatorConfig || {};
61
- // line indicator <Y> coordinates
62
- const y1 = context.extraSpaceTopY;
63
- const y2 = Number(context.canvasHeight) - context.extraSpaceBottomY;
68
+ // Calculate line indicator boundaries using pre-calculated axis coordinates
69
+ // Y-axis: spans from top to bottom of chart area
70
+ const { y1, y2 } = yAxisCoordinates.coordinates;
71
+ // X-axis: constrain to path area to prevent overflow into axis labels
72
+ // The indicator should only render within the data visualization area
73
+ const { x1: pathAreaMinX, x2: pathAreaMaxX } = xAxisCoordinates.coordinates;
74
+ const isCursorWithinPathArea = context.xCursor >= pathAreaMinX && context.xCursor <= pathAreaMaxX;
64
75
  // the path
65
76
  const { tickValues: xTickValues } = xAxisCoordinates;
66
77
  const { tickValues: yTickValues } = yAxisCoordinates;
67
78
  const xData = getAxisData(context.data, context.xKey);
68
- const yData = getAxisData(context.data, props.dataKey);
79
+ const yData = getAxisData(context.data, dataKey);
69
80
  const xPoints = getPoints(xTickValues, xData, true);
70
81
  const yPoints = getPoints(yTickValues, yData);
71
82
  const points = xPoints.map((x, i) => [x, yPoints[i]]);
@@ -134,5 +145,5 @@ export const LineChartPath = ({ ariaLabel, closestClick, curved, getNodeFocusInf
134
145
  // Handle deprecated ariaLabel - give precedence to ariaLabel for backward compatibility
135
146
  ...(ariaLabel && { 'aria-label': ariaLabel }),
136
147
  };
137
- return (_jsxs(_Fragment, { children: [_jsx(Path, { ref: innerRefs, d: dataOnlyLine, dFill: dataFill, dataTestId: `${context.dataTestId}path`, dataValue: context.data, points: points, xKey: context.xKey, onClick: handleClick, ...mergedProps }), lineProjection && (_jsx(LineChartProjection, { curved: curved, dataKey: props.dataKey, lineProjection: lineProjection, points: points, svgHeight: Number(context.canvasHeight) - context.extraSpaceBottomY })), showIndicator && (_jsxs(_Fragment, { children: [!!lineIndicator && (_jsx(Line, { ...lineIndicator, className: "pointer-events-none", x1: context.xCursor, x2: context.xCursor, y1: y1, y2: y2 })), _jsx("g", { ref: indicatorRef, className: "pointer-events-none", children: _jsx(Node, { ...nodeIndicatorConfig }) })] }))] }));
148
+ return (_jsxs(_Fragment, { children: [_jsx(Path, { ref: innerRefs, d: dataOnlyLine, dFill: dataFill, dataTestId: `${context.dataTestId}path`, dataValue: context.data, points: points, xKey: context.xKey, onClick: handleClick, ...mergedProps }), lineProjection && (_jsx(LineChartProjection, { curved: curved, dataKey: props.dataKey, lineProjection: lineProjection, points: points, svgHeight: Number(context.canvasHeight) - context.extraSpaceBottomY })), showIndicator && (_jsxs(_Fragment, { children: [!!lineIndicator && isCursorWithinPathArea && (_jsx(Line, { ...lineIndicator, className: "pointer-events-none", x1: context.xCursor, x2: context.xCursor, y1: y1, y2: y2 })), _jsx("g", { ref: indicatorRef, className: "pointer-events-none", children: _jsx(Node, { ...nodeIndicatorConfig }) })] }))] }));
138
149
  };
@@ -1 +1 @@
1
- {"version":3,"file":"lineChartProjection.d.ts","sourceRoot":"","sources":["../../../../../src/charts/lineChart/fragments/lineChartProjection.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,EAAyB,MAAM,OAAO,CAAC;AASvD,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,mBAAmB,CAAC;AAElE,OAAO,qBAAqB,CAAC;AAE7B,eAAO,MAAM,mBAAmB,EAAE,EAAE,CAAC,wBAAwB,CA4E5D,CAAC"}
1
+ {"version":3,"file":"lineChartProjection.d.ts","sourceRoot":"","sources":["../../../../../src/charts/lineChart/fragments/lineChartProjection.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,EAAyB,MAAM,OAAO,CAAC;AASvD,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,mBAAmB,CAAC;AAElE,OAAO,qBAAqB,CAAC;AAE7B,eAAO,MAAM,mBAAmB,EAAE,EAAE,CAAC,wBAAwB,CA8E5D,CAAC"}
@@ -11,21 +11,25 @@ export const LineChartProjection = ({ curved, lineProjection, points, svgHeight,
11
11
  const { xProjection: xDw, yProjection: yDw, ...lowerProps } = lower || {};
12
12
  const upperProjection = xUp || yUp ? { x: xUp, y: yUp } : undefined;
13
13
  const lowerProjection = xDw || yDw ? { x: xDw, y: yDw } : undefined;
14
+ // Extract values for stable dependencies
15
+ const upperY = upperProjection?.y;
16
+ const lowerY = lowerProjection?.y;
17
+ const upperX = upperProjection?.x;
18
+ const lowerX = lowerProjection?.x;
14
19
  // Projection error validations
15
20
  useEffect(() => {
16
21
  // Invalid projection bounds - upper/lower overlap
17
22
  if (upperProjection && lowerProjection) {
18
- const upperY = upperProjection.y || 0;
19
- const lowerY = lowerProjection.y || 0;
20
- if (upperY >= lowerY) {
23
+ const upperYVal = upperY || 0;
24
+ const lowerYVal = lowerY || 0;
25
+ if (upperYVal >= lowerYVal) {
21
26
  addError?.('LINE_CHART_PROJECTION_ERROR', {
22
- error: buildProjectionBoundsError(upperY, lowerY),
27
+ error: buildProjectionBoundsError(upperYVal, lowerYVal),
23
28
  });
24
29
  }
25
30
  }
26
31
  // Projection coordinates outside chart area
27
32
  if (upperProjection) {
28
- const { x: upperX, y: upperY } = upperProjection;
29
33
  if (upperX !== undefined && (upperX < 0 || upperX > 100)) {
30
34
  addError?.('LINE_CHART_PROJECTION_ERROR', {
31
35
  error: buildProjectionXOutOfRangeError(upperX, true),
@@ -38,7 +42,6 @@ export const LineChartProjection = ({ curved, lineProjection, points, svgHeight,
38
42
  }
39
43
  }
40
44
  if (lowerProjection) {
41
- const { x: lowerX, y: lowerY } = lowerProjection;
42
45
  if (lowerX !== undefined && (lowerX < 0 || lowerX > 100)) {
43
46
  addError?.('LINE_CHART_PROJECTION_ERROR', {
44
47
  error: buildProjectionXOutOfRangeError(lowerX, false),
@@ -50,7 +53,7 @@ export const LineChartProjection = ({ curved, lineProjection, points, svgHeight,
50
53
  });
51
54
  }
52
55
  }
53
- }, [upperProjection, lowerProjection, svgHeight, addError]);
56
+ }, [lowerProjection, lowerX, lowerY, svgHeight, upperProjection, upperX, upperY]);
54
57
  const { downPath, shapePath, upPath } = getProjection({
55
58
  curved,
56
59
  lowerProjection,
@@ -1 +1 @@
1
- {"version":3,"file":"lineChartSeparator.d.ts","sourceRoot":"","sources":["../../../../../src/charts/lineChart/fragments/lineChartSeparator.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,EAA4C,MAAM,OAAO,CAAC;AAa1E,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AAEjE,eAAO,MAAM,kBAAkB,EAAE,EAAE,CAAC,uBAAuB,CA0F1D,CAAC"}
1
+ {"version":3,"file":"lineChartSeparator.d.ts","sourceRoot":"","sources":["../../../../../src/charts/lineChart/fragments/lineChartSeparator.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,EAA4C,MAAM,OAAO,CAAC;AAa1E,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AAEjE,eAAO,MAAM,kBAAkB,EAAE,EAAE,CAAC,uBAAuB,CA0G1D,CAAC"}
@@ -5,13 +5,26 @@ import { getPoints } from '../../../utils/getPoints/getPoints';
5
5
  import { LineChartContext } from '../context/lineChartContext';
6
6
  export const LineChartSeparator = ({ areaSeparator, dataTestId, rightSeparator, topSeparator, xBreakAxis, yBreakAxis, }) => {
7
7
  const { addError, crossXAxis, crossYAxis, xAxisCoordinates, yAxisCoordinates } = useContext(LineChartContext);
8
+ // Extract tick values for stable dependencies
9
+ const xTickValues = xAxisCoordinates.tickValues;
10
+ const yTickValues = yAxisCoordinates.tickValues;
11
+ // Pre-calculate numeric values for dependencies
12
+ const xBreakNumeric = xBreakAxis !== undefined
13
+ ? typeof xBreakAxis === 'string'
14
+ ? parseFloat(xBreakAxis)
15
+ : xBreakAxis
16
+ : undefined;
17
+ const yBreakNumeric = yBreakAxis !== undefined
18
+ ? typeof yBreakAxis === 'string'
19
+ ? parseFloat(yBreakAxis)
20
+ : yBreakAxis
21
+ : undefined;
8
22
  // Separator error validations
9
23
  useEffect(() => {
10
24
  // xBreakAxis validation
11
25
  if (xBreakAxis !== undefined) {
12
- const xValues = xAxisCoordinates.tickValues.map(tick => tick.value);
13
- const xBreakNumeric = typeof xBreakAxis === 'string' ? parseFloat(xBreakAxis) : xBreakAxis;
14
- if (isNaN(xBreakNumeric)) {
26
+ const xValues = xTickValues.map(tick => tick.value);
27
+ if (xBreakNumeric === undefined || isNaN(xBreakNumeric)) {
15
28
  addError?.('LINE_CHART_SEPARATOR_ERROR', {
16
29
  error: buildSeparatorXBreakAxisError(xBreakAxis),
17
30
  });
@@ -28,9 +41,8 @@ export const LineChartSeparator = ({ areaSeparator, dataTestId, rightSeparator,
28
41
  }
29
42
  // yBreakAxis validation
30
43
  if (yBreakAxis !== undefined) {
31
- const yValues = yAxisCoordinates.tickValues.map(tick => tick.value);
32
- const yBreakNumeric = typeof yBreakAxis === 'string' ? parseFloat(yBreakAxis) : yBreakAxis;
33
- if (isNaN(yBreakNumeric)) {
44
+ const yValues = yTickValues.map(tick => tick.value);
45
+ if (yBreakNumeric === undefined || isNaN(yBreakNumeric)) {
34
46
  addError?.('LINE_CHART_SEPARATOR_ERROR', {
35
47
  error: buildSeparatorYBreakAxisError(yBreakAxis),
36
48
  });
@@ -45,7 +57,7 @@ export const LineChartSeparator = ({ areaSeparator, dataTestId, rightSeparator,
45
57
  }
46
58
  }
47
59
  }
48
- }, [xBreakAxis, yBreakAxis, xAxisCoordinates.tickValues, yAxisCoordinates.tickValues, addError]);
60
+ }, [xBreakAxis, xBreakNumeric, xTickValues, yBreakAxis, yBreakNumeric, yTickValues]);
49
61
  if (!topSeparator && !rightSeparator && !areaSeparator) {
50
62
  return _jsx(_Fragment, {});
51
63
  }
@@ -64,7 +76,7 @@ export const LineChartSeparator = ({ areaSeparator, dataTestId, rightSeparator,
64
76
  error: buildError(BuildError.LINE_CHART_SEPARATOR_INVALID_COORDINATES),
65
77
  });
66
78
  }
67
- }, [xStart, xEnd, yStart, yEnd, addError]);
79
+ }, [xStart, xEnd, yStart, yEnd]);
68
80
  const squarePath = `M${xStart} ${yStart} H ${xEnd} V ${yEnd} H ${xStart} Z`;
69
81
  const lineTop = `M${xStart} ${yEnd} H ${xEnd}`;
70
82
  const lineRight = `M${xEnd} ${yStart} V ${yEnd}`;
@@ -1,9 +1,11 @@
1
+ import type { ChartError, ErrorType } from '../../../types/errors.type';
1
2
  import type { PieChartChildrenType, PieChartContextType } from '../pieChart.type';
2
3
  interface BuildPieContextValueProps {
3
4
  children: PieChartChildrenType;
4
5
  canvasWidth: number;
5
6
  canvasHeight: number;
6
7
  halfChart?: boolean;
8
+ addError?: (errorType: keyof typeof ErrorType, error: Omit<ChartError, 'type'>) => void;
7
9
  }
8
10
  /**
9
11
  * Builds the context value for the PieChart component.
@@ -11,6 +13,6 @@ interface BuildPieContextValueProps {
11
13
  * @param {BuildPieContextValueProps} props - The props for building the context value.
12
14
  * @returns {Omit<PieChartContextType, 'canvasHeight' | 'canvasWidth' | 'data'>} The context value.
13
15
  */
14
- export declare const buildPieContextValue: ({ canvasHeight, canvasWidth, children, halfChart, }: BuildPieContextValueProps) => Omit<PieChartContextType, "canvasHeight" | "canvasWidth" | "data">;
16
+ export declare const buildPieContextValue: ({ addError, canvasHeight, canvasWidth, children, halfChart, }: BuildPieContextValueProps) => Omit<PieChartContextType, "canvasHeight" | "canvasWidth" | "data">;
15
17
  export {};
16
18
  //# sourceMappingURL=buildPieContextValue.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"buildPieContextValue.d.ts","sourceRoot":"","sources":["../../../../../src/charts/pieChart/context/buildPieContextValue.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAElF,UAAU,yBAAyB;IACjC,QAAQ,EAAE,oBAAoB,CAAC;IAC/B,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED;;;;;GAKG;AAEH,eAAO,MAAM,oBAAoB,GAAI,qDAKlC,yBAAyB,KAAG,IAAI,CACjC,mBAAmB,EACnB,cAAc,GAAG,aAAa,GAAG,MAAM,CAsCxC,CAAC"}
1
+ {"version":3,"file":"buildPieContextValue.d.ts","sourceRoot":"","sources":["../../../../../src/charts/pieChart/context/buildPieContextValue.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAMjE,OAAO,KAAK,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAElF,UAAU,yBAAyB;IACjC,QAAQ,EAAE,oBAAoB,CAAC;IAC/B,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,QAAQ,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,OAAO,SAAS,EAAE,KAAK,EAAE,IAAI,CAAC,UAAU,EAAE,MAAM,CAAC,KAAK,IAAI,CAAC;CACzF;AAED;;;;;GAKG;AAEH,eAAO,MAAM,oBAAoB,GAAI,+DAMlC,yBAAyB,KAAG,IAAI,CACjC,mBAAmB,EACnB,cAAc,GAAG,aAAa,GAAG,MAAM,CAkDxC,CAAC"}
@@ -1,5 +1,7 @@
1
1
  import { Children, isValidElement } from 'react';
2
+ import { buildCanvasDimensionsError } from '../../../utils/buildErrors/buildErrors';
2
3
  import { parseStringToNumberPx } from '../../../utils/parseStringToNumberPx.ts/parseStringToNumberPx';
4
+ import { CHART_CANVAS_DEFAULTS } from '../../constants/chartDefaults';
3
5
  import { PieChartPath } from '../fragments/pieChartPath';
4
6
  /**
5
7
  * Builds the context value for the PieChart component.
@@ -7,7 +9,16 @@ import { PieChartPath } from '../fragments/pieChartPath';
7
9
  * @param {BuildPieContextValueProps} props - The props for building the context value.
8
10
  * @returns {Omit<PieChartContextType, 'canvasHeight' | 'canvasWidth' | 'data'>} The context value.
9
11
  */
10
- export const buildPieContextValue = ({ canvasHeight, canvasWidth, children, halfChart, }) => {
12
+ export const buildPieContextValue = ({ addError, canvasHeight, canvasWidth, children, halfChart, }) => {
13
+ // Validate canvas dimensions
14
+ if (canvasWidth <= 0 || canvasHeight <= 0) {
15
+ addError?.('PIE_CHART_CONTEXT_ERROR', {
16
+ error: buildCanvasDimensionsError(canvasWidth, canvasHeight),
17
+ });
18
+ }
19
+ // Use safe canvas dimensions with defaults if invalid
20
+ const safeCanvasWidth = canvasWidth > 0 ? canvasWidth : CHART_CANVAS_DEFAULTS.SAFE_WIDTH;
21
+ const safeCanvasHeight = canvasHeight > 0 ? canvasHeight : CHART_CANVAS_DEFAULTS.SAFE_HEIGHT;
11
22
  // Use the min inner radious of the paths to calculate the size
12
23
  let minRadius = undefined;
13
24
  let foreignObjectSize = undefined;
@@ -32,9 +43,10 @@ export const buildPieContextValue = ({ canvasHeight, canvasWidth, children, half
32
43
  const sizeFixed = foreignObjectSize ?? 0;
33
44
  const height = halfChart ? sizeFixed / 2 : sizeFixed;
34
45
  const width = sizeFixed;
35
- const x = canvasWidth / 2;
36
- const y = halfChart ? canvasHeight : canvasHeight / 2;
46
+ const x = safeCanvasWidth / 2;
47
+ const y = halfChart ? safeCanvasHeight : safeCanvasHeight / 2;
37
48
  return {
49
+ addError,
38
50
  foreignObject: {
39
51
  height,
40
52
  width,
@@ -1 +1 @@
1
- {"version":3,"file":"pieChartPath.d.ts","sourceRoot":"","sources":["../../../../../src/charts/pieChart/fragments/pieChartPath.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,EAAyC,MAAM,OAAO,CAAC;AAEvE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AAM9D;;;;;;;;;;GAUG;AACH,eAAO,MAAM,YAAY,EAAE,EAAE,CAAC,SAAS,CAyCtC,CAAC"}
1
+ {"version":3,"file":"pieChartPath.d.ts","sourceRoot":"","sources":["../../../../../src/charts/pieChart/fragments/pieChartPath.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,EAAoD,MAAM,OAAO,CAAC;AAElF,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AAW9D;;;;;;;;;;GAUG;AACH,eAAO,MAAM,YAAY,EAAE,EAAE,CAAC,SAAS,CA4EtC,CAAC"}
@@ -1,6 +1,7 @@
1
1
  import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  import { createElement as _createElement } from "react";
3
- import { useContext, useRef } from 'react';
3
+ import { useContext, useEffect, useRef } from 'react';
4
+ import { buildEmptyDataArrayError, buildInvalidTotalError, buildPieDataKeyNotFoundError, } from '../../../utils/buildErrors/buildErrors';
4
5
  import { parseStringToNumberPx } from '../../../utils/parseStringToNumberPx.ts/parseStringToNumberPx';
5
6
  import { PieChartContext } from '../context/pieChartContext';
6
7
  import { PieChartSegment } from './pieChartSegment';
@@ -17,12 +18,39 @@ import { PieChartSegment } from './pieChartSegment';
17
18
  */
18
19
  export const PieChartPath = ({ dataKey, fill, gap, innerRadius, radius, ...props }) => {
19
20
  const key = String(dataKey);
20
- const { canvasHeight, canvasWidth, data, dataTestId, halfChart } = useContext(PieChartContext);
21
+ const { addError, canvasHeight, canvasWidth, data, dataTestId, halfChart } = useContext(PieChartContext);
21
22
  const chartInitAngle = halfChart ? 0 : -Math.PI / 2; // ? 0deg : -90deg
22
23
  const startAngle = useRef(chartInitAngle);
24
+ // Extract data for this key to optimize useEffect dependencies
25
+ const dataArray = data[key];
26
+ const hasDataKey = Object.prototype.hasOwnProperty.call(data, key);
27
+ // Path error validations
28
+ useEffect(() => {
29
+ // Validate dataKey exists in dataset
30
+ if (!hasDataKey) {
31
+ addError?.('PIE_CHART_PATH_ERROR', {
32
+ error: buildPieDataKeyNotFoundError(key),
33
+ });
34
+ return;
35
+ }
36
+ // Validate data array exists and is not empty
37
+ if (!dataArray || dataArray.length === 0) {
38
+ addError?.('PIE_CHART_PATH_ERROR', {
39
+ error: buildEmptyDataArrayError(key),
40
+ });
41
+ return;
42
+ }
43
+ // Calculate total and validate
44
+ const calculatedTotal = dataArray.reduce((acc, group) => acc + group.value, 0);
45
+ if (calculatedTotal <= 0 || isNaN(calculatedTotal)) {
46
+ addError?.('PIE_CHART_PATH_ERROR', {
47
+ error: buildInvalidTotalError(key, calculatedTotal),
48
+ });
49
+ }
50
+ }, [dataArray, hasDataKey, key]);
23
51
  const total = data[key]?.reduce((acc, group) => acc + group.value, 0);
24
52
  const singleStroke = data[key]?.length === 1;
25
53
  const parsedInnerRadius = innerRadius ? parseStringToNumberPx(innerRadius) : undefined;
26
54
  const parsedRadius = radius ? parseStringToNumberPx(radius) : undefined;
27
- return data[key]?.length ? (_jsx("g", { children: data[key].map((group, index) => (_createElement(PieChartSegment, { ...props, ...group, key: `${index.toString()}`, canvasHeight: canvasHeight, canvasWidth: canvasWidth, color: group.color || fill, dataTestId: `${dataTestId}path-${index}`, gap: gap, halfChart: halfChart, innerRadius: parsedInnerRadius, radius: parsedRadius, singleStroke: singleStroke, startAngle: startAngle, total: total }))) })) : (_jsx(_Fragment, {}));
55
+ return data[key]?.length ? (_jsx("g", { children: data[key].map((group, index) => (_createElement(PieChartSegment, { ...props, ...group, key: `${index.toString()}`, canvasHeight: canvasHeight, canvasWidth: canvasWidth, color: group.color || fill, dataKey: key, dataTestId: `${dataTestId}path-${index}`, gap: gap, halfChart: halfChart, index: index, innerRadius: parsedInnerRadius, radius: parsedRadius, singleStroke: singleStroke, startAngle: startAngle, total: total }))) })) : (_jsx(_Fragment, {}));
28
56
  };
@@ -1 +1 @@
1
- {"version":3,"file":"pieChartSegment.d.ts","sourceRoot":"","sources":["../../../../../src/charts/pieChart/fragments/pieChartSegment.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAG7D;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC,oBAAoB,CAmC1D,CAAC"}
1
+ {"version":3,"file":"pieChartSegment.d.ts","sourceRoot":"","sources":["../../../../../src/charts/pieChart/fragments/pieChartSegment.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAG7D;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC,oBAAoB,CAoG1D,CAAC"}
@@ -1,5 +1,8 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useContext, useEffect } from 'react';
2
3
  import { Path } from '../../../components/path/path';
4
+ import { buildInnerRadiusOutOfRangeError, buildInvalidGroupError, buildInvalidInnerRadiusError, buildInvalidRadiusError, buildSegmentNegativeValueError, buildSegmentValueError, } from '../../../utils/buildErrors/buildErrors';
5
+ import { PieChartContext } from '../context/pieChartContext';
3
6
  import { calculateSegmentPath } from '../utils/calculateSegmentPath';
4
7
  /**
5
8
  * Renders a segment of a pie chart.
@@ -16,7 +19,61 @@ import { calculateSegmentPath } from '../utils/calculateSegmentPath';
16
19
  * @param props - Additional props to pass to the Path component.
17
20
  * @returns A React element representing the pie chart segment.
18
21
  */
19
- export const PieChartSegment = ({ canvasHeight, canvasWidth, color = 'blue', gap, halfChart, innerRadius, radius, singleStroke, startAngle, total, value, ...props }) => {
22
+ export const PieChartSegment = ({ canvasHeight, canvasWidth, color = 'blue', dataKey, gap, halfChart, index, innerRadius, name, radius, singleStroke, startAngle, total, value, ...props }) => {
23
+ const { addError } = useContext(PieChartContext);
24
+ // Convert values to primitives for stable dependencies
25
+ const numericValue = Number(value);
26
+ const numericRadius = radius !== undefined ? Number(radius) : undefined;
27
+ const numericInnerRadius = innerRadius !== undefined ? Number(innerRadius) : undefined;
28
+ const trimmedName = name?.trim() || '';
29
+ // Segment error validations
30
+ useEffect(() => {
31
+ // Validate segment has non-empty name property
32
+ if (!trimmedName) {
33
+ addError?.('PIE_CHART_SEGMENT_ERROR', {
34
+ error: buildInvalidGroupError(dataKey || 'unknown', index || 0, 'name'),
35
+ });
36
+ }
37
+ // Validate segment value is numeric
38
+ if (isNaN(numericValue)) {
39
+ addError?.('PIE_CHART_SEGMENT_ERROR', {
40
+ error: buildSegmentValueError(value, trimmedName || `segment-${index}`),
41
+ });
42
+ return;
43
+ }
44
+ // Validate non-negative values
45
+ if (numericValue < 0) {
46
+ addError?.('PIE_CHART_SEGMENT_ERROR', {
47
+ error: buildSegmentNegativeValueError(numericValue, trimmedName || `segment-${index}`),
48
+ });
49
+ }
50
+ // Validate radius if provided
51
+ if (numericRadius !== undefined) {
52
+ if (isNaN(numericRadius) || numericRadius <= 0) {
53
+ addError?.('PIE_CHART_SEGMENT_ERROR', {
54
+ error: buildInvalidRadiusError(radius),
55
+ });
56
+ }
57
+ }
58
+ // Validate innerRadius if provided
59
+ if (numericInnerRadius !== undefined) {
60
+ if (isNaN(numericInnerRadius) || numericInnerRadius < 0) {
61
+ addError?.('PIE_CHART_SEGMENT_ERROR', {
62
+ error: buildInvalidInnerRadiusError(innerRadius),
63
+ });
64
+ }
65
+ // Validate innerRadius < radius
66
+ if (numericRadius !== undefined) {
67
+ if (!isNaN(numericRadius) && !isNaN(numericInnerRadius)) {
68
+ if (numericInnerRadius >= numericRadius) {
69
+ addError?.('PIE_CHART_SEGMENT_ERROR', {
70
+ error: buildInnerRadiusOutOfRangeError(numericInnerRadius, numericRadius),
71
+ });
72
+ }
73
+ }
74
+ }
75
+ }
76
+ }, [dataKey, index, numericInnerRadius, numericRadius, numericValue, trimmedName]);
20
77
  const pathData = calculateSegmentPath({
21
78
  canvasHeight,
22
79
  canvasWidth,
@@ -1,6 +1,7 @@
1
1
  import type { ReactElement, ReactNode } from 'react';
2
2
  import type { PathProps } from '../../components/path/path.types';
3
3
  import type { CanvasConfig } from '../../types/canvas.type';
4
+ import type { ChartError, ChartErrorCollection, ErrorType } from '../../types/errors.type';
4
5
  interface Group {
5
6
  name: string;
6
7
  value: number;
@@ -34,6 +35,7 @@ export interface PieChartProps {
34
35
  onBlur?: (event: React.FocusEvent<SVGElement>) => void;
35
36
  onKeyDown?: (event: React.KeyboardEvent<SVGSVGElement>) => void;
36
37
  onKeyUp?: (event: React.KeyboardEvent<SVGSVGElement>) => void;
38
+ onErrors?: (errors: ChartErrorCollection) => void;
37
39
  }
38
40
  export interface PieChartContextType {
39
41
  foreignObject?: {
@@ -47,6 +49,8 @@ export interface PieChartContextType {
47
49
  data: DataItem;
48
50
  dataTestId?: string;
49
51
  halfChart?: boolean;
52
+ error?: ChartError;
53
+ addError?: (errorType: keyof typeof ErrorType, error: Omit<ChartError, 'type'>) => void;
50
54
  }
51
55
  export type PieChartSegmentProps = PathProps & {
52
56
  total: number;
@@ -58,8 +62,11 @@ export type PieChartSegmentProps = PathProps & {
58
62
  radius?: number;
59
63
  value: number;
60
64
  color?: string;
65
+ name?: string;
61
66
  singleStroke: boolean;
62
67
  halfChart?: boolean;
68
+ dataKey?: string;
69
+ index?: number;
63
70
  };
64
71
  export {};
65
72
  //# sourceMappingURL=pieChart.type.d.ts.map