@pie-lib/graphing 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.
- package/lib/axis/arrow.js +0 -3
- package/lib/axis/arrow.js.map +1 -1
- package/lib/axis/axes.js +0 -16
- package/lib/axis/axes.js.map +1 -1
- package/lib/axis/index.js +0 -7
- package/lib/axis/index.js.map +1 -1
- package/lib/bg.js +0 -6
- package/lib/bg.js.map +1 -1
- package/lib/container/actions.js +0 -1
- package/lib/container/actions.js.map +1 -1
- package/lib/container/index.js +4 -8
- package/lib/container/index.js.map +1 -1
- package/lib/container/marks.js +0 -2
- package/lib/container/marks.js.map +1 -1
- package/lib/container/middleware.js +0 -1
- package/lib/container/middleware.js.map +1 -1
- package/lib/container/reducer.js +0 -1
- package/lib/container/reducer.js.map +1 -1
- package/lib/coordinates-label.js +0 -11
- package/lib/coordinates-label.js.map +1 -1
- package/lib/graph-with-controls.js +3 -21
- package/lib/graph-with-controls.js.map +1 -1
- package/lib/graph.js +8 -27
- package/lib/graph.js.map +1 -1
- package/lib/grid-setup.js +0 -11
- package/lib/grid-setup.js.map +1 -1
- package/lib/grid.js +0 -22
- package/lib/grid.js.map +1 -1
- package/lib/index.js +0 -7
- package/lib/index.js.map +1 -1
- package/lib/key-legend.js +1 -2
- package/lib/key-legend.js.map +1 -1
- package/lib/label-svg-icon.js +0 -1
- package/lib/label-svg-icon.js.map +1 -1
- package/lib/labels.js +0 -13
- package/lib/labels.js.map +1 -1
- package/lib/mark-label.js +0 -15
- package/lib/mark-label.js.map +1 -1
- package/lib/toggle-bar.js +0 -17
- package/lib/toggle-bar.js.map +1 -1
- package/lib/tool-menu.js +0 -3
- package/lib/tool-menu.js.map +1 -1
- package/lib/tools/absolute/component.js +0 -1
- package/lib/tools/absolute/component.js.map +1 -1
- package/lib/tools/absolute/index.js +0 -10
- package/lib/tools/absolute/index.js.map +1 -1
- package/lib/tools/circle/bg-circle.js +0 -15
- package/lib/tools/circle/bg-circle.js.map +1 -1
- package/lib/tools/circle/component.js +2 -15
- package/lib/tools/circle/component.js.map +1 -1
- package/lib/tools/circle/index.js +0 -10
- package/lib/tools/circle/index.js.map +1 -1
- package/lib/tools/exponential/component.js +0 -1
- package/lib/tools/exponential/component.js.map +1 -1
- package/lib/tools/exponential/index.js +0 -10
- package/lib/tools/exponential/index.js.map +1 -1
- package/lib/tools/index.js +0 -1
- package/lib/tools/index.js.map +1 -1
- package/lib/tools/line/component.js +0 -2
- package/lib/tools/line/component.js.map +1 -1
- package/lib/tools/line/index.js +0 -1
- package/lib/tools/line/index.js.map +1 -1
- package/lib/tools/parabola/component.js +0 -1
- package/lib/tools/parabola/component.js.map +1 -1
- package/lib/tools/parabola/index.js +0 -10
- package/lib/tools/parabola/index.js.map +1 -1
- package/lib/tools/point/component.js +3 -15
- package/lib/tools/point/component.js.map +1 -1
- package/lib/tools/point/index.js +0 -10
- package/lib/tools/point/index.js.map +1 -1
- package/lib/tools/polygon/component.js +5 -29
- package/lib/tools/polygon/component.js.map +1 -1
- package/lib/tools/polygon/index.js +0 -12
- package/lib/tools/polygon/index.js.map +1 -1
- package/lib/tools/polygon/line.js +0 -15
- package/lib/tools/polygon/line.js.map +1 -1
- package/lib/tools/polygon/polygon.js +0 -18
- package/lib/tools/polygon/polygon.js.map +1 -1
- package/lib/tools/ray/component.js +0 -11
- package/lib/tools/ray/component.js.map +1 -1
- package/lib/tools/ray/index.js +0 -1
- package/lib/tools/ray/index.js.map +1 -1
- package/lib/tools/segment/component.js +0 -10
- package/lib/tools/segment/component.js.map +1 -1
- package/lib/tools/segment/index.js +0 -1
- package/lib/tools/segment/index.js.map +1 -1
- package/lib/tools/shared/arrow-head.js +0 -14
- package/lib/tools/shared/arrow-head.js.map +1 -1
- package/lib/tools/shared/icons/CorrectSVG.js +0 -1
- package/lib/tools/shared/icons/CorrectSVG.js.map +1 -1
- package/lib/tools/shared/icons/IncorrectSVG.js +0 -1
- package/lib/tools/shared/icons/IncorrectSVG.js.map +1 -1
- package/lib/tools/shared/icons/MissingSVG.js +0 -1
- package/lib/tools/shared/icons/MissingSVG.js.map +1 -1
- package/lib/tools/shared/line/index.js +7 -21
- package/lib/tools/shared/line/index.js.map +1 -1
- package/lib/tools/shared/line/line-path.js +0 -15
- package/lib/tools/shared/line/line-path.js.map +1 -1
- package/lib/tools/shared/line/with-root-edge.js +0 -11
- package/lib/tools/shared/line/with-root-edge.js.map +1 -1
- package/lib/tools/shared/point/arrow-point.js +0 -3
- package/lib/tools/shared/point/arrow-point.js.map +1 -1
- package/lib/tools/shared/point/arrow.js +0 -3
- package/lib/tools/shared/point/arrow.js.map +1 -1
- package/lib/tools/shared/point/base-point.js +0 -16
- package/lib/tools/shared/point/base-point.js.map +1 -1
- package/lib/tools/shared/point/index.js +0 -7
- package/lib/tools/shared/point/index.js.map +1 -1
- package/lib/tools/shared/styles.js +0 -1
- package/lib/tools/shared/styles.js.map +1 -1
- package/lib/tools/shared/types.js +0 -1
- package/lib/tools/shared/types.js.map +1 -1
- package/lib/tools/sine/component.js +0 -10
- package/lib/tools/sine/component.js.map +1 -1
- package/lib/tools/sine/index.js +0 -10
- package/lib/tools/sine/index.js.map +1 -1
- package/lib/tools/vector/component.js +0 -10
- package/lib/tools/vector/component.js.map +1 -1
- package/lib/tools/vector/index.js +0 -1
- package/lib/tools/vector/index.js.map +1 -1
- package/lib/undo-redo.js +0 -2
- package/lib/undo-redo.js.map +1 -1
- package/lib/use-debounce.js +0 -2
- package/lib/use-debounce.js.map +1 -1
- package/lib/utils.js +9 -26
- package/lib/utils.js.map +1 -1
- package/package.json +13 -10
- package/src/__tests__/bg.test.jsx +250 -0
- package/src/__tests__/coordinates-label.test.jsx +243 -0
- package/src/__tests__/graph-with-controls.test.jsx +9 -16
- package/src/__tests__/graph.test.jsx +560 -5
- package/src/__tests__/grid-setup.test.jsx +645 -0
- package/src/__tests__/grid.test.jsx +1 -1
- package/src/__tests__/key-legend.test.jsx +260 -0
- package/src/__tests__/label-svg-icon.test.jsx +278 -0
- package/src/__tests__/mark-label.test.jsx +1 -1
- package/src/__tests__/toggle-bar.test.jsx +0 -6
- package/src/__tests__/tool-menu.test.jsx +0 -4
- package/src/__tests__/use-debounce.test.js +1 -1
- package/src/__tests__/utils.test.js +15 -61
- package/src/axis/__tests__/axes.test.jsx +1 -1
- package/src/axis/axes.jsx +7 -21
- package/src/axis/index.js +1 -0
- package/src/bg.jsx +1 -1
- package/src/container/__tests__/actions.test.js +105 -0
- package/src/container/__tests__/index.test.jsx +319 -0
- package/src/container/__tests__/marks.test.js +172 -0
- package/src/container/__tests__/middleware.test.js +235 -0
- package/src/container/__tests__/reducer.test.js +324 -0
- package/src/container/index.jsx +2 -3
- package/src/coordinates-label.jsx +1 -7
- package/src/graph-with-controls.jsx +8 -6
- package/src/graph.jsx +2 -3
- package/src/grid-setup.jsx +1 -1
- package/src/key-legend.jsx +2 -1
- package/src/mark-label.jsx +7 -24
- package/src/toggle-bar.jsx +8 -1
- package/src/tools/absolute/__tests__/component.test.jsx +1 -2
- package/src/tools/absolute/component.jsx +2 -2
- package/src/tools/circle/__tests__/component.test.jsx +438 -0
- package/src/tools/circle/__tests__/index.test.js +480 -0
- package/src/tools/circle/bg-circle.jsx +2 -2
- package/src/tools/circle/component.jsx +10 -12
- package/src/tools/exponential/__tests__/component.test.jsx +0 -1
- package/src/tools/exponential/__tests__/index.test.js +729 -0
- package/src/tools/exponential/component.jsx +1 -1
- package/src/tools/line/__tests__/component.test.jsx +1 -0
- package/src/tools/line/component.jsx +4 -11
- package/src/tools/parabola/__tests__/component.test.jsx +0 -1
- package/src/tools/parabola/__tests__/index.test.js +470 -0
- package/src/tools/parabola/component.jsx +1 -1
- package/src/tools/point/__tests__/component.test.jsx +310 -2
- package/src/tools/point/__tests__/index.test.js +241 -0
- package/src/tools/point/component.jsx +1 -2
- package/src/tools/polygon/__tests__/component.test.jsx +391 -2
- package/src/tools/polygon/__tests__/index.test.js +237 -8
- package/src/tools/polygon/__tests__/line.test.jsx +13 -0
- package/src/tools/polygon/__tests__/polygon.test.jsx +19 -1
- package/src/tools/polygon/component.jsx +4 -14
- package/src/tools/polygon/line.jsx +1 -1
- package/src/tools/polygon/polygon.jsx +1 -1
- package/src/tools/ray/__tests__/component.test.jsx +1 -0
- package/src/tools/ray/component.jsx +3 -5
- package/src/tools/segment/__tests__/component.test.jsx +1 -0
- package/src/tools/segment/component.jsx +1 -1
- package/src/tools/shared/arrow-head.jsx +11 -6
- package/src/tools/shared/line/__tests__/index.test.jsx +1 -1
- package/src/tools/shared/line/__tests__/line-path.test.jsx +3 -3
- package/src/tools/shared/line/__tests__/with-root-edge.test.jsx +2 -2
- package/src/tools/shared/line/index.jsx +4 -6
- package/src/tools/shared/line/line-path.jsx +2 -8
- package/src/tools/shared/point/arrow-point.jsx +2 -5
- package/src/tools/sine/component.jsx +2 -2
- package/src/tools/vector/component.jsx +1 -1
- package/src/undo-redo.jsx +3 -9
- package/src/use-debounce.js +1 -1
- package/src/utils.js +1 -5
- package/NEXT.CHANGELOG.json +0 -16
|
@@ -0,0 +1,324 @@
|
|
|
1
|
+
import reducer from '../reducer';
|
|
2
|
+
import { changeMarks } from '../actions';
|
|
3
|
+
|
|
4
|
+
describe('container reducer', () => {
|
|
5
|
+
describe('reducer creation', () => {
|
|
6
|
+
it('creates a reducer function', () => {
|
|
7
|
+
const rootReducer = reducer();
|
|
8
|
+
expect(typeof rootReducer).toBe('function');
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
it('returns an object with marks property', () => {
|
|
12
|
+
const rootReducer = reducer();
|
|
13
|
+
const state = rootReducer(undefined, { type: 'INIT' });
|
|
14
|
+
expect(state).toHaveProperty('marks');
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
it('wraps marks reducer with undoable', () => {
|
|
18
|
+
const rootReducer = reducer();
|
|
19
|
+
const state = rootReducer(undefined, { type: 'INIT' });
|
|
20
|
+
|
|
21
|
+
expect(state.marks).toHaveProperty('past');
|
|
22
|
+
expect(state.marks).toHaveProperty('present');
|
|
23
|
+
expect(state.marks).toHaveProperty('future');
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
describe('initial state', () => {
|
|
28
|
+
it('initializes with empty past', () => {
|
|
29
|
+
const rootReducer = reducer();
|
|
30
|
+
const state = rootReducer(undefined, { type: 'INIT' });
|
|
31
|
+
|
|
32
|
+
expect(state.marks.past).toEqual([]);
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it('initializes with empty present', () => {
|
|
36
|
+
const rootReducer = reducer();
|
|
37
|
+
const state = rootReducer(undefined, { type: 'INIT' });
|
|
38
|
+
|
|
39
|
+
expect(state.marks.present).toEqual([]);
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
it('initializes with empty future', () => {
|
|
43
|
+
const rootReducer = reducer();
|
|
44
|
+
const state = rootReducer(undefined, { type: 'INIT' });
|
|
45
|
+
|
|
46
|
+
expect(state.marks.future).toEqual([]);
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
describe('CHANGE_MARKS action', () => {
|
|
51
|
+
it('updates present with new marks', () => {
|
|
52
|
+
const rootReducer = reducer();
|
|
53
|
+
const newMarks = [{ id: 1, type: 'point', x: 5, y: 10 }];
|
|
54
|
+
const action = changeMarks(newMarks);
|
|
55
|
+
|
|
56
|
+
let state = rootReducer(undefined, { type: '@@INIT' });
|
|
57
|
+
state = rootReducer(state, action);
|
|
58
|
+
|
|
59
|
+
expect(state.marks.present).toEqual(newMarks);
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
it('adds previous state to past', () => {
|
|
63
|
+
const rootReducer = reducer();
|
|
64
|
+
const firstMarks = [{ id: 1, type: 'point' }];
|
|
65
|
+
const secondMarks = [{ id: 2, type: 'line' }];
|
|
66
|
+
|
|
67
|
+
let state = rootReducer(undefined, { type: '@@INIT' });
|
|
68
|
+
state = rootReducer(state, changeMarks(firstMarks));
|
|
69
|
+
state = rootReducer(state, changeMarks(secondMarks));
|
|
70
|
+
|
|
71
|
+
expect(state.marks.past.length).toBeGreaterThan(0);
|
|
72
|
+
expect(state.marks.present).toEqual(secondMarks);
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
it('clears future on new action', () => {
|
|
76
|
+
const rootReducer = reducer();
|
|
77
|
+
const firstMarks = [{ id: 1, type: 'point' }];
|
|
78
|
+
const secondMarks = [{ id: 2, type: 'line' }];
|
|
79
|
+
const thirdMarks = [{ id: 3, type: 'circle' }];
|
|
80
|
+
|
|
81
|
+
let state = rootReducer(undefined, { type: '@@INIT' });
|
|
82
|
+
state = rootReducer(state, changeMarks(firstMarks));
|
|
83
|
+
state = rootReducer(state, changeMarks(secondMarks));
|
|
84
|
+
state = rootReducer(state, { type: '@@redux-undo/UNDO' });
|
|
85
|
+
|
|
86
|
+
expect(state.marks.future.length).toBeGreaterThan(0);
|
|
87
|
+
|
|
88
|
+
state = rootReducer(state, changeMarks(thirdMarks));
|
|
89
|
+
expect(state.marks.future).toEqual([]);
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
it('handles empty marks array', () => {
|
|
93
|
+
const rootReducer = reducer();
|
|
94
|
+
const action = changeMarks([]);
|
|
95
|
+
|
|
96
|
+
let state = rootReducer(undefined, { type: '@@INIT' });
|
|
97
|
+
state = rootReducer(state, action);
|
|
98
|
+
|
|
99
|
+
expect(state.marks.present).toEqual([]);
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
it('handles multiple marks', () => {
|
|
103
|
+
const rootReducer = reducer();
|
|
104
|
+
const marks = [
|
|
105
|
+
{ id: 1, type: 'point', x: 1, y: 2 },
|
|
106
|
+
{ id: 2, type: 'line', from: { x: 0, y: 0 }, to: { x: 5, y: 5 } },
|
|
107
|
+
{ id: 3, type: 'circle', center: { x: 3, y: 3 }, radius: 2 },
|
|
108
|
+
];
|
|
109
|
+
const action = changeMarks(marks);
|
|
110
|
+
|
|
111
|
+
let state = rootReducer(undefined, { type: '@@INIT' });
|
|
112
|
+
state = rootReducer(state, action);
|
|
113
|
+
|
|
114
|
+
expect(state.marks.present).toEqual(marks);
|
|
115
|
+
expect(state.marks.present.length).toBe(3);
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
describe('undo functionality', () => {
|
|
120
|
+
it('supports undo action', () => {
|
|
121
|
+
const rootReducer = reducer();
|
|
122
|
+
const firstMarks = [{ id: 1, type: 'point' }];
|
|
123
|
+
const secondMarks = [{ id: 2, type: 'line' }];
|
|
124
|
+
|
|
125
|
+
let state = rootReducer(undefined, { type: '@@INIT' });
|
|
126
|
+
state = rootReducer(state, changeMarks(firstMarks));
|
|
127
|
+
state = rootReducer(state, changeMarks(secondMarks));
|
|
128
|
+
|
|
129
|
+
state = rootReducer(state, { type: '@@redux-undo/UNDO' });
|
|
130
|
+
|
|
131
|
+
expect(state.marks.present).toEqual(firstMarks);
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
it('moves present to future on undo', () => {
|
|
135
|
+
const rootReducer = reducer();
|
|
136
|
+
const firstMarks = [{ id: 1, type: 'point' }];
|
|
137
|
+
const secondMarks = [{ id: 2, type: 'line' }];
|
|
138
|
+
|
|
139
|
+
let state = rootReducer(undefined, { type: '@@INIT' });
|
|
140
|
+
state = rootReducer(state, changeMarks(firstMarks));
|
|
141
|
+
state = rootReducer(state, changeMarks(secondMarks));
|
|
142
|
+
state = rootReducer(state, { type: '@@redux-undo/UNDO' });
|
|
143
|
+
|
|
144
|
+
expect(state.marks.future.length).toBeGreaterThan(0);
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
it('handles multiple undos', () => {
|
|
148
|
+
const rootReducer = reducer();
|
|
149
|
+
const marks1 = [{ id: 1 }];
|
|
150
|
+
const marks2 = [{ id: 2 }];
|
|
151
|
+
const marks3 = [{ id: 3 }];
|
|
152
|
+
|
|
153
|
+
let state = rootReducer(undefined, { type: '@@INIT' });
|
|
154
|
+
state = rootReducer(state, changeMarks(marks1));
|
|
155
|
+
state = rootReducer(state, changeMarks(marks2));
|
|
156
|
+
state = rootReducer(state, changeMarks(marks3));
|
|
157
|
+
|
|
158
|
+
state = rootReducer(state, { type: '@@redux-undo/UNDO' });
|
|
159
|
+
state = rootReducer(state, { type: '@@redux-undo/UNDO' });
|
|
160
|
+
|
|
161
|
+
expect(state.marks.present).toEqual(marks1);
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
it('does not undo beyond initial state', () => {
|
|
165
|
+
const rootReducer = reducer();
|
|
166
|
+
const marks = [{ id: 1, type: 'point' }];
|
|
167
|
+
|
|
168
|
+
let state = rootReducer(undefined, { type: '@@INIT' });
|
|
169
|
+
state = rootReducer(state, changeMarks(marks));
|
|
170
|
+
|
|
171
|
+
state = rootReducer(state, { type: '@@redux-undo/UNDO' });
|
|
172
|
+
state = rootReducer(state, { type: '@@redux-undo/UNDO' });
|
|
173
|
+
state = rootReducer(state, { type: '@@redux-undo/UNDO' });
|
|
174
|
+
|
|
175
|
+
expect(state.marks.present).toEqual([]);
|
|
176
|
+
expect(state.marks.past).toEqual([]);
|
|
177
|
+
});
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
describe('redo functionality', () => {
|
|
181
|
+
it('supports redo action', () => {
|
|
182
|
+
const rootReducer = reducer();
|
|
183
|
+
const firstMarks = [{ id: 1, type: 'point' }];
|
|
184
|
+
const secondMarks = [{ id: 2, type: 'line' }];
|
|
185
|
+
|
|
186
|
+
let state = rootReducer(undefined, { type: '@@INIT' });
|
|
187
|
+
state = rootReducer(state, changeMarks(firstMarks));
|
|
188
|
+
state = rootReducer(state, changeMarks(secondMarks));
|
|
189
|
+
state = rootReducer(state, { type: '@@redux-undo/UNDO' });
|
|
190
|
+
|
|
191
|
+
// Redo
|
|
192
|
+
state = rootReducer(state, { type: '@@redux-undo/REDO' });
|
|
193
|
+
|
|
194
|
+
expect(state.marks.present).toEqual(secondMarks);
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
it('moves future to past on redo', () => {
|
|
198
|
+
const rootReducer = reducer();
|
|
199
|
+
const firstMarks = [{ id: 1, type: 'point' }];
|
|
200
|
+
const secondMarks = [{ id: 2, type: 'line' }];
|
|
201
|
+
|
|
202
|
+
let state = rootReducer(undefined, { type: '@@INIT' });
|
|
203
|
+
state = rootReducer(state, changeMarks(firstMarks));
|
|
204
|
+
state = rootReducer(state, changeMarks(secondMarks));
|
|
205
|
+
state = rootReducer(state, { type: '@@redux-undo/UNDO' });
|
|
206
|
+
|
|
207
|
+
const futureBeforeRedo = state.marks.future.length;
|
|
208
|
+
state = rootReducer(state, { type: '@@redux-undo/REDO' });
|
|
209
|
+
|
|
210
|
+
expect(state.marks.future.length).toBe(futureBeforeRedo - 1);
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
it('handles multiple redos', () => {
|
|
214
|
+
const rootReducer = reducer();
|
|
215
|
+
const marks1 = [{ id: 1 }];
|
|
216
|
+
const marks2 = [{ id: 2 }];
|
|
217
|
+
const marks3 = [{ id: 3 }];
|
|
218
|
+
|
|
219
|
+
let state = rootReducer(undefined, { type: '@@INIT' });
|
|
220
|
+
state = rootReducer(state, changeMarks(marks1));
|
|
221
|
+
state = rootReducer(state, changeMarks(marks2));
|
|
222
|
+
state = rootReducer(state, changeMarks(marks3));
|
|
223
|
+
|
|
224
|
+
// undo twice, then redo twice
|
|
225
|
+
state = rootReducer(state, { type: '@@redux-undo/UNDO' });
|
|
226
|
+
state = rootReducer(state, { type: '@@redux-undo/UNDO' });
|
|
227
|
+
state = rootReducer(state, { type: '@@redux-undo/REDO' });
|
|
228
|
+
state = rootReducer(state, { type: '@@redux-undo/REDO' });
|
|
229
|
+
|
|
230
|
+
expect(state.marks.present).toEqual(marks3);
|
|
231
|
+
});
|
|
232
|
+
|
|
233
|
+
it('does not redo beyond last state', () => {
|
|
234
|
+
const rootReducer = reducer();
|
|
235
|
+
const marks = [{ id: 1, type: 'point' }];
|
|
236
|
+
|
|
237
|
+
let state = rootReducer(undefined, { type: '@@INIT' });
|
|
238
|
+
state = rootReducer(state, changeMarks(marks));
|
|
239
|
+
state = rootReducer(state, { type: '@@redux-undo/UNDO' });
|
|
240
|
+
state = rootReducer(state, { type: '@@redux-undo/REDO' });
|
|
241
|
+
|
|
242
|
+
// try to redo beyond the end
|
|
243
|
+
state = rootReducer(state, { type: '@@redux-undo/REDO' });
|
|
244
|
+
state = rootReducer(state, { type: '@@redux-undo/REDO' });
|
|
245
|
+
|
|
246
|
+
expect(state.marks.present).toEqual(marks);
|
|
247
|
+
expect(state.marks.future).toEqual([]);
|
|
248
|
+
});
|
|
249
|
+
});
|
|
250
|
+
|
|
251
|
+
describe('state structure', () => {
|
|
252
|
+
it('maintains correct undoable structure', () => {
|
|
253
|
+
const rootReducer = reducer();
|
|
254
|
+
const state = rootReducer(undefined, { type: 'INIT' });
|
|
255
|
+
|
|
256
|
+
expect(state.marks).toHaveProperty('past');
|
|
257
|
+
expect(state.marks).toHaveProperty('present');
|
|
258
|
+
expect(state.marks).toHaveProperty('future');
|
|
259
|
+
expect(Array.isArray(state.marks.past)).toBe(true);
|
|
260
|
+
expect(Array.isArray(state.marks.future)).toBe(true);
|
|
261
|
+
});
|
|
262
|
+
|
|
263
|
+
it('preserves mark properties through undo/redo', () => {
|
|
264
|
+
const rootReducer = reducer();
|
|
265
|
+
const marks = [
|
|
266
|
+
{
|
|
267
|
+
id: 1,
|
|
268
|
+
type: 'point',
|
|
269
|
+
x: 10,
|
|
270
|
+
y: 20,
|
|
271
|
+
label: 'A',
|
|
272
|
+
correctness: { value: 'correct' },
|
|
273
|
+
},
|
|
274
|
+
];
|
|
275
|
+
|
|
276
|
+
let state = rootReducer(undefined, { type: 'INIT' });
|
|
277
|
+
state = rootReducer(state, changeMarks(marks));
|
|
278
|
+
state = rootReducer(state, changeMarks([]));
|
|
279
|
+
state = rootReducer(state, { type: '@@redux-undo/UNDO' });
|
|
280
|
+
|
|
281
|
+
expect(state.marks.present).toEqual(marks);
|
|
282
|
+
expect(state.marks.present[0]).toBeDefined();
|
|
283
|
+
if (state.marks.present[0]) {
|
|
284
|
+
expect(state.marks.present[0]).toEqual(marks[0]);
|
|
285
|
+
expect(state.marks.present[0].correctness).toBeDefined();
|
|
286
|
+
}
|
|
287
|
+
});
|
|
288
|
+
});
|
|
289
|
+
|
|
290
|
+
describe('integration', () => {
|
|
291
|
+
it('handles complex undo/redo sequences', () => {
|
|
292
|
+
const rootReducer = reducer();
|
|
293
|
+
const marks1 = [{ id: 1 }];
|
|
294
|
+
const marks2 = [{ id: 2 }];
|
|
295
|
+
const marks3 = [{ id: 3 }];
|
|
296
|
+
const marks4 = [{ id: 4 }];
|
|
297
|
+
|
|
298
|
+
let state = rootReducer(undefined, { type: '@@INIT' });
|
|
299
|
+
state = rootReducer(state, changeMarks(marks1));
|
|
300
|
+
state = rootReducer(state, changeMarks(marks2));
|
|
301
|
+
state = rootReducer(state, changeMarks(marks3));
|
|
302
|
+
state = rootReducer(state, { type: '@@redux-undo/UNDO' }); // back to marks2
|
|
303
|
+
state = rootReducer(state, { type: '@@redux-undo/UNDO' }); // back to marks1
|
|
304
|
+
state = rootReducer(state, { type: '@@redux-undo/REDO' }); // forward to marks2
|
|
305
|
+
state = rootReducer(state, changeMarks(marks4));
|
|
306
|
+
|
|
307
|
+
expect(state.marks.present).toEqual(marks4);
|
|
308
|
+
expect(state.marks.future).toEqual([]);
|
|
309
|
+
});
|
|
310
|
+
|
|
311
|
+
it('works with empty state transitions', () => {
|
|
312
|
+
const rootReducer = reducer();
|
|
313
|
+
const marks = [{ id: 1 }];
|
|
314
|
+
|
|
315
|
+
let state = rootReducer(undefined, { type: '@@INIT' });
|
|
316
|
+
state = rootReducer(state, changeMarks([]));
|
|
317
|
+
state = rootReducer(state, changeMarks(marks));
|
|
318
|
+
state = rootReducer(state, changeMarks([]));
|
|
319
|
+
state = rootReducer(state, { type: '@@redux-undo/UNDO' });
|
|
320
|
+
|
|
321
|
+
expect(state.marks.present).toEqual(marks);
|
|
322
|
+
});
|
|
323
|
+
});
|
|
324
|
+
});
|
package/src/container/index.jsx
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
import { connect } from 'react-redux';
|
|
1
|
+
import { connect, Provider } from 'react-redux';
|
|
2
2
|
import React from 'react';
|
|
3
|
-
import { Provider } from 'react-redux';
|
|
4
3
|
import { applyMiddleware, createStore } from 'redux';
|
|
5
4
|
import reducer from './reducer';
|
|
6
5
|
import { changeMarks } from './actions';
|
|
7
6
|
import PropTypes from 'prop-types';
|
|
8
|
-
import isEqual from 'lodash
|
|
7
|
+
import { isEqual } from 'lodash-es';
|
|
9
8
|
import { ActionCreators } from 'redux-undo';
|
|
10
9
|
import GraphWithControls from '../graph-with-controls';
|
|
11
10
|
import { lastActionMiddleware } from './middleware';
|
|
@@ -51,13 +51,7 @@ export const CoordinatesLabel = ({ x, y, graphProps }) => {
|
|
|
51
51
|
...labelPosition,
|
|
52
52
|
};
|
|
53
53
|
|
|
54
|
-
return
|
|
55
|
-
<StyledInputBase
|
|
56
|
-
style={style}
|
|
57
|
-
value={label}
|
|
58
|
-
inputProps={{ ariaLabel: 'naked' }}
|
|
59
|
-
/>
|
|
60
|
-
);
|
|
54
|
+
return <StyledInputBase style={style} value={label} inputProps={{ ariaLabel: 'naked' }} />;
|
|
61
55
|
};
|
|
62
56
|
|
|
63
57
|
CoordinatesLabel.propTypes = {
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
3
|
import { styled } from '@mui/material/styles';
|
|
4
|
-
import uniq from 'lodash
|
|
5
|
-
import isString from 'lodash/isString';
|
|
4
|
+
import { isString, uniq } from 'lodash-es';
|
|
6
5
|
import { color } from '@pie-lib/render-ui';
|
|
7
6
|
|
|
8
7
|
import ToolMenu from './tool-menu';
|
|
@@ -66,7 +65,12 @@ export const filterByVisibleToolTypes = (toolbarTools, marks) =>
|
|
|
66
65
|
const getDefaultCurrentTool = (toolType) => toolsArr.find((tool) => tool.type === toolType) || null;
|
|
67
66
|
|
|
68
67
|
const Collapsible = ({ children, title }) => (
|
|
69
|
-
<StyledAccordion
|
|
68
|
+
<StyledAccordion
|
|
69
|
+
elevation={0}
|
|
70
|
+
disableGutters={true}
|
|
71
|
+
square={true}
|
|
72
|
+
TransitionProps={{ timeout: { enter: 225, exit: 195 } }}
|
|
73
|
+
>
|
|
70
74
|
<StyledAccordionSummary expandIcon={<ExpandMoreIcon />}>
|
|
71
75
|
<Typography variant="subheading">{title}</Typography>
|
|
72
76
|
</StyledAccordionSummary>
|
|
@@ -193,9 +197,7 @@ export class GraphWithControls extends React.Component {
|
|
|
193
197
|
<StyledGraphContainer className={className}>
|
|
194
198
|
<StyledControls>
|
|
195
199
|
{collapsibleToolbar ? (
|
|
196
|
-
<Collapsible title={collapsibleToolbarTitle}>
|
|
197
|
-
{graphActions}
|
|
198
|
-
</Collapsible>
|
|
200
|
+
<Collapsible title={collapsibleToolbarTitle}>{graphActions}</Collapsible>
|
|
199
201
|
) : (
|
|
200
202
|
graphActions
|
|
201
203
|
)}
|
package/src/graph.jsx
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
|
-
import isEqual from 'lodash
|
|
4
|
-
import
|
|
5
|
-
import { Root, types, createGraphProps } from '@pie-lib/plot';
|
|
3
|
+
import { cloneDeep, isEqual } from 'lodash-es';
|
|
4
|
+
import { createGraphProps, Root, types } from '@pie-lib/plot';
|
|
6
5
|
import debug from 'debug';
|
|
7
6
|
|
|
8
7
|
import { Axes, AxisPropTypes } from './axis';
|
package/src/grid-setup.jsx
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
3
|
import { color, InputContainer } from '@pie-lib/render-ui';
|
|
4
|
-
import { Accordion,
|
|
4
|
+
import { Accordion, AccordionDetails, AccordionSummary, Typography } from '@mui/material';
|
|
5
5
|
import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
|
|
6
6
|
import { NumberTextFieldCustom, Toggle } from '@pie-lib/config-ui';
|
|
7
7
|
import EditableHTML from '@pie-lib/editable-html-tip-tap';
|
package/src/key-legend.jsx
CHANGED
|
@@ -110,7 +110,8 @@ const KeyLegend = ({ className, isLabelAvailable }) => {
|
|
|
110
110
|
<path
|
|
111
111
|
d="M12.1953 4.46875C12.3125 4.35156 12.5 4.35156 12.5938 4.46875L13.2734 5.125C13.3672 5.24219 13.3672 5.42969 13.2734 5.52344L6.24219 12.5547C6.125 12.6719 5.96094 12.6719 5.84375 12.5547L2.70312 9.4375C2.60938 9.32031 2.60938 9.13281 2.70312 9.03906L3.38281 8.35938C3.47656 8.26562 3.66406 8.26562 3.78125 8.35938L6.03125 10.6328L12.1953 4.46875Z"
|
|
112
112
|
fill="white"
|
|
113
|
-
/>
|
|
113
|
+
/>{' '}
|
|
114
|
+
</svg>
|
|
114
115
|
</StyledRow>
|
|
115
116
|
{isLabelAvailable && (
|
|
116
117
|
<StyledRow>
|
package/src/mark-label.jsx
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, {
|
|
1
|
+
import React, { useCallback, useEffect, useState } from 'react';
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
3
|
import { styled, useTheme } from '@mui/material/styles';
|
|
4
4
|
import AutosizeInput from 'react-input-autosize';
|
|
@@ -53,9 +53,9 @@ const getInputStyles = (theme, disabled, markDisabled) => ({
|
|
|
53
53
|
padding: theme.spacing(0.5),
|
|
54
54
|
fontFamily: theme.typography.fontFamily,
|
|
55
55
|
fontSize: '10px',
|
|
56
|
-
border: disabled
|
|
56
|
+
border: disabled
|
|
57
57
|
? `solid 1px ${color.defaults.PRIMARY_DARK}`
|
|
58
|
-
: markDisabled
|
|
58
|
+
: markDisabled
|
|
59
59
|
? `solid 1px ${color.disabled()}`
|
|
60
60
|
: `solid 1px ${color.defaults.SECONDARY}`,
|
|
61
61
|
borderRadius: '3px',
|
|
@@ -208,37 +208,20 @@ export const MarkLabel = (props) => {
|
|
|
208
208
|
renderInput(studentInputStyle, label)
|
|
209
209
|
)}
|
|
210
210
|
</StyledInputIncorrect>
|
|
211
|
-
<StyledInputMissing style={secondLabelStyle}>
|
|
212
|
-
{renderInput(studentInputStyle, correctlabel)}
|
|
213
|
-
</StyledInputMissing>
|
|
211
|
+
<StyledInputMissing style={secondLabelStyle}>{renderInput(studentInputStyle, correctlabel)}</StyledInputMissing>
|
|
214
212
|
</>
|
|
215
213
|
);
|
|
216
214
|
}
|
|
217
215
|
|
|
218
216
|
if (correctness === 'missing') {
|
|
219
|
-
return (
|
|
220
|
-
<StyledInputMissing style={style}>
|
|
221
|
-
{renderInput(studentInputStyle, label)}
|
|
222
|
-
</StyledInputMissing>
|
|
223
|
-
);
|
|
217
|
+
return <StyledInputMissing style={style}>{renderInput(studentInputStyle, label)}</StyledInputMissing>;
|
|
224
218
|
}
|
|
225
219
|
|
|
226
220
|
if (correctness === 'incorrect') {
|
|
227
|
-
return (
|
|
228
|
-
<StyledIncorrect style={style}>
|
|
229
|
-
{renderInput(studentInputStyle, label)}
|
|
230
|
-
</StyledIncorrect>
|
|
231
|
-
);
|
|
221
|
+
return <StyledIncorrect style={style}>{renderInput(studentInputStyle, label)}</StyledIncorrect>;
|
|
232
222
|
}
|
|
233
223
|
|
|
234
|
-
return (
|
|
235
|
-
<div style={style}>
|
|
236
|
-
{renderInput(
|
|
237
|
-
getInputStyles(theme, disabled, mark.disabled),
|
|
238
|
-
label,
|
|
239
|
-
)}
|
|
240
|
-
</div>
|
|
241
|
-
);
|
|
224
|
+
return <div style={style}>{renderInput(getInputStyles(theme, disabled, mark.disabled), label)}</div>;
|
|
242
225
|
};
|
|
243
226
|
|
|
244
227
|
MarkLabel.propTypes = {
|
package/src/toggle-bar.jsx
CHANGED
|
@@ -158,7 +158,14 @@ export class ToggleBar extends React.Component {
|
|
|
158
158
|
|
|
159
159
|
// DragTool functional component using @dnd-kit hooks
|
|
160
160
|
function DragTool({ children, index, draggable, toolRef, value }) {
|
|
161
|
-
const {
|
|
161
|
+
const {
|
|
162
|
+
attributes,
|
|
163
|
+
listeners,
|
|
164
|
+
setNodeRef: setDragNodeRef,
|
|
165
|
+
transform,
|
|
166
|
+
transition,
|
|
167
|
+
isDragging,
|
|
168
|
+
} = useDraggable({
|
|
162
169
|
id: `tool-${value}-${index}`,
|
|
163
170
|
disabled: !draggable,
|
|
164
171
|
data: {
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
1
|
import { withRootEdge } from '../../shared/line/with-root-edge';
|
|
3
|
-
import {
|
|
2
|
+
import { absoluteFromTwoPoints, buildDataPoints } from '@pie-lib/graphing-utils';
|
|
4
3
|
import { utils } from '@pie-lib/plot';
|
|
5
4
|
|
|
6
5
|
import { graphProps as getGraphProps } from '../../../__tests__/utils';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import debug from 'debug';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { absoluteFromTwoPoints, buildDataPoints } from '@pie-lib/graphing-utils';
|
|
3
|
+
import { rootEdgeComponent, withRootEdge } from '../shared/line/with-root-edge';
|
|
4
4
|
|
|
5
5
|
const log = debug('pie-lib:graphing:absolute');
|
|
6
6
|
|