@pie-lib/graphing-solution-set 3.1.1-next.0 → 3.2.0-next.0

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 (124) hide show
  1. package/lib/axis/arrow.js +0 -3
  2. package/lib/axis/arrow.js.map +1 -1
  3. package/lib/axis/axes.js +0 -16
  4. package/lib/axis/axes.js.map +1 -1
  5. package/lib/axis/index.js +0 -7
  6. package/lib/axis/index.js.map +1 -1
  7. package/lib/bg.js +0 -6
  8. package/lib/bg.js.map +1 -1
  9. package/lib/container/actions.js +0 -1
  10. package/lib/container/actions.js.map +1 -1
  11. package/lib/container/index.js +4 -10
  12. package/lib/container/index.js.map +1 -1
  13. package/lib/container/marks.js +0 -2
  14. package/lib/container/marks.js.map +1 -1
  15. package/lib/container/middleware.js +0 -1
  16. package/lib/container/middleware.js.map +1 -1
  17. package/lib/container/reducer.js +0 -1
  18. package/lib/container/reducer.js.map +1 -1
  19. package/lib/coordinates-label.js +0 -11
  20. package/lib/coordinates-label.js.map +1 -1
  21. package/lib/graph-with-controls.js +3 -22
  22. package/lib/graph-with-controls.js.map +1 -1
  23. package/lib/graph.js +7 -26
  24. package/lib/graph.js.map +1 -1
  25. package/lib/grid-setup.js +0 -11
  26. package/lib/grid-setup.js.map +1 -1
  27. package/lib/grid.js +0 -22
  28. package/lib/grid.js.map +1 -1
  29. package/lib/index.js +0 -7
  30. package/lib/index.js.map +1 -1
  31. package/lib/labels.js +0 -13
  32. package/lib/labels.js.map +1 -1
  33. package/lib/mark-label.js +0 -16
  34. package/lib/mark-label.js.map +1 -1
  35. package/lib/toggle-bar.js +0 -17
  36. package/lib/toggle-bar.js.map +1 -1
  37. package/lib/tool-menu.js +0 -3
  38. package/lib/tool-menu.js.map +1 -1
  39. package/lib/tools/index.js +0 -1
  40. package/lib/tools/index.js.map +1 -1
  41. package/lib/tools/line/component.js +0 -13
  42. package/lib/tools/line/component.js.map +1 -1
  43. package/lib/tools/line/index.js +0 -1
  44. package/lib/tools/line/index.js.map +1 -1
  45. package/lib/tools/polygon/component.js +5 -25
  46. package/lib/tools/polygon/component.js.map +1 -1
  47. package/lib/tools/polygon/index.js +0 -12
  48. package/lib/tools/polygon/index.js.map +1 -1
  49. package/lib/tools/polygon/line.js +0 -16
  50. package/lib/tools/polygon/line.js.map +1 -1
  51. package/lib/tools/polygon/polygon.js +0 -19
  52. package/lib/tools/polygon/polygon.js.map +1 -1
  53. package/lib/tools/shared/arrow-head.js +0 -3
  54. package/lib/tools/shared/arrow-head.js.map +1 -1
  55. package/lib/tools/shared/line/index.js +7 -22
  56. package/lib/tools/shared/line/index.js.map +1 -1
  57. package/lib/tools/shared/line/line-path.js +0 -16
  58. package/lib/tools/shared/line/line-path.js.map +1 -1
  59. package/lib/tools/shared/line/with-root-edge.js +0 -11
  60. package/lib/tools/shared/line/with-root-edge.js.map +1 -1
  61. package/lib/tools/shared/point/arrow-point.js +2 -5
  62. package/lib/tools/shared/point/arrow-point.js.map +1 -1
  63. package/lib/tools/shared/point/arrow.js +0 -3
  64. package/lib/tools/shared/point/arrow.js.map +1 -1
  65. package/lib/tools/shared/point/base-point.js +0 -11
  66. package/lib/tools/shared/point/base-point.js.map +1 -1
  67. package/lib/tools/shared/point/index.js +0 -16
  68. package/lib/tools/shared/point/index.js.map +1 -1
  69. package/lib/tools/shared/styles.js +0 -1
  70. package/lib/tools/shared/styles.js.map +1 -1
  71. package/lib/tools/shared/types.js +0 -1
  72. package/lib/tools/shared/types.js.map +1 -1
  73. package/lib/undo-redo.js +0 -2
  74. package/lib/undo-redo.js.map +1 -1
  75. package/lib/use-debounce.js +0 -2
  76. package/lib/use-debounce.js.map +1 -1
  77. package/lib/utils.js +8 -26
  78. package/lib/utils.js.map +1 -1
  79. package/package.json +14 -11
  80. package/src/__tests__/bg.test.jsx +250 -0
  81. package/src/__tests__/coordinates-label.test.jsx +243 -0
  82. package/src/__tests__/graph-with-controls.test.jsx +9 -10
  83. package/src/__tests__/graph.test.jsx +0 -2
  84. package/src/__tests__/grid-setup.test.jsx +645 -0
  85. package/src/__tests__/mark-label.test.jsx +1 -1
  86. package/src/__tests__/tool-menu.test.jsx +422 -2
  87. package/src/__tests__/use-debounce.test.js +1 -1
  88. package/src/__tests__/utils.test.js +15 -61
  89. package/src/axis/__tests__/axes.test.jsx +1 -1
  90. package/src/axis/axes.jsx +7 -21
  91. package/src/axis/index.js +1 -0
  92. package/src/bg.jsx +1 -1
  93. package/src/container/__tests__/actions.test.js +105 -0
  94. package/src/container/__tests__/index.test.jsx +227 -0
  95. package/src/container/__tests__/marks.test.js +172 -0
  96. package/src/container/__tests__/middleware.test.js +235 -0
  97. package/src/container/__tests__/reducer.test.js +324 -0
  98. package/src/container/index.jsx +3 -4
  99. package/src/coordinates-label.jsx +1 -7
  100. package/src/graph-with-controls.jsx +7 -25
  101. package/src/graph.jsx +3 -4
  102. package/src/grid-setup.jsx +1 -1
  103. package/src/mark-label.jsx +2 -2
  104. package/src/toggle-bar.jsx +8 -1
  105. package/src/tool-menu.jsx +1 -1
  106. package/src/tools/line/__tests__/component.test.jsx +1 -0
  107. package/src/tools/line/component.jsx +2 -2
  108. package/src/tools/polygon/__tests__/component.test.jsx +417 -5
  109. package/src/tools/polygon/__tests__/polygon.test.jsx +1 -1
  110. package/src/tools/polygon/component.jsx +4 -14
  111. package/src/tools/polygon/line.jsx +1 -1
  112. package/src/tools/shared/line/__tests__/index.test.jsx +460 -17
  113. package/src/tools/shared/line/__tests__/line-path.test.jsx +7 -4
  114. package/src/tools/shared/line/__tests__/with-root-edge.test.jsx +439 -14
  115. package/src/tools/shared/line/index.jsx +4 -6
  116. package/src/tools/shared/line/line-path.jsx +2 -8
  117. package/src/tools/shared/point/__tests__/arrow.test.jsx +469 -0
  118. package/src/tools/shared/point/arrow-point.jsx +2 -2
  119. package/src/tools/shared/point/base-point.jsx +1 -1
  120. package/src/tools/shared/point/index.jsx +1 -1
  121. package/src/undo-redo.jsx +1 -3
  122. package/src/use-debounce.js +1 -1
  123. package/src/utils.js +1 -5
  124. package/NEXT.CHANGELOG.json +0 -16
@@ -1,12 +1,16 @@
1
- import { render } from '@pie-lib/test-utils';
1
+ import { fireEvent, render } from '@pie-lib/test-utils';
2
2
  import React from 'react';
3
3
 
4
4
  import ToolMenu from '../tool-menu';
5
5
 
6
6
  describe('ToolMenu', () => {
7
- let onChange = jest.fn();
7
+ let onChange;
8
8
  const tools = ['one', 'two'];
9
9
 
10
+ beforeEach(() => {
11
+ onChange = jest.fn();
12
+ });
13
+
10
14
  const renderComponent = (extras) => {
11
15
  const defaults = {
12
16
  classes: {},
@@ -16,6 +20,7 @@ describe('ToolMenu', () => {
16
20
  tools,
17
21
  gssLineData: {
18
22
  selectedTool: 'lineA',
23
+ numberOfLines: 2,
19
24
  lineA: { lineType: 'Solid' },
20
25
  lineB: { lineType: 'Solid' },
21
26
  },
@@ -29,5 +34,420 @@ describe('ToolMenu', () => {
29
34
  const { container } = renderComponent();
30
35
  expect(container.firstChild).toBeInTheDocument();
31
36
  });
37
+
38
+ it('renders Line A radio button', () => {
39
+ const { getByText } = renderComponent();
40
+ expect(getByText('Line A')).toBeInTheDocument();
41
+ });
42
+
43
+ it('renders Line B radio button when numberOfLines is 2', () => {
44
+ const { getByText } = renderComponent();
45
+ expect(getByText('Line B')).toBeInTheDocument();
46
+ });
47
+
48
+ it('does not render Line B radio button when numberOfLines is 1', () => {
49
+ const { queryByText } = renderComponent({
50
+ gssLineData: {
51
+ selectedTool: 'lineA',
52
+ numberOfLines: 1,
53
+ lineA: { lineType: 'Solid' },
54
+ lineB: { lineType: 'Solid' },
55
+ },
56
+ });
57
+ expect(queryByText('Line B')).not.toBeInTheDocument();
58
+ });
59
+
60
+ it('renders Solution Set radio button', () => {
61
+ const { getByText } = renderComponent();
62
+ expect(getByText('Solution Set')).toBeInTheDocument();
63
+ });
64
+
65
+ it('renders Solid and Dashed buttons for Line A', () => {
66
+ const { getAllByText } = renderComponent();
67
+ const solidButtons = getAllByText(/Solid/);
68
+ const dashedButtons = getAllByText(/Dashed/);
69
+ expect(solidButtons.length).toBeGreaterThan(0);
70
+ expect(dashedButtons.length).toBeGreaterThan(0);
71
+ });
72
+
73
+ it('shows checkmark on selected line type for Line A', () => {
74
+ const { getAllByText } = renderComponent({
75
+ gssLineData: {
76
+ selectedTool: 'lineA',
77
+ numberOfLines: 2,
78
+ lineA: { lineType: 'Solid' },
79
+ lineB: { lineType: 'Dashed' },
80
+ },
81
+ });
82
+ const solidButtons = getAllByText(/✔ Solid/);
83
+ expect(solidButtons.length).toBeGreaterThan(0);
84
+ });
85
+
86
+ it('disables all controls when disabled prop is true', () => {
87
+ const { getAllByRole } = renderComponent({ disabled: true });
88
+ const radios = getAllByRole('radio');
89
+ const buttons = getAllByRole('button');
90
+
91
+ radios.forEach((radio) => {
92
+ expect(radio).toBeDisabled();
93
+ });
94
+
95
+ buttons.forEach((button) => {
96
+ expect(button).toBeDisabled();
97
+ });
98
+ });
99
+ });
100
+
101
+ describe('onChangeRadioValue', () => {
102
+ it('calls onChange with updated selectedTool when lineA radio is clicked', () => {
103
+ const { getAllByRole } = renderComponent({
104
+ gssLineData: {
105
+ selectedTool: 'solutionSet',
106
+ numberOfLines: 2,
107
+ lineA: { lineType: 'Solid' },
108
+ lineB: { lineType: 'Solid' },
109
+ },
110
+ });
111
+
112
+ const radios = getAllByRole('radio');
113
+ const lineARadio = radios.find((r) => r.value === 'lineA');
114
+
115
+ fireEvent.click(lineARadio);
116
+
117
+ expect(onChange).toHaveBeenCalledTimes(1);
118
+ const [updatedData, oldSelectedTool] = onChange.mock.calls[0];
119
+ expect(updatedData.selectedTool).toBe('lineA');
120
+ expect(oldSelectedTool).toBe('solutionSet');
121
+ });
122
+
123
+ it('calls onChange with updated selectedTool when lineB radio is clicked', () => {
124
+ const { getAllByRole } = renderComponent({
125
+ gssLineData: {
126
+ selectedTool: 'lineA',
127
+ numberOfLines: 2,
128
+ lineA: { lineType: 'Solid' },
129
+ lineB: { lineType: 'Solid' },
130
+ },
131
+ });
132
+
133
+ const radios = getAllByRole('radio');
134
+ const lineBRadio = radios.find((r) => r.value === 'lineB');
135
+
136
+ fireEvent.click(lineBRadio);
137
+
138
+ expect(onChange).toHaveBeenCalledTimes(1);
139
+ const [updatedData, oldSelectedTool] = onChange.mock.calls[0];
140
+ expect(updatedData.selectedTool).toBe('lineB');
141
+ expect(oldSelectedTool).toBe('lineA');
142
+ });
143
+
144
+ it('calls onChange with updated selectedTool when solutionSet radio is clicked', () => {
145
+ const { getAllByRole } = renderComponent({
146
+ gssLineData: {
147
+ selectedTool: 'lineA',
148
+ numberOfLines: 2,
149
+ lineA: { lineType: 'Solid' },
150
+ lineB: { lineType: 'Solid' },
151
+ },
152
+ });
153
+
154
+ const radios = getAllByRole('radio');
155
+ const solutionSetRadio = radios.find((r) => r.value === 'solutionSet');
156
+
157
+ fireEvent.click(solutionSetRadio);
158
+
159
+ expect(onChange).toHaveBeenCalledTimes(1);
160
+ const [updatedData, oldSelectedTool] = onChange.mock.calls[0];
161
+ expect(updatedData.selectedTool).toBe('solutionSet');
162
+ expect(oldSelectedTool).toBe('lineA');
163
+ });
164
+
165
+ it('preserves other gssLineData properties when changing selectedTool', () => {
166
+ const { getAllByRole } = renderComponent({
167
+ gssLineData: {
168
+ selectedTool: 'lineA',
169
+ numberOfLines: 2,
170
+ lineA: { lineType: 'Dashed' },
171
+ lineB: { lineType: 'Solid' },
172
+ },
173
+ });
174
+
175
+ const radios = getAllByRole('radio');
176
+ const lineBRadio = radios.find((r) => r.value === 'lineB');
177
+
178
+ fireEvent.click(lineBRadio);
179
+
180
+ const [updatedData] = onChange.mock.calls[0];
181
+ expect(updatedData.lineA.lineType).toBe('Dashed');
182
+ expect(updatedData.lineB.lineType).toBe('Solid');
183
+ expect(updatedData.numberOfLines).toBe(2);
184
+ });
185
+
186
+ it('does not call onChange when disabled', () => {
187
+ const { getAllByRole } = renderComponent({
188
+ disabled: true,
189
+ gssLineData: {
190
+ selectedTool: 'lineA',
191
+ numberOfLines: 2,
192
+ lineA: { lineType: 'Solid' },
193
+ lineB: { lineType: 'Solid' },
194
+ },
195
+ });
196
+
197
+ const radios = getAllByRole('radio');
198
+ const lineBRadio = radios.find((r) => r.value === 'lineB');
199
+
200
+ // Disabled radios should not fire change events
201
+ expect(lineBRadio).toBeDisabled();
202
+ });
203
+ });
204
+
205
+ describe('lineTypeChange', () => {
206
+ it('calls onChange with updated lineType for Line A when Solid button is clicked', () => {
207
+ const { getAllByText } = renderComponent({
208
+ gssLineData: {
209
+ selectedTool: 'lineA',
210
+ numberOfLines: 2,
211
+ lineA: { lineType: 'Dashed' },
212
+ lineB: { lineType: 'Solid' },
213
+ },
214
+ });
215
+
216
+ const solidButtons = getAllByText(/Solid/);
217
+ // First solid button should be for Line A
218
+ fireEvent.click(solidButtons[0]);
219
+
220
+ expect(onChange).toHaveBeenCalledTimes(1);
221
+ const [updatedData, oldSelectedTool] = onChange.mock.calls[0];
222
+ expect(updatedData.lineA.lineType).toBe('Solid');
223
+ expect(oldSelectedTool).toBe('lineA');
224
+ });
225
+
226
+ it('calls onChange with updated lineType for Line A when Dashed button is clicked', () => {
227
+ const { getAllByText } = renderComponent({
228
+ gssLineData: {
229
+ selectedTool: 'lineA',
230
+ numberOfLines: 2,
231
+ lineA: { lineType: 'Solid' },
232
+ lineB: { lineType: 'Solid' },
233
+ },
234
+ });
235
+
236
+ const dashedButtons = getAllByText(/Dashed/);
237
+ // First dashed button should be for Line A
238
+ fireEvent.click(dashedButtons[0]);
239
+
240
+ expect(onChange).toHaveBeenCalledTimes(1);
241
+ const [updatedData, oldSelectedTool] = onChange.mock.calls[0];
242
+ expect(updatedData.lineA.lineType).toBe('Dashed');
243
+ expect(oldSelectedTool).toBe('lineA');
244
+ });
245
+
246
+ it('calls onChange with updated lineType for Line B when Solid button is clicked', () => {
247
+ const { getAllByText } = renderComponent({
248
+ gssLineData: {
249
+ selectedTool: 'lineB',
250
+ numberOfLines: 2,
251
+ lineA: { lineType: 'Solid' },
252
+ lineB: { lineType: 'Dashed' },
253
+ },
254
+ });
255
+
256
+ const solidButtons = getAllByText(/Solid/);
257
+ // Second solid button should be for Line B
258
+ fireEvent.click(solidButtons[1]);
259
+
260
+ expect(onChange).toHaveBeenCalledTimes(1);
261
+ const [updatedData, oldSelectedTool] = onChange.mock.calls[0];
262
+ expect(updatedData.lineB.lineType).toBe('Solid');
263
+ expect(oldSelectedTool).toBe('lineB');
264
+ });
265
+
266
+ it('calls onChange with updated lineType for Line B when Dashed button is clicked', () => {
267
+ const { getAllByText } = renderComponent({
268
+ gssLineData: {
269
+ selectedTool: 'lineB',
270
+ numberOfLines: 2,
271
+ lineA: { lineType: 'Solid' },
272
+ lineB: { lineType: 'Solid' },
273
+ },
274
+ });
275
+
276
+ const dashedButtons = getAllByText(/Dashed/);
277
+ // Second dashed button should be for Line B
278
+ fireEvent.click(dashedButtons[1]);
279
+
280
+ expect(onChange).toHaveBeenCalledTimes(1);
281
+ const [updatedData, oldSelectedTool] = onChange.mock.calls[0];
282
+ expect(updatedData.lineB.lineType).toBe('Dashed');
283
+ expect(oldSelectedTool).toBe('lineB');
284
+ });
285
+
286
+ it('preserves other line properties when changing Line A lineType', () => {
287
+ const { getAllByText } = renderComponent({
288
+ gssLineData: {
289
+ selectedTool: 'lineA',
290
+ numberOfLines: 2,
291
+ lineA: { lineType: 'Solid' },
292
+ lineB: { lineType: 'Dashed' },
293
+ },
294
+ });
295
+
296
+ const dashedButtons = getAllByText(/Dashed/);
297
+ fireEvent.click(dashedButtons[0]);
298
+
299
+ const [updatedData] = onChange.mock.calls[0];
300
+ expect(updatedData.lineA.lineType).toBe('Dashed');
301
+ expect(updatedData.lineB.lineType).toBe('Dashed');
302
+ expect(updatedData.selectedTool).toBe('lineA');
303
+ expect(updatedData.numberOfLines).toBe(2);
304
+ });
305
+
306
+ it('preserves other line properties when changing Line B lineType', () => {
307
+ const { getAllByText } = renderComponent({
308
+ gssLineData: {
309
+ selectedTool: 'lineB',
310
+ numberOfLines: 2,
311
+ lineA: { lineType: 'Dashed' },
312
+ lineB: { lineType: 'Solid' },
313
+ },
314
+ });
315
+
316
+ const dashedButtons = getAllByText(/Dashed/);
317
+ fireEvent.click(dashedButtons[1]);
318
+
319
+ const [updatedData] = onChange.mock.calls[0];
320
+ expect(updatedData.lineA.lineType).toBe('Dashed');
321
+ expect(updatedData.lineB.lineType).toBe('Dashed');
322
+ expect(updatedData.selectedTool).toBe('lineB');
323
+ expect(updatedData.numberOfLines).toBe(2);
324
+ });
325
+
326
+ it('handles multiple line type changes correctly', () => {
327
+ const { getAllByText } = renderComponent({
328
+ gssLineData: {
329
+ selectedTool: 'lineA',
330
+ numberOfLines: 2,
331
+ lineA: { lineType: 'Solid' },
332
+ lineB: { lineType: 'Solid' },
333
+ },
334
+ });
335
+
336
+ // Change Line A to Dashed
337
+ let dashedButtons = getAllByText(/Dashed/);
338
+ fireEvent.click(dashedButtons[0]);
339
+
340
+ expect(onChange).toHaveBeenCalledTimes(1);
341
+ let [updatedData] = onChange.mock.calls[0];
342
+ expect(updatedData.lineA.lineType).toBe('Dashed');
343
+
344
+ // Change Line B to Dashed
345
+ dashedButtons = getAllByText(/Dashed/);
346
+ fireEvent.click(dashedButtons[1]);
347
+
348
+ expect(onChange).toHaveBeenCalledTimes(2);
349
+ [updatedData] = onChange.mock.calls[1];
350
+ expect(updatedData.lineB.lineType).toBe('Dashed');
351
+ });
352
+
353
+ it('does not call onChange when line type button is disabled', () => {
354
+ const { getAllByRole } = renderComponent({
355
+ disabled: true,
356
+ gssLineData: {
357
+ selectedTool: 'lineA',
358
+ numberOfLines: 2,
359
+ lineA: { lineType: 'Solid' },
360
+ lineB: { lineType: 'Solid' },
361
+ },
362
+ });
363
+
364
+ const buttons = getAllByRole('button');
365
+
366
+ buttons.forEach((button) => {
367
+ expect(button).toBeDisabled();
368
+ });
369
+ });
370
+
371
+ it('maintains correct state when clicking same line type that is already selected', () => {
372
+ const { getAllByText } = renderComponent({
373
+ gssLineData: {
374
+ selectedTool: 'lineA',
375
+ numberOfLines: 2,
376
+ lineA: { lineType: 'Solid' },
377
+ lineB: { lineType: 'Solid' },
378
+ },
379
+ });
380
+
381
+ const solidButtons = getAllByText(/Solid/);
382
+ fireEvent.click(solidButtons[0]); // Click Solid when already Solid
383
+
384
+ expect(onChange).toHaveBeenCalledTimes(1);
385
+ const [updatedData] = onChange.mock.calls[0];
386
+ expect(updatedData.lineA.lineType).toBe('Solid');
387
+ });
388
+ });
389
+
390
+ describe('integration tests', () => {
391
+ it('allows switching selected tool and changing line type in sequence', () => {
392
+ const { getAllByRole, getAllByText } = renderComponent({
393
+ gssLineData: {
394
+ selectedTool: 'lineA',
395
+ numberOfLines: 2,
396
+ lineA: { lineType: 'Solid' },
397
+ lineB: { lineType: 'Solid' },
398
+ },
399
+ });
400
+
401
+ // Switch to Line B
402
+ const radios = getAllByRole('radio');
403
+ const lineBRadio = radios.find((r) => r.value === 'lineB');
404
+ fireEvent.click(lineBRadio);
405
+
406
+ expect(onChange).toHaveBeenCalledTimes(1);
407
+ let [updatedData] = onChange.mock.calls[0];
408
+ expect(updatedData.selectedTool).toBe('lineB');
409
+
410
+ // Change Line B to Dashed
411
+ const dashedButtons = getAllByText(/Dashed/);
412
+ fireEvent.click(dashedButtons[1]);
413
+
414
+ expect(onChange).toHaveBeenCalledTimes(2);
415
+ [updatedData] = onChange.mock.calls[1];
416
+ expect(updatedData.lineB.lineType).toBe('Dashed');
417
+ });
418
+
419
+ it('handles complete workflow of switching between all tools and changing line types', () => {
420
+ const { getAllByRole, getAllByText } = renderComponent({
421
+ gssLineData: {
422
+ selectedTool: 'lineA',
423
+ numberOfLines: 2,
424
+ lineA: { lineType: 'Solid' },
425
+ lineB: { lineType: 'Solid' },
426
+ },
427
+ });
428
+
429
+ // Change Line A to Dashed
430
+ let dashedButtons = getAllByText(/Dashed/);
431
+ fireEvent.click(dashedButtons[0]);
432
+ expect(onChange.mock.calls[0][0].lineA.lineType).toBe('Dashed');
433
+
434
+ // Switch to Line B
435
+ const radios = getAllByRole('radio');
436
+ const lineBRadio = radios.find((r) => r.value === 'lineB');
437
+ fireEvent.click(lineBRadio);
438
+ expect(onChange.mock.calls[1][0].selectedTool).toBe('lineB');
439
+
440
+ // Change Line B to Dashed
441
+ dashedButtons = getAllByText(/Dashed/);
442
+ fireEvent.click(dashedButtons[1]);
443
+ expect(onChange.mock.calls[2][0].lineB.lineType).toBe('Dashed');
444
+
445
+ // Switch to Solution Set
446
+ const solutionSetRadio = radios.find((r) => r.value === 'solutionSet');
447
+ fireEvent.click(solutionSetRadio);
448
+ expect(onChange.mock.calls[3][0].selectedTool).toBe('solutionSet');
449
+
450
+ expect(onChange).toHaveBeenCalledTimes(4);
451
+ });
32
452
  });
33
453
  });
@@ -1,4 +1,4 @@
1
- import { useState, useEffect } from 'react';
1
+ import { useState } from 'react';
2
2
  import { useDebounce } from '../use-debounce';
3
3
 
4
4
  jest.useFakeTimers();
@@ -63,67 +63,21 @@ describe('utils', () => {
63
63
  assertGetTickValues({ min: -0.2, max: 2, step: 0.6 }, [0, 0.6, 1.2, 1.8]);
64
64
  assertGetTickValues({ min: -3.4, max: 6.2, step: 1.2 }, [0, -1.2, -2.4, 1.2, 2.4, 3.6, 4.8, 6]);
65
65
 
66
- assertGetTickValues({ min: 0.6, max: 4.8, step: 0.3 }, [
67
- 0.6,
68
- 0.9,
69
- 1.2,
70
- 1.5,
71
- 1.8,
72
- 2.1,
73
- 2.4,
74
- 2.7,
75
- 3.0,
76
- 3.3,
77
- 3.6,
78
- 3.9,
79
- 4.2,
80
- 4.5,
81
- 4.8,
82
- ]);
83
- assertGetTickValues({ min: 0.5, max: 4.9, step: 0.3 }, [
84
- 0.6,
85
- 0.9,
86
- 1.2,
87
- 1.5,
88
- 1.8,
89
- 2.1,
90
- 2.4,
91
- 2.7,
92
- 3.0,
93
- 3.3,
94
- 3.6,
95
- 3.9,
96
- 4.2,
97
- 4.5,
98
- 4.8,
99
- ]);
100
- assertGetTickValues({ min: 0, max: 3, step: 0.125 }, [
101
- 0,
102
- 0.125,
103
- 0.25,
104
- 0.375,
105
- 0.5,
106
- 0.625,
107
- 0.75,
108
- 0.875,
109
- 1,
110
- 1.125,
111
- 1.25,
112
- 1.375,
113
- 1.5,
114
- 1.625,
115
- 1.75,
116
- 1.875,
117
- 2,
118
- 2.125,
119
- 2.25,
120
- 2.375,
121
- 2.5,
122
- 2.625,
123
- 2.75,
124
- 2.875,
125
- 3,
126
- ]);
66
+ assertGetTickValues(
67
+ { min: 0.6, max: 4.8, step: 0.3 },
68
+ [0.6, 0.9, 1.2, 1.5, 1.8, 2.1, 2.4, 2.7, 3.0, 3.3, 3.6, 3.9, 4.2, 4.5, 4.8],
69
+ );
70
+ assertGetTickValues(
71
+ { min: 0.5, max: 4.9, step: 0.3 },
72
+ [0.6, 0.9, 1.2, 1.5, 1.8, 2.1, 2.4, 2.7, 3.0, 3.3, 3.6, 3.9, 4.2, 4.5, 4.8],
73
+ );
74
+ assertGetTickValues(
75
+ { min: 0, max: 3, step: 0.125 },
76
+ [
77
+ 0, 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875, 1, 1.125, 1.25, 1.375, 1.5, 1.625, 1.75, 1.875, 2, 2.125, 2.25,
78
+ 2.375, 2.5, 2.625, 2.75, 2.875, 3,
79
+ ],
80
+ );
127
81
  });
128
82
 
129
83
  describe('countWords', () => {
@@ -2,7 +2,7 @@ import { render } from '@pie-lib/test-utils';
2
2
  import React from 'react';
3
3
  import { graphProps } from '../../__tests__/utils';
4
4
 
5
- import Axes, { RawXAxis, RawYAxis, firstNegativeValue, sharedValues } from '../axes';
5
+ import { firstNegativeValue, RawXAxis, RawYAxis, sharedValues } from '../axes';
6
6
 
7
7
  describe('RawXAxis', () => {
8
8
  let onChange = jest.fn();
package/src/axis/axes.jsx CHANGED
@@ -4,7 +4,7 @@ import { types } from '@pie-lib/plot';
4
4
  import PropTypes from 'prop-types';
5
5
  import Arrow from './arrow';
6
6
  import { styled } from '@mui/material/styles';
7
- import { countWords, findLongestWord, amountToIncreaseWidth, getTickValues } from '../utils';
7
+ import { amountToIncreaseWidth, countWords, findLongestWord, getTickValues } from '../utils';
8
8
  import { color, Readable } from '@pie-lib/render-ui';
9
9
 
10
10
  export const AxisPropTypes = {
@@ -92,14 +92,8 @@ export class RawXAxis extends React.Component {
92
92
  static defaultProps = AxisDefaultProps;
93
93
 
94
94
  render() {
95
- const {
96
- includeArrows,
97
- graphProps,
98
- columnTicksValues,
99
- skipValues,
100
- distanceFromOriginToFirstNegativeY,
101
- dy,
102
- } = this.props;
95
+ const { includeArrows, graphProps, columnTicksValues, skipValues, distanceFromOriginToFirstNegativeY, dy } =
96
+ this.props;
103
97
  const { scale, domain, size, range } = graphProps || {};
104
98
 
105
99
  const labelProps = (label) => {
@@ -131,12 +125,8 @@ export class RawXAxis extends React.Component {
131
125
  tickValues={columnTicksValues}
132
126
  hideZero={!(domain.labelStep || range.labelStep) && domain.min <= 0}
133
127
  />
134
- {includeArrows && includeArrows.left && (
135
- <StyledArrow direction="left" x={domain.min} y={0} scale={scale} />
136
- )}
137
- {includeArrows && includeArrows.right && (
138
- <StyledArrow direction="right" x={domain.max} y={0} scale={scale} />
139
- )}
128
+ {includeArrows && includeArrows.left && <StyledArrow direction="left" x={domain.min} y={0} scale={scale} />}
129
+ {includeArrows && includeArrows.right && <StyledArrow direction="right" x={domain.max} y={0} scale={scale} />}
140
130
  {domain.axisLabel && (
141
131
  <foreignObject x={size.width + 17} y={scale.y(0) - 9} width={necessaryWidth} height={20 * necessaryRows}>
142
132
  <LabelContainer dangerouslySetInnerHTML={{ __html: domain.axisLabel }} />
@@ -191,12 +181,8 @@ export class RawYAxis extends React.Component {
191
181
  tickTextAnchor={'bottom'}
192
182
  tickValues={rowTickValues}
193
183
  />
194
- {includeArrows && includeArrows.down && (
195
- <StyledArrow direction="down" x={0} y={range.min} scale={scale} />
196
- )}
197
- {includeArrows && includeArrows.up && (
198
- <StyledArrow direction="up" x={0} y={range.max} scale={scale} />
199
- )}
184
+ {includeArrows && includeArrows.down && <StyledArrow direction="down" x={0} y={range.min} scale={scale} />}
185
+ {includeArrows && includeArrows.up && <StyledArrow direction="up" x={0} y={range.max} scale={scale} />}
200
186
  {range.axisLabel && (
201
187
  <foreignObject x={scale.x(0) - necessaryWidth / 2} y={-33} width={necessaryWidth} height="20">
202
188
  <Readable false>
package/src/axis/index.js CHANGED
@@ -1,2 +1,3 @@
1
1
  import Axes, { AxisPropTypes } from './axes';
2
+
2
3
  export { Axes, AxisPropTypes };
package/src/bg.jsx CHANGED
@@ -1,6 +1,6 @@
1
1
  import React from 'react';
2
2
  import PropTypes from 'prop-types';
3
- import { select, pointer } from 'd3-selection';
3
+ import { pointer, select } from 'd3-selection';
4
4
  import { types, utils } from '@pie-lib/plot';
5
5
  import { getTickValues, thinnerShapesNeeded } from './utils';
6
6