@pie-lib/charting 7.0.4-next.30 → 7.0.4-next.34

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 (272) hide show
  1. package/CHANGELOG.json +17 -0
  2. package/CHANGELOG.md +1116 -0
  3. package/LICENSE.md +5 -0
  4. package/lib/actions-button.js +145 -0
  5. package/lib/actions-button.js.map +1 -0
  6. package/lib/axes.js +643 -0
  7. package/lib/axes.js.map +1 -0
  8. package/lib/bars/bar.js +58 -0
  9. package/lib/bars/bar.js.map +1 -0
  10. package/lib/bars/common/bars.js +277 -0
  11. package/lib/bars/common/bars.js.map +1 -0
  12. package/lib/bars/common/correct-check-icon.js +54 -0
  13. package/lib/bars/common/correct-check-icon.js.map +1 -0
  14. package/lib/bars/histogram.js +59 -0
  15. package/lib/bars/histogram.js.map +1 -0
  16. package/lib/chart-setup.js +382 -0
  17. package/lib/chart-setup.js.map +1 -0
  18. package/lib/chart-type.js +80 -0
  19. package/lib/chart-type.js.map +1 -0
  20. package/lib/chart-types.js +22 -0
  21. package/lib/chart-types.js.map +1 -0
  22. package/lib/chart.js +384 -0
  23. package/lib/chart.js.map +1 -0
  24. package/lib/common/correctness-indicators.js +156 -0
  25. package/lib/common/correctness-indicators.js.map +1 -0
  26. package/lib/common/drag-handle.js +160 -0
  27. package/lib/common/drag-handle.js.map +1 -0
  28. package/lib/common/drag-icon.js +52 -0
  29. package/lib/common/drag-icon.js.map +1 -0
  30. package/lib/common/styles.js +22 -0
  31. package/lib/common/styles.js.map +1 -0
  32. package/lib/grid.js +112 -0
  33. package/lib/grid.js.map +1 -0
  34. package/lib/index.js +42 -0
  35. package/lib/index.js.map +1 -0
  36. package/lib/key-legend.js +87 -0
  37. package/lib/key-legend.js.map +1 -0
  38. package/lib/line/common/drag-handle.js +146 -0
  39. package/lib/line/common/drag-handle.js.map +1 -0
  40. package/lib/line/common/line.js +214 -0
  41. package/lib/line/common/line.js.map +1 -0
  42. package/lib/line/line-cross.js +214 -0
  43. package/lib/line/line-cross.js.map +1 -0
  44. package/lib/line/line-dot.js +158 -0
  45. package/lib/line/line-dot.js.map +1 -0
  46. package/lib/mark-label.js +237 -0
  47. package/lib/mark-label.js.map +1 -0
  48. package/lib/plot/common/plot.js +349 -0
  49. package/lib/plot/common/plot.js.map +1 -0
  50. package/lib/plot/dot.js +110 -0
  51. package/lib/plot/dot.js.map +1 -0
  52. package/lib/plot/line.js +140 -0
  53. package/lib/plot/line.js.map +1 -0
  54. package/lib/tool-menu.js +106 -0
  55. package/lib/tool-menu.js.map +1 -0
  56. package/lib/utils.js +189 -0
  57. package/lib/utils.js.map +1 -0
  58. package/package.json +28 -39
  59. package/src/__tests__/actions-button.test.jsx +280 -0
  60. package/src/__tests__/axes.test.jsx +667 -0
  61. package/src/__tests__/chart-setup.test.jsx +532 -0
  62. package/src/__tests__/chart-type.test.jsx +23 -0
  63. package/src/__tests__/chart.test.jsx +86 -0
  64. package/src/__tests__/grid.test.jsx +37 -0
  65. package/src/__tests__/key-legend.test.jsx +223 -0
  66. package/src/__tests__/mark-label.test.jsx +33 -0
  67. package/src/__tests__/tool-menu.test.jsx +522 -0
  68. package/src/__tests__/utils.js +36 -0
  69. package/src/__tests__/utils.test.js +100 -0
  70. package/src/actions-button.jsx +115 -0
  71. package/src/axes.jsx +594 -0
  72. package/src/bars/__tests__/bar.test.jsx +45 -0
  73. package/src/bars/__tests__/histogram.test.jsx +45 -0
  74. package/src/bars/__tests__/utils.js +30 -0
  75. package/src/bars/bar.js +28 -0
  76. package/src/bars/common/__tests__/bars.test.jsx +68 -0
  77. package/src/bars/common/__tests__/utils.js +30 -0
  78. package/src/bars/common/bars.jsx +249 -0
  79. package/src/bars/common/correct-check-icon.jsx +25 -0
  80. package/src/bars/histogram.js +28 -0
  81. package/src/chart-setup.jsx +356 -0
  82. package/src/chart-type.js +59 -0
  83. package/src/chart-types.js +8 -0
  84. package/src/chart.jsx +357 -0
  85. package/src/common/__tests__/correctness-indicators.test.jsx +720 -0
  86. package/src/common/__tests__/drag-handle.test.jsx +58 -0
  87. package/src/common/__tests__/utils.js +30 -0
  88. package/src/common/correctness-indicators.jsx +128 -0
  89. package/src/common/drag-handle.jsx +125 -0
  90. package/src/common/drag-icon.jsx +36 -0
  91. package/src/common/styles.js +19 -0
  92. package/src/grid.jsx +80 -0
  93. package/src/index.js +7 -0
  94. package/src/key-legend.jsx +77 -0
  95. package/src/line/__tests__/line-cross.test.jsx +463 -0
  96. package/src/line/__tests__/line-dot.test.jsx +41 -0
  97. package/src/line/__tests__/utils.js +36 -0
  98. package/src/line/common/__tests__/drag-handle.test.jsx +62 -0
  99. package/src/line/common/__tests__/line.test.jsx +79 -0
  100. package/src/line/common/__tests__/utils.js +30 -0
  101. package/src/line/common/drag-handle.jsx +114 -0
  102. package/src/line/common/line.jsx +171 -0
  103. package/src/line/line-cross.js +144 -0
  104. package/src/line/line-dot.js +111 -0
  105. package/src/mark-label.jsx +238 -0
  106. package/src/plot/__tests__/dot.test.jsx +344 -0
  107. package/src/plot/__tests__/line.test.jsx +375 -0
  108. package/src/plot/__tests__/utils.js +30 -0
  109. package/src/plot/common/__tests__/plot.test.jsx +69 -0
  110. package/src/plot/common/__tests__/utils.js +30 -0
  111. package/src/plot/common/plot.jsx +358 -0
  112. package/src/plot/dot.js +74 -0
  113. package/src/plot/line.js +98 -0
  114. package/src/tool-menu.jsx +85 -0
  115. package/src/utils.js +201 -0
  116. package/dist/_virtual/_rolldown/runtime.js +0 -23
  117. package/dist/actions-button.d.ts +0 -26
  118. package/dist/actions-button.js +0 -84
  119. package/dist/autosize-input.d.ts +0 -10
  120. package/dist/autosize-input.js +0 -66
  121. package/dist/axes.d.ts +0 -84
  122. package/dist/axes.js +0 -376
  123. package/dist/bars/bar.d.ts +0 -47
  124. package/dist/bars/bar.js +0 -27
  125. package/dist/bars/common/bars.d.ts +0 -98
  126. package/dist/bars/common/bars.js +0 -174
  127. package/dist/bars/common/correct-check-icon.d.ts +0 -18
  128. package/dist/bars/common/correct-check-icon.js +0 -50
  129. package/dist/bars/histogram.d.ts +0 -47
  130. package/dist/bars/histogram.js +0 -28
  131. package/dist/chart-setup.d.ts +0 -29
  132. package/dist/chart-setup.js +0 -231
  133. package/dist/chart-type.d.ts +0 -32
  134. package/dist/chart-type.js +0 -68
  135. package/dist/chart-types.d.ts +0 -41
  136. package/dist/chart-types.js +0 -17
  137. package/dist/chart.d.ts +0 -88
  138. package/dist/chart.js +0 -250
  139. package/dist/common/correctness-indicators.d.ts +0 -70
  140. package/dist/common/correctness-indicators.js +0 -106
  141. package/dist/common/drag-handle.d.ts +0 -129
  142. package/dist/common/drag-handle.js +0 -120
  143. package/dist/common/drag-icon.d.ts +0 -23
  144. package/dist/common/drag-icon.js +0 -45
  145. package/dist/common/styles.d.ts +0 -23
  146. package/dist/common/styles.js +0 -17
  147. package/dist/grid.d.ts +0 -45
  148. package/dist/grid.js +0 -56
  149. package/dist/index.d.ts +0 -14
  150. package/dist/index.js +0 -6
  151. package/dist/key-legend.d.ts +0 -19
  152. package/dist/key-legend.js +0 -46
  153. package/dist/line/common/drag-handle.d.ts +0 -120
  154. package/dist/line/common/drag-handle.js +0 -92
  155. package/dist/line/common/line.d.ts +0 -96
  156. package/dist/line/common/line.js +0 -114
  157. package/dist/line/line-cross.d.ts +0 -47
  158. package/dist/line/line-cross.js +0 -133
  159. package/dist/line/line-dot.d.ts +0 -47
  160. package/dist/line/line-dot.js +0 -101
  161. package/dist/mark-label.d.ts +0 -55
  162. package/dist/mark-label.js +0 -138
  163. package/dist/node_modules/.bun/@visx_axis@3.12.0_f4eacebf2041cd4f/node_modules/@visx/axis/esm/axis/Axis.js +0 -101
  164. package/dist/node_modules/.bun/@visx_axis@3.12.0_f4eacebf2041cd4f/node_modules/@visx/axis/esm/axis/AxisBottom.js +0 -46
  165. package/dist/node_modules/.bun/@visx_axis@3.12.0_f4eacebf2041cd4f/node_modules/@visx/axis/esm/axis/AxisLeft.js +0 -47
  166. package/dist/node_modules/.bun/@visx_axis@3.12.0_f4eacebf2041cd4f/node_modules/@visx/axis/esm/axis/AxisRenderer.js +0 -63
  167. package/dist/node_modules/.bun/@visx_axis@3.12.0_f4eacebf2041cd4f/node_modules/@visx/axis/esm/axis/Ticks.js +0 -44
  168. package/dist/node_modules/.bun/@visx_axis@3.12.0_f4eacebf2041cd4f/node_modules/@visx/axis/esm/constants/orientation.js +0 -9
  169. package/dist/node_modules/.bun/@visx_axis@3.12.0_f4eacebf2041cd4f/node_modules/@visx/axis/esm/utils/createPoint.js +0 -14
  170. package/dist/node_modules/.bun/@visx_axis@3.12.0_f4eacebf2041cd4f/node_modules/@visx/axis/esm/utils/getAxisRangePaddingConfig.js +0 -21
  171. package/dist/node_modules/.bun/@visx_axis@3.12.0_f4eacebf2041cd4f/node_modules/@visx/axis/esm/utils/getLabelTransform.js +0 -16
  172. package/dist/node_modules/.bun/@visx_axis@3.12.0_f4eacebf2041cd4f/node_modules/@visx/axis/esm/utils/getTickFormatter.js +0 -8
  173. package/dist/node_modules/.bun/@visx_axis@3.12.0_f4eacebf2041cd4f/node_modules/@visx/axis/esm/utils/getTickPosition.js +0 -15
  174. package/dist/node_modules/.bun/@visx_grid@3.12.0_f4eacebf2041cd4f/node_modules/@visx/grid/esm/grids/GridColumns.js +0 -79
  175. package/dist/node_modules/.bun/@visx_grid@3.12.0_f4eacebf2041cd4f/node_modules/@visx/grid/esm/grids/GridRows.js +0 -79
  176. package/dist/node_modules/.bun/@visx_grid@3.12.0_f4eacebf2041cd4f/node_modules/@visx/grid/esm/utils/getScaleBandwidth.js +0 -6
  177. package/dist/node_modules/.bun/@visx_group@3.12.0_f4eacebf2041cd4f/node_modules/@visx/group/esm/Group.js +0 -50
  178. package/dist/node_modules/.bun/@visx_point@3.12.0/node_modules/@visx/point/esm/Point.js +0 -18
  179. package/dist/node_modules/.bun/@visx_scale@3.12.0/node_modules/@visx/scale/esm/operators/align.js +0 -6
  180. package/dist/node_modules/.bun/@visx_scale@3.12.0/node_modules/@visx/scale/esm/operators/base.js +0 -6
  181. package/dist/node_modules/.bun/@visx_scale@3.12.0/node_modules/@visx/scale/esm/operators/clamp.js +0 -6
  182. package/dist/node_modules/.bun/@visx_scale@3.12.0/node_modules/@visx/scale/esm/operators/constant.js +0 -6
  183. package/dist/node_modules/.bun/@visx_scale@3.12.0/node_modules/@visx/scale/esm/operators/domain.js +0 -6
  184. package/dist/node_modules/.bun/@visx_scale@3.12.0/node_modules/@visx/scale/esm/operators/exponent.js +0 -6
  185. package/dist/node_modules/.bun/@visx_scale@3.12.0/node_modules/@visx/scale/esm/operators/interpolate.js +0 -10
  186. package/dist/node_modules/.bun/@visx_scale@3.12.0/node_modules/@visx/scale/esm/operators/nice.js +0 -37
  187. package/dist/node_modules/.bun/@visx_scale@3.12.0/node_modules/@visx/scale/esm/operators/padding.js +0 -6
  188. package/dist/node_modules/.bun/@visx_scale@3.12.0/node_modules/@visx/scale/esm/operators/range.js +0 -6
  189. package/dist/node_modules/.bun/@visx_scale@3.12.0/node_modules/@visx/scale/esm/operators/reverse.js +0 -9
  190. package/dist/node_modules/.bun/@visx_scale@3.12.0/node_modules/@visx/scale/esm/operators/round.js +0 -7
  191. package/dist/node_modules/.bun/@visx_scale@3.12.0/node_modules/@visx/scale/esm/operators/scaleOperator.js +0 -58
  192. package/dist/node_modules/.bun/@visx_scale@3.12.0/node_modules/@visx/scale/esm/operators/unknown.js +0 -6
  193. package/dist/node_modules/.bun/@visx_scale@3.12.0/node_modules/@visx/scale/esm/operators/zero.js +0 -9
  194. package/dist/node_modules/.bun/@visx_scale@3.12.0/node_modules/@visx/scale/esm/scales/band.js +0 -9
  195. package/dist/node_modules/.bun/@visx_scale@3.12.0/node_modules/@visx/scale/esm/scales/point.js +0 -9
  196. package/dist/node_modules/.bun/@visx_scale@3.12.0/node_modules/@visx/scale/esm/utils/coerceNumber.js +0 -10
  197. package/dist/node_modules/.bun/@visx_scale@3.12.0/node_modules/@visx/scale/esm/utils/createColorInterpolator.js +0 -29
  198. package/dist/node_modules/.bun/@visx_scale@3.12.0/node_modules/@visx/scale/esm/utils/getTicks.js +0 -9
  199. package/dist/node_modules/.bun/@visx_scale@3.12.0/node_modules/@visx/scale/esm/utils/isUtcScale.js +0 -7
  200. package/dist/node_modules/.bun/@visx_scale@3.12.0/node_modules/@visx/scale/esm/utils/toString.js +0 -6
  201. package/dist/node_modules/.bun/@visx_shape@3.12.0_f4eacebf2041cd4f/node_modules/@visx/shape/esm/shapes/Bar.js +0 -29
  202. package/dist/node_modules/.bun/@visx_shape@3.12.0_f4eacebf2041cd4f/node_modules/@visx/shape/esm/shapes/Circle.js +0 -29
  203. package/dist/node_modules/.bun/@visx_shape@3.12.0_f4eacebf2041cd4f/node_modules/@visx/shape/esm/shapes/Line.js +0 -47
  204. package/dist/node_modules/.bun/@visx_shape@3.12.0_f4eacebf2041cd4f/node_modules/@visx/shape/esm/shapes/LinePath.js +0 -50
  205. package/dist/node_modules/.bun/@visx_shape@3.12.0_f4eacebf2041cd4f/node_modules/@visx/shape/esm/util/D3ShapeFactories.js +0 -9
  206. package/dist/node_modules/.bun/@visx_shape@3.12.0_f4eacebf2041cd4f/node_modules/@visx/shape/esm/util/setNumberOrNumberAccessor.js +0 -6
  207. package/dist/node_modules/.bun/@visx_shape@3.12.0_f4eacebf2041cd4f/node_modules/@visx/shape/lib/shapes/Line.js +0 -53
  208. package/dist/node_modules/.bun/@visx_text@3.12.0_f4eacebf2041cd4f/node_modules/@visx/text/esm/Text.js +0 -57
  209. package/dist/node_modules/.bun/@visx_text@3.12.0_f4eacebf2041cd4f/node_modules/@visx/text/esm/hooks/useText.js +0 -91
  210. package/dist/node_modules/.bun/@visx_text@3.12.0_f4eacebf2041cd4f/node_modules/@visx/text/esm/util/getStringWidth.js +0 -21
  211. package/dist/node_modules/.bun/@visx_vendor@3.12.0/node_modules/@visx/vendor/esm/d3-interpolate.js +0 -8
  212. package/dist/node_modules/.bun/@visx_vendor@3.12.0/node_modules/@visx/vendor/esm/d3-scale.js +0 -8
  213. package/dist/node_modules/.bun/@visx_vendor@3.12.0/node_modules/@visx/vendor/esm/d3-time.js +0 -8
  214. package/dist/node_modules/.bun/balanced-match@0.4.2/node_modules/balanced-match/index.js +0 -32
  215. package/dist/node_modules/.bun/balanced-match@1.0.2/node_modules/balanced-match/index.js +0 -33
  216. package/dist/node_modules/.bun/classnames@2.5.1/node_modules/classnames/index.js +0 -32
  217. package/dist/node_modules/.bun/clsx@2.1.1/node_modules/clsx/dist/clsx.js +0 -16
  218. package/dist/node_modules/.bun/lodash@4.18.1/node_modules/lodash/_Hash.js +0 -21
  219. package/dist/node_modules/.bun/lodash@4.18.1/node_modules/lodash/_ListCache.js +0 -21
  220. package/dist/node_modules/.bun/lodash@4.18.1/node_modules/lodash/_Map.js +0 -10
  221. package/dist/node_modules/.bun/lodash@4.18.1/node_modules/lodash/_MapCache.js +0 -21
  222. package/dist/node_modules/.bun/lodash@4.18.1/node_modules/lodash/_Symbol.js +0 -9
  223. package/dist/node_modules/.bun/lodash@4.18.1/node_modules/lodash/_assocIndexOf.js +0 -14
  224. package/dist/node_modules/.bun/lodash@4.18.1/node_modules/lodash/_baseGetTag.js +0 -15
  225. package/dist/node_modules/.bun/lodash@4.18.1/node_modules/lodash/_baseIsNative.js +0 -16
  226. package/dist/node_modules/.bun/lodash@4.18.1/node_modules/lodash/_coreJsData.js +0 -9
  227. package/dist/node_modules/.bun/lodash@4.18.1/node_modules/lodash/_freeGlobal.js +0 -8
  228. package/dist/node_modules/.bun/lodash@4.18.1/node_modules/lodash/_getMapData.js +0 -14
  229. package/dist/node_modules/.bun/lodash@4.18.1/node_modules/lodash/_getNative.js +0 -15
  230. package/dist/node_modules/.bun/lodash@4.18.1/node_modules/lodash/_getRawTag.js +0 -19
  231. package/dist/node_modules/.bun/lodash@4.18.1/node_modules/lodash/_getValue.js +0 -11
  232. package/dist/node_modules/.bun/lodash@4.18.1/node_modules/lodash/_hashClear.js +0 -13
  233. package/dist/node_modules/.bun/lodash@4.18.1/node_modules/lodash/_hashDelete.js +0 -12
  234. package/dist/node_modules/.bun/lodash@4.18.1/node_modules/lodash/_hashGet.js +0 -18
  235. package/dist/node_modules/.bun/lodash@4.18.1/node_modules/lodash/_hashHas.js +0 -14
  236. package/dist/node_modules/.bun/lodash@4.18.1/node_modules/lodash/_hashSet.js +0 -14
  237. package/dist/node_modules/.bun/lodash@4.18.1/node_modules/lodash/_isKeyable.js +0 -12
  238. package/dist/node_modules/.bun/lodash@4.18.1/node_modules/lodash/_isMasked.js +0 -16
  239. package/dist/node_modules/.bun/lodash@4.18.1/node_modules/lodash/_listCacheClear.js +0 -11
  240. package/dist/node_modules/.bun/lodash@4.18.1/node_modules/lodash/_listCacheDelete.js +0 -14
  241. package/dist/node_modules/.bun/lodash@4.18.1/node_modules/lodash/_listCacheGet.js +0 -14
  242. package/dist/node_modules/.bun/lodash@4.18.1/node_modules/lodash/_listCacheHas.js +0 -13
  243. package/dist/node_modules/.bun/lodash@4.18.1/node_modules/lodash/_listCacheSet.js +0 -14
  244. package/dist/node_modules/.bun/lodash@4.18.1/node_modules/lodash/_mapCacheClear.js +0 -19
  245. package/dist/node_modules/.bun/lodash@4.18.1/node_modules/lodash/_mapCacheDelete.js +0 -14
  246. package/dist/node_modules/.bun/lodash@4.18.1/node_modules/lodash/_mapCacheGet.js +0 -13
  247. package/dist/node_modules/.bun/lodash@4.18.1/node_modules/lodash/_mapCacheHas.js +0 -13
  248. package/dist/node_modules/.bun/lodash@4.18.1/node_modules/lodash/_mapCacheSet.js +0 -14
  249. package/dist/node_modules/.bun/lodash@4.18.1/node_modules/lodash/_nativeCreate.js +0 -9
  250. package/dist/node_modules/.bun/lodash@4.18.1/node_modules/lodash/_objectToString.js +0 -12
  251. package/dist/node_modules/.bun/lodash@4.18.1/node_modules/lodash/_root.js +0 -10
  252. package/dist/node_modules/.bun/lodash@4.18.1/node_modules/lodash/_toSource.js +0 -20
  253. package/dist/node_modules/.bun/lodash@4.18.1/node_modules/lodash/eq.js +0 -11
  254. package/dist/node_modules/.bun/lodash@4.18.1/node_modules/lodash/isFunction.js +0 -16
  255. package/dist/node_modules/.bun/lodash@4.18.1/node_modules/lodash/isObject.js +0 -12
  256. package/dist/node_modules/.bun/lodash@4.18.1/node_modules/lodash/memoize.js +0 -20
  257. package/dist/node_modules/.bun/math-expression-evaluator@1.4.0/node_modules/math-expression-evaluator/src/formula_evaluator.js +0 -37
  258. package/dist/node_modules/.bun/math-expression-evaluator@1.4.0/node_modules/math-expression-evaluator/src/lexer.js +0 -509
  259. package/dist/node_modules/.bun/math-expression-evaluator@1.4.0/node_modules/math-expression-evaluator/src/math_function.js +0 -108
  260. package/dist/node_modules/.bun/math-expression-evaluator@1.4.0/node_modules/math-expression-evaluator/src/postfix.js +0 -31
  261. package/dist/node_modules/.bun/math-expression-evaluator@1.4.0/node_modules/math-expression-evaluator/src/postfix_evaluator.js +0 -45
  262. package/dist/node_modules/.bun/reduce-css-calc@1.3.0/node_modules/reduce-css-calc/index.js +0 -49
  263. package/dist/node_modules/.bun/reduce-function-call@1.0.3/node_modules/reduce-function-call/index.js +0 -34
  264. package/dist/plot/common/plot.d.ts +0 -103
  265. package/dist/plot/common/plot.js +0 -227
  266. package/dist/plot/dot.d.ts +0 -47
  267. package/dist/plot/dot.js +0 -62
  268. package/dist/plot/line.d.ts +0 -47
  269. package/dist/plot/line.js +0 -84
  270. package/dist/tool-menu.d.ts +0 -31
  271. package/dist/utils.d.ts +0 -39
  272. package/dist/utils.js +0 -101
@@ -0,0 +1,532 @@
1
+ import React from 'react';
2
+ import { fireEvent, render, waitFor } from '@testing-library/react';
3
+ import { createTheme, ThemeProvider } from '@mui/material/styles';
4
+ import ConfigureChartPanel, { resetValues } from '../chart-setup';
5
+
6
+ jest.mock('../chart-type', () => {
7
+ return function ChartType({ value, onChange }) {
8
+ return (
9
+ <select data-testid="chart-type-select" value={value} onChange={onChange}>
10
+ <option value="bar">Bar</option>
11
+ <option value="line">Line</option>
12
+ <option value="linePlot">Line Plot</option>
13
+ <option value="dotPlot">Dot Plot</option>
14
+ </select>
15
+ );
16
+ };
17
+ });
18
+
19
+ jest.mock('@pie-lib/config-ui', () => ({
20
+ NumberTextFieldCustom: ({ label, value, onChange, ...props }) => (
21
+ <input
22
+ data-testid={`number-field-${label.toLowerCase().replace(/\s+/g, '-')}`}
23
+ type="number"
24
+ value={value}
25
+ onChange={(e) => onChange(e, parseFloat(e.target.value) || 0)}
26
+ aria-label={label}
27
+ {...props}
28
+ />
29
+ ),
30
+ AlertDialog: ({ open, title, text, onClose, onConfirm }) =>
31
+ open ? (
32
+ <div data-testid="alert-dialog">
33
+ <h2>{title}</h2>
34
+ <p>{text}</p>
35
+ <button data-testid="alert-cancel" onClick={onClose}>
36
+ Cancel
37
+ </button>
38
+ <button data-testid="alert-confirm" onClick={onConfirm}>
39
+ Confirm
40
+ </button>
41
+ </div>
42
+ ) : null,
43
+ }));
44
+
45
+ let theme;
46
+
47
+ beforeAll(() => {
48
+ theme = createTheme();
49
+ });
50
+
51
+ describe('resetValues', () => {
52
+ let data;
53
+ let range;
54
+ let model;
55
+ let onChange;
56
+
57
+ beforeEach(() => {
58
+ range = { min: 0, max: 10, step: 1 };
59
+ data = [{ value: 2 }, { value: 11 }, { value: 5.5 }, { value: 2.0000000001 }, { value: 2.9999999999 }];
60
+ model = { someField: 'someValue', data };
61
+ onChange = jest.fn();
62
+ });
63
+
64
+ it('should reset values greater than range.max to zero', () => {
65
+ resetValues(data, true, range, onChange, model);
66
+ expect(data[1].value).toBe(0);
67
+ });
68
+
69
+ it('should reset values that are not multiples of range.step to zero', () => {
70
+ resetValues(data, true, range, onChange, model);
71
+ expect(data[2].value).toBe(0);
72
+ });
73
+
74
+ it('should not reset values that are within range and multiples of range.step', () => {
75
+ resetValues(data, true, range, onChange, model);
76
+ expect(data[0].value).toBe(2);
77
+ });
78
+
79
+ it('should not reset floating point values that are close to multiples of range.step', () => {
80
+ resetValues(data, true, range, onChange, model);
81
+ expect(data[3].value).toBe(2.0000000001);
82
+ expect(data[4].value).toBe(2.9999999999);
83
+ });
84
+
85
+ it('should not call onChange when updateModel is false', () => {
86
+ resetValues(data, false, range, onChange, model);
87
+ expect(onChange).not.toHaveBeenCalled();
88
+ });
89
+
90
+ it('should handle null or undefined data array', () => {
91
+ expect(() => resetValues(null, true, range, onChange, model)).not.toThrow();
92
+ expect(() => resetValues(undefined, true, range, onChange, model)).not.toThrow();
93
+ });
94
+
95
+ it('should handle empty data array', () => {
96
+ resetValues([], true, range, onChange, model);
97
+ expect(onChange).toHaveBeenCalledWith({ ...model, data: [] });
98
+ });
99
+
100
+ it('should reset multiple invalid values', () => {
101
+ const multiData = [{ value: 11 }, { value: 12 }, { value: 5.5 }, { value: 3.7 }];
102
+ resetValues(multiData, true, range, onChange, { ...model, data: multiData });
103
+ expect(multiData.every((d) => d.value === 0)).toBe(true);
104
+ });
105
+
106
+ it('should handle decimal step values', () => {
107
+ const decimalRange = { min: 0, max: 10, step: 0.5 };
108
+ const decimalData = [{ value: 1.5 }, { value: 2.3 }, { value: 3.0 }];
109
+ resetValues(decimalData, true, decimalRange, onChange, model);
110
+ expect(decimalData[0].value).toBe(1.5);
111
+ expect(decimalData[1].value).toBe(0);
112
+ expect(decimalData[2].value).toBe(3.0);
113
+ });
114
+ });
115
+
116
+ describe('ConfigureChartPanel', () => {
117
+ const defaultModel = {
118
+ chartType: 'bar',
119
+ range: { min: 0, max: 10, step: 1, labelStep: 1 },
120
+ graph: { width: 400, height: 500 },
121
+ data: [{ value: 5 }],
122
+ correctAnswer: { data: [{ value: 3 }] },
123
+ changeInteractiveEnabled: true,
124
+ changeEditableEnabled: true,
125
+ };
126
+
127
+ const defaultProps = {
128
+ model: defaultModel,
129
+ onChange: jest.fn(),
130
+ chartDimensions: {
131
+ showInConfigPanel: true,
132
+ width: { min: 50, max: 700, step: 20 },
133
+ height: { min: 400, max: 700, step: 20 },
134
+ },
135
+ gridValues: { range: { min: 0, max: 10000 } },
136
+ labelValues: { range: { min: 0, max: 10000 } },
137
+ studentNewCategoryDefaultLabel: { label: 'Category' },
138
+ availableChartTypes: {},
139
+ chartTypeLabel: 'Chart Type',
140
+ };
141
+
142
+ beforeEach(() => {
143
+ jest.clearAllMocks();
144
+ });
145
+
146
+ const renderComponent = (extras = {}) => {
147
+ const props = { ...defaultProps, ...extras };
148
+ return render(
149
+ <ThemeProvider theme={theme}>
150
+ <ConfigureChartPanel {...props} />
151
+ </ThemeProvider>,
152
+ );
153
+ };
154
+
155
+ describe('rendering', () => {
156
+ it('should render without crashing', () => {
157
+ const { container } = renderComponent();
158
+ expect(container).toBeInTheDocument();
159
+ });
160
+
161
+ it('should render "Configure Chart" title', () => {
162
+ const { getByText } = renderComponent();
163
+ expect(getByText('Configure Chart')).toBeInTheDocument();
164
+ });
165
+
166
+ it('should render chart type selector', () => {
167
+ const { getByTestId } = renderComponent();
168
+ expect(getByTestId('chart-type-select')).toBeInTheDocument();
169
+ });
170
+
171
+ it('should render max value field', () => {
172
+ const { getByLabelText } = renderComponent();
173
+ expect(getByLabelText('Max Value')).toBeInTheDocument();
174
+ });
175
+
176
+ it('should render grid interval field for non-plot charts', () => {
177
+ const { getByLabelText } = renderComponent({
178
+ model: { ...defaultModel, chartType: 'bar' },
179
+ });
180
+ expect(getByLabelText('Grid Interval')).toBeInTheDocument();
181
+ });
182
+
183
+ it('should render label interval field for non-plot charts', () => {
184
+ const { getByLabelText } = renderComponent({
185
+ model: { ...defaultModel, chartType: 'bar' },
186
+ });
187
+ expect(getByLabelText('Label Interval')).toBeInTheDocument();
188
+ });
189
+
190
+ it('should not render step config for plot charts', () => {
191
+ const { queryByLabelText } = renderComponent({
192
+ model: { ...defaultModel, chartType: 'linePlot' },
193
+ });
194
+ expect(queryByLabelText('Grid Interval')).not.toBeInTheDocument();
195
+ expect(queryByLabelText('Label Interval')).not.toBeInTheDocument();
196
+ });
197
+
198
+ it('should render dimensions section when showInConfigPanel is true', () => {
199
+ const { getByText } = renderComponent({
200
+ chartDimensions: {
201
+ showInConfigPanel: true,
202
+ width: { min: 50, max: 700, step: 20 },
203
+ height: { min: 400, max: 700, step: 20 },
204
+ },
205
+ });
206
+ expect(getByText('Dimensions(px)')).toBeInTheDocument();
207
+ });
208
+
209
+ it('should not render dimensions section when showInConfigPanel is false', () => {
210
+ const { queryByText } = renderComponent({
211
+ chartDimensions: {
212
+ showInConfigPanel: false,
213
+ width: { min: 50, max: 700, step: 20 },
214
+ height: { min: 400, max: 700, step: 20 },
215
+ },
216
+ });
217
+ expect(queryByText('Dimensions(px)')).not.toBeInTheDocument();
218
+ });
219
+
220
+ it('should render width field when dimensions are shown', () => {
221
+ const { getByLabelText } = renderComponent();
222
+ expect(getByLabelText('Width')).toBeInTheDocument();
223
+ });
224
+
225
+ it('should render height field when dimensions are shown', () => {
226
+ const { getByLabelText } = renderComponent();
227
+ expect(getByLabelText('Height')).toBeInTheDocument();
228
+ });
229
+
230
+ it('should display width constraints', () => {
231
+ const { getByText } = renderComponent();
232
+ expect(getByText('Min 50, Max 700')).toBeInTheDocument();
233
+ });
234
+
235
+ it('should display height constraints', () => {
236
+ const { getAllByText } = renderComponent();
237
+ const constraints = getAllByText('Min 400, Max 700');
238
+ expect(constraints.length).toBeGreaterThan(0);
239
+ });
240
+ });
241
+
242
+ describe('chart type changes', () => {
243
+ it('should call onChange when chart type is changed to non-plot', () => {
244
+ const onChange = jest.fn();
245
+ const { getByTestId } = renderComponent({ onChange });
246
+
247
+ fireEvent.change(getByTestId('chart-type-select'), { target: { value: 'line' } });
248
+
249
+ expect(onChange).toHaveBeenCalled();
250
+ });
251
+
252
+ it('should show warning when switching to plot with invalid config', async () => {
253
+ const { getByTestId, getByText } = renderComponent({
254
+ model: { ...defaultModel, range: { max: 20, step: 2, labelStep: 2 } },
255
+ });
256
+
257
+ fireEvent.change(getByTestId('chart-type-select'), { target: { value: 'linePlot' } });
258
+
259
+ await waitFor(() => {
260
+ expect(getByText('Warning')).toBeInTheDocument();
261
+ });
262
+ });
263
+
264
+ it('should allow switching to plot with valid config', () => {
265
+ const onChange = jest.fn();
266
+ const { getByTestId } = renderComponent({
267
+ onChange,
268
+ model: { ...defaultModel, range: { max: 10, step: 1, labelStep: 1 } },
269
+ });
270
+
271
+ fireEvent.change(getByTestId('chart-type-select'), { target: { value: 'dotPlot' } });
272
+
273
+ expect(onChange).toHaveBeenCalledWith(
274
+ expect.objectContaining({
275
+ chartType: 'dotPlot',
276
+ }),
277
+ );
278
+ });
279
+ });
280
+
281
+ describe('range changes', () => {
282
+ it('should update max value', () => {
283
+ const onChange = jest.fn();
284
+ const { getByLabelText } = renderComponent({ onChange });
285
+
286
+ const maxInput = getByLabelText('Max Value');
287
+ fireEvent.change(maxInput, { target: { value: '15' } });
288
+
289
+ expect(onChange).toHaveBeenCalled();
290
+ });
291
+
292
+ it('should update step value', () => {
293
+ const onChange = jest.fn();
294
+ const { getByLabelText } = renderComponent({ onChange });
295
+
296
+ const stepInput = getByLabelText('Grid Interval');
297
+ fireEvent.change(stepInput, { target: { value: '2' } });
298
+
299
+ expect(onChange).toHaveBeenCalled();
300
+ });
301
+
302
+ it('should update label step value', () => {
303
+ const onChange = jest.fn();
304
+ const { getByLabelText } = renderComponent({ onChange });
305
+
306
+ const labelStepInput = getByLabelText('Label Interval');
307
+ fireEvent.change(labelStepInput, { target: { value: '2' } });
308
+
309
+ expect(onChange).toHaveBeenCalled();
310
+ });
311
+
312
+ it('should show alert when changing max causes data to be out of range', async () => {
313
+ const onChange = jest.fn();
314
+ const { getByLabelText, queryByTestId } = renderComponent({
315
+ onChange,
316
+ model: {
317
+ ...defaultModel,
318
+ range: { min: 0, max: 10, step: 1, labelStep: 1 },
319
+ data: [{ value: 8 }],
320
+ correctAnswer: { data: [] },
321
+ },
322
+ });
323
+
324
+ const maxInput = getByLabelText('Max Value');
325
+ fireEvent.change(maxInput, { target: { value: '5' } });
326
+
327
+ await waitFor(() => {
328
+ expect(onChange).toHaveBeenCalled();
329
+ });
330
+ });
331
+
332
+ it('should show alert when changing step causes data to be out of range', async () => {
333
+ const onChange = jest.fn();
334
+ const { getByLabelText } = renderComponent({
335
+ onChange,
336
+ model: {
337
+ ...defaultModel,
338
+ range: { min: 0, max: 10, step: 1, labelStep: 1 },
339
+ data: [{ value: 5 }],
340
+ correctAnswer: { data: [] },
341
+ },
342
+ });
343
+
344
+ const stepInput = getByLabelText('Grid Interval');
345
+ fireEvent.change(stepInput, { target: { value: '3' } });
346
+
347
+ await waitFor(() => {
348
+ expect(onChange).toHaveBeenCalled();
349
+ });
350
+ });
351
+ });
352
+
353
+ describe('dimensions changes', () => {
354
+ it('should update width', () => {
355
+ const onChange = jest.fn();
356
+ const { getByLabelText } = renderComponent({ onChange });
357
+
358
+ const widthInput = getByLabelText('Width');
359
+ fireEvent.change(widthInput, { target: { value: '500' } });
360
+
361
+ expect(onChange).toHaveBeenCalledWith(
362
+ expect.objectContaining({
363
+ graph: expect.objectContaining({ width: 500 }),
364
+ }),
365
+ );
366
+ });
367
+
368
+ it('should update height', () => {
369
+ const onChange = jest.fn();
370
+ const { getByLabelText } = renderComponent({ onChange });
371
+
372
+ const heightInput = getByLabelText('Height');
373
+ fireEvent.change(heightInput, { target: { value: '600' } });
374
+
375
+ expect(onChange).toHaveBeenCalledWith(
376
+ expect.objectContaining({
377
+ graph: expect.objectContaining({ height: 600 }),
378
+ }),
379
+ );
380
+ });
381
+ });
382
+
383
+ describe('alert dialog', () => {
384
+ it('should reset range on cancel', async () => {
385
+ const onChange = jest.fn();
386
+ const { getByLabelText, queryByTestId } = renderComponent({
387
+ onChange,
388
+ model: {
389
+ ...defaultModel,
390
+ range: { min: 0, max: 10, step: 1, labelStep: 1 },
391
+ data: [{ value: 8 }],
392
+ correctAnswer: { data: [] },
393
+ },
394
+ });
395
+
396
+ const maxInput = getByLabelText('Max Value');
397
+
398
+ const event = { target: maxInput };
399
+ fireEvent.change(maxInput, { target: { value: '5' } });
400
+
401
+ await waitFor(
402
+ () => {
403
+ const dialog = queryByTestId('alert-dialog');
404
+ if (dialog) {
405
+ fireEvent.click(queryByTestId('alert-cancel'));
406
+ }
407
+ },
408
+ { timeout: 100 },
409
+ ).catch(() => {});
410
+
411
+ expect(onChange).toHaveBeenCalled();
412
+ });
413
+
414
+ it('should apply changes and reset data on confirm', async () => {
415
+ const onChange = jest.fn();
416
+ const { getByLabelText, queryByTestId } = renderComponent({
417
+ onChange,
418
+ model: {
419
+ ...defaultModel,
420
+ range: { min: 0, max: 10, step: 1, labelStep: 1 },
421
+ data: [{ value: 8 }],
422
+ correctAnswer: { data: [] },
423
+ },
424
+ });
425
+
426
+ const maxInput = getByLabelText('Max Value');
427
+ fireEvent.change(maxInput, { target: { value: '5' } });
428
+
429
+ await waitFor(
430
+ () => {
431
+ const dialog = queryByTestId('alert-dialog');
432
+ if (dialog) {
433
+ fireEvent.click(queryByTestId('alert-confirm'));
434
+ }
435
+ },
436
+ { timeout: 100 },
437
+ ).catch(() => {});
438
+
439
+ expect(onChange).toHaveBeenCalled();
440
+ });
441
+ });
442
+
443
+ describe('edge cases', () => {
444
+ it('should handle missing chartDimensions', () => {
445
+ const { container } = renderComponent({ chartDimensions: undefined });
446
+ expect(container).toBeInTheDocument();
447
+ });
448
+
449
+ it('should handle missing gridValues', () => {
450
+ const { container } = renderComponent({ gridValues: undefined });
451
+ expect(container).toBeInTheDocument();
452
+ });
453
+
454
+ it('should handle missing labelValues', () => {
455
+ const { container } = renderComponent({ labelValues: undefined });
456
+ expect(container).toBeInTheDocument();
457
+ });
458
+
459
+ it('should handle empty model data', () => {
460
+ const { container } = renderComponent({
461
+ model: {
462
+ ...defaultModel,
463
+ data: [],
464
+ correctAnswer: { data: [] },
465
+ },
466
+ });
467
+ expect(container).toBeInTheDocument();
468
+ });
469
+
470
+ it('should handle empty range object', () => {
471
+ const { container } = renderComponent({
472
+ model: {
473
+ ...defaultModel,
474
+ range: {},
475
+ },
476
+ });
477
+ expect(container).toBeInTheDocument();
478
+ });
479
+
480
+ it('should apply width constraints correctly', () => {
481
+ const { container } = renderComponent({
482
+ chartDimensions: {
483
+ showInConfigPanel: true,
484
+ width: { min: 100, max: 600, step: 50 },
485
+ height: { min: 400, max: 700, step: 20 },
486
+ },
487
+ });
488
+ expect(container).toBeInTheDocument();
489
+ });
490
+
491
+ it('should apply height constraints correctly', () => {
492
+ const { container } = renderComponent({
493
+ chartDimensions: {
494
+ showInConfigPanel: true,
495
+ width: { min: 50, max: 700, step: 20 },
496
+ height: { min: 450, max: 650, step: 30 },
497
+ },
498
+ });
499
+ expect(container).toBeInTheDocument();
500
+ });
501
+
502
+ it('should handle very small step values', () => {
503
+ const { container } = renderComponent({
504
+ chartDimensions: {
505
+ showInConfigPanel: true,
506
+ width: { min: 50, max: 700, step: 0.5 },
507
+ height: { min: 400, max: 700, step: 0.5 },
508
+ },
509
+ });
510
+ expect(container).toBeInTheDocument();
511
+ });
512
+ });
513
+
514
+ describe('useEffect lifecycle', () => {
515
+ it('should call onChange on mount', () => {
516
+ const onChange = jest.fn();
517
+ renderComponent({ onChange });
518
+
519
+ expect(onChange).toHaveBeenCalled();
520
+ });
521
+
522
+ it('should set category default label on mount', () => {
523
+ const onChange = jest.fn();
524
+ renderComponent({
525
+ onChange,
526
+ studentNewCategoryDefaultLabel: { label: 'Test Category' },
527
+ });
528
+
529
+ expect(onChange).toHaveBeenCalled();
530
+ });
531
+ });
532
+ });
@@ -0,0 +1,23 @@
1
+ import React from 'react';
2
+ import { render } from '@pie-lib/test-utils';
3
+ import ChartType from '../chart-type';
4
+
5
+ describe('ChartType', () => {
6
+ let props;
7
+ const onChange = jest.fn();
8
+
9
+ beforeEach(() => {
10
+ props = {
11
+ classes: {},
12
+ value: 'bar',
13
+ onChange,
14
+ };
15
+ });
16
+
17
+ describe('rendering', () => {
18
+ it('renders chart type selector', () => {
19
+ const { container } = render(<ChartType {...props} />);
20
+ expect(container.firstChild).toBeInTheDocument();
21
+ });
22
+ });
23
+ });
@@ -0,0 +1,86 @@
1
+ import React from 'react';
2
+ import { render } from '@pie-lib/test-utils';
3
+ import { Chart } from '../chart';
4
+ import { createBandScale, graphProps } from './utils';
5
+
6
+ describe('ChartAxes', () => {
7
+ let onDataChange = jest.fn();
8
+
9
+ const renderComponent = (extras) => {
10
+ const defaults = {
11
+ classes: {},
12
+ onDataChange,
13
+ className: 'className',
14
+ graphProps: graphProps(),
15
+ xBand: createBandScale(['a', 'b', 'c'], [0, 100]),
16
+ charts: [
17
+ {
18
+ type: 'bar',
19
+ Component: () => <div />,
20
+ },
21
+ ],
22
+ chartType: 'bar',
23
+ domain: {},
24
+ range: {
25
+ min: 0,
26
+ max: 10,
27
+ },
28
+ size: {
29
+ width: 100,
30
+ height: 100,
31
+ },
32
+ data: [],
33
+ };
34
+ const props = { ...defaults, ...extras };
35
+ return render(<Chart {...props} />);
36
+ };
37
+
38
+ describe('rendering', () => {
39
+ it('renders chart container', () => {
40
+ const { container } = renderComponent();
41
+ expect(container.firstChild).toBeInTheDocument();
42
+ expect(container.querySelector('svg')).toBeInTheDocument();
43
+ });
44
+
45
+ it('renders chart with default size', () => {
46
+ const { container } = renderComponent();
47
+ const svg = container.querySelector('svg');
48
+ expect(svg).toBeInTheDocument();
49
+ expect(svg).toHaveAttribute('width', '240');
50
+ expect(svg).toHaveAttribute('height', '240');
51
+ });
52
+
53
+ it('renders chart when size is not defined', () => {
54
+ const { container } = renderComponent({ size: undefined });
55
+ expect(container.firstChild).toBeInTheDocument();
56
+ const svg = container.querySelector('svg');
57
+ expect(svg).toBeInTheDocument();
58
+ });
59
+
60
+ it('renders chart without chartType property', () => {
61
+ const { container } = renderComponent({ chartType: null });
62
+ expect(container.firstChild).toBeInTheDocument();
63
+ expect(container.querySelector('svg')).toBeInTheDocument();
64
+ });
65
+
66
+ it('renders chart without chartType and charts properties', () => {
67
+ const { container } = renderComponent({ chartType: null, charts: null });
68
+ expect(container.firstChild).toBeInTheDocument();
69
+ });
70
+
71
+ it('renders chart without chartType property and empty charts property', () => {
72
+ const { container } = renderComponent({ chartType: null, charts: [] });
73
+ expect(container.firstChild).toBeInTheDocument();
74
+ });
75
+
76
+ it('renders chart with chartType property and empty charts property', () => {
77
+ const { container } = renderComponent({ charts: [] });
78
+ expect(container.firstChild).toBeInTheDocument();
79
+ expect(container.querySelector('svg')).toBeInTheDocument();
80
+ });
81
+ });
82
+
83
+ // Note: changeData, getChart, and deleteCategory are internal implementation details.
84
+ // In RTL philosophy, we test user-visible behavior rather than implementation.
85
+ // These methods would be tested indirectly through user interactions that trigger them.
86
+ });
@@ -0,0 +1,37 @@
1
+ import React from 'react';
2
+ import { render } from '@pie-lib/test-utils';
3
+ import { Grid } from '../grid';
4
+ import { createBandScale, graphProps } from './utils';
5
+
6
+ describe('Grid', () => {
7
+ const renderComponent = (extras) => {
8
+ const defaults = {
9
+ classes: {},
10
+ className: 'className',
11
+ graphProps: graphProps(),
12
+ xBand: createBandScale(['a', 'b', 'c'], [0, 400]),
13
+ };
14
+ const props = { ...defaults, ...extras };
15
+ return render(
16
+ <svg>
17
+ <Grid {...props} />
18
+ </svg>,
19
+ );
20
+ };
21
+
22
+ describe('rendering', () => {
23
+ it('renders grid container', () => {
24
+ const { container } = renderComponent();
25
+ expect(container.firstChild).toBeInTheDocument();
26
+ });
27
+
28
+ it('renders grid with SVG group', () => {
29
+ const { container } = renderComponent();
30
+ const svg = container.querySelector('svg');
31
+ expect(svg).toBeInTheDocument();
32
+ // Grid renders a <g> element (StyledGridGroup)
33
+ const gridGroup = container.querySelector('g');
34
+ expect(gridGroup).toBeInTheDocument();
35
+ });
36
+ });
37
+ });