@pie-lib/graphing 2.14.22-next.0 → 2.15.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (193) hide show
  1. package/CHANGELOG.md +16 -75
  2. package/NEXT.CHANGELOG.json +1 -0
  3. package/lib/axis/axes.js +5 -5
  4. package/lib/axis/axes.js.map +1 -1
  5. package/lib/container/index.js +1 -4
  6. package/lib/container/index.js.map +1 -1
  7. package/lib/coordinates-label.js +5 -3
  8. package/lib/coordinates-label.js.map +1 -1
  9. package/lib/graph-with-controls.js +8 -15
  10. package/lib/graph-with-controls.js.map +1 -1
  11. package/lib/graph.js +29 -12
  12. package/lib/graph.js.map +1 -1
  13. package/lib/grid.js +6 -14
  14. package/lib/grid.js.map +1 -1
  15. package/lib/index.js +8 -0
  16. package/lib/index.js.map +1 -1
  17. package/lib/key-legend.js +246 -0
  18. package/lib/key-legend.js.map +1 -0
  19. package/lib/label-svg-icon.js +56 -0
  20. package/lib/label-svg-icon.js.map +1 -0
  21. package/lib/labels.js +2 -1
  22. package/lib/labels.js.map +1 -1
  23. package/lib/mark-label.js +167 -56
  24. package/lib/mark-label.js.map +1 -1
  25. package/lib/toggle-bar.js +3 -4
  26. package/lib/toggle-bar.js.map +1 -1
  27. package/lib/tool-menu.js +2 -22
  28. package/lib/tool-menu.js.map +1 -1
  29. package/lib/tools/absolute/component.js +35 -0
  30. package/lib/tools/absolute/component.js.map +1 -0
  31. package/lib/tools/absolute/index.js +63 -0
  32. package/lib/tools/absolute/index.js.map +1 -0
  33. package/lib/tools/circle/bg-circle.js +4 -3
  34. package/lib/tools/circle/bg-circle.js.map +1 -1
  35. package/lib/tools/circle/component.js +34 -15
  36. package/lib/tools/circle/component.js.map +1 -1
  37. package/lib/tools/exponential/component.js +34 -0
  38. package/lib/tools/exponential/component.js.map +1 -0
  39. package/lib/tools/exponential/index.js +71 -0
  40. package/lib/tools/exponential/index.js.map +1 -0
  41. package/lib/tools/index.js +26 -6
  42. package/lib/tools/index.js.map +1 -1
  43. package/lib/tools/line/component.js +2 -1
  44. package/lib/tools/line/component.js.map +1 -1
  45. package/lib/tools/parabola/component.js +6 -5
  46. package/lib/tools/parabola/component.js.map +1 -1
  47. package/lib/tools/point/component.js +14 -9
  48. package/lib/tools/point/component.js.map +1 -1
  49. package/lib/tools/polygon/component.js +25 -12
  50. package/lib/tools/polygon/component.js.map +1 -1
  51. package/lib/tools/polygon/line.js +12 -6
  52. package/lib/tools/polygon/line.js.map +1 -1
  53. package/lib/tools/polygon/polygon.js +6 -3
  54. package/lib/tools/polygon/polygon.js.map +1 -1
  55. package/lib/tools/ray/component.js +2 -1
  56. package/lib/tools/ray/component.js.map +1 -1
  57. package/lib/tools/segment/component.js +2 -1
  58. package/lib/tools/segment/component.js.map +1 -1
  59. package/lib/tools/shared/icons/CorrectSVG.js +36 -0
  60. package/lib/tools/shared/icons/CorrectSVG.js.map +1 -0
  61. package/lib/tools/shared/icons/IncorrectSVG.js +36 -0
  62. package/lib/tools/shared/icons/IncorrectSVG.js.map +1 -0
  63. package/lib/tools/shared/icons/MissingSVG.js +35 -0
  64. package/lib/tools/shared/icons/MissingSVG.js.map +1 -0
  65. package/lib/tools/shared/line/index.js +51 -19
  66. package/lib/tools/shared/line/index.js.map +1 -1
  67. package/lib/tools/shared/line/line-path.js +13 -7
  68. package/lib/tools/shared/line/line-path.js.map +1 -1
  69. package/lib/tools/shared/line/with-root-edge.js +19 -8
  70. package/lib/tools/shared/line/with-root-edge.js.map +1 -1
  71. package/lib/tools/shared/point/arrow-point.js +1 -1
  72. package/lib/tools/shared/point/arrow-point.js.map +1 -1
  73. package/lib/tools/shared/point/arrow.js +1 -1
  74. package/lib/tools/shared/point/arrow.js.map +1 -1
  75. package/lib/tools/shared/point/base-point.js +43 -7
  76. package/lib/tools/shared/point/base-point.js.map +1 -1
  77. package/lib/tools/shared/point/index.js +4 -1
  78. package/lib/tools/shared/point/index.js.map +1 -1
  79. package/lib/tools/shared/styles.js +16 -7
  80. package/lib/tools/shared/styles.js.map +1 -1
  81. package/lib/tools/sine/component.js +13 -4
  82. package/lib/tools/sine/component.js.map +1 -1
  83. package/lib/tools/vector/component.js +2 -1
  84. package/lib/tools/vector/component.js.map +1 -1
  85. package/lib/undo-redo.js +0 -1
  86. package/lib/undo-redo.js.map +1 -1
  87. package/lib/utils.js +1 -1
  88. package/lib/utils.js.map +1 -1
  89. package/package.json +15 -9
  90. package/src/__tests__/__snapshots__/graph-with-controls.test.jsx.snap +237 -0
  91. package/src/__tests__/__snapshots__/graph.test.jsx.snap +211 -0
  92. package/src/__tests__/__snapshots__/grid.test.jsx.snap +54 -0
  93. package/src/__tests__/__snapshots__/labels.test.jsx.snap +30 -0
  94. package/src/__tests__/__snapshots__/mark-label.test.jsx.snap +45 -0
  95. package/src/__tests__/__snapshots__/toggle-bar.test.jsx.snap +7 -0
  96. package/src/__tests__/__snapshots__/tool-menu.test.jsx.snap +13 -0
  97. package/src/__tests__/__snapshots__/undo-redo.test.jsx.snap +14 -0
  98. package/src/__tests__/graph-with-controls.test.jsx +147 -0
  99. package/src/__tests__/graph.test.jsx +230 -0
  100. package/src/__tests__/grid.test.jsx +20 -0
  101. package/src/__tests__/labels.test.jsx +38 -0
  102. package/src/__tests__/mark-label.test.jsx +68 -0
  103. package/src/__tests__/toggle-bar.test.jsx +36 -0
  104. package/src/__tests__/tool-menu.test.jsx +29 -0
  105. package/src/__tests__/undo-redo.test.jsx +25 -0
  106. package/src/__tests__/use-debounce.test.js +21 -0
  107. package/src/__tests__/utils.js +38 -0
  108. package/src/__tests__/utils.test.js +151 -0
  109. package/src/axis/__tests__/__snapshots__/arrow.test.jsx.snap +33 -0
  110. package/src/axis/__tests__/__snapshots__/axes.test.jsx.snap +122 -0
  111. package/src/axis/__tests__/arrow.test.jsx +39 -0
  112. package/src/axis/__tests__/axes.test.jsx +220 -0
  113. package/src/axis/axes.jsx +5 -5
  114. package/src/container/index.jsx +2 -4
  115. package/src/coordinates-label.jsx +4 -3
  116. package/src/graph-with-controls.jsx +8 -10
  117. package/src/graph.jsx +22 -10
  118. package/src/grid.jsx +8 -10
  119. package/src/index.js +2 -2
  120. package/src/key-legend.jsx +145 -0
  121. package/src/label-svg-icon.jsx +39 -0
  122. package/src/labels.jsx +2 -1
  123. package/src/mark-label.jsx +149 -52
  124. package/src/toggle-bar.jsx +1 -2
  125. package/src/tool-menu.jsx +3 -26
  126. package/src/tools/absolute/__tests__/component.test.jsx +54 -0
  127. package/src/tools/absolute/component.jsx +23 -0
  128. package/src/tools/absolute/index.js +31 -0
  129. package/src/tools/circle/__tests__/__snapshots__/bg-circle.test.jsx.snap +46 -0
  130. package/src/tools/circle/__tests__/__snapshots__/component.test.jsx.snap +293 -0
  131. package/src/tools/circle/__tests__/bg-circle.test.jsx +28 -0
  132. package/src/tools/circle/__tests__/component.test.jsx +228 -0
  133. package/src/tools/circle/bg-circle.jsx +5 -4
  134. package/src/tools/circle/component.jsx +22 -8
  135. package/src/tools/exponential/__tests__/component.test.jsx +54 -0
  136. package/src/tools/exponential/component.jsx +23 -0
  137. package/src/tools/exponential/index.js +39 -0
  138. package/src/tools/index.js +38 -5
  139. package/src/tools/line/__tests__/__snapshots__/component.test.jsx.snap +20 -0
  140. package/src/tools/line/__tests__/component.test.jsx +36 -0
  141. package/src/tools/line/component.jsx +2 -1
  142. package/src/tools/parabola/__tests__/component.test.jsx +49 -0
  143. package/src/tools/parabola/component.jsx +7 -6
  144. package/src/tools/point/__tests__/__snapshots__/component.test.jsx.snap +40 -0
  145. package/src/tools/point/__tests__/component.test.jsx +66 -0
  146. package/src/tools/point/component.jsx +12 -6
  147. package/src/tools/polygon/__tests__/__snapshots__/component.test.jsx.snap +415 -0
  148. package/src/tools/polygon/__tests__/__snapshots__/line.test.jsx.snap +45 -0
  149. package/src/tools/polygon/__tests__/__snapshots__/polygon.test.jsx.snap +52 -0
  150. package/src/tools/polygon/__tests__/component.test.jsx +226 -0
  151. package/src/tools/polygon/__tests__/index.test.js +65 -0
  152. package/src/tools/polygon/__tests__/line.test.jsx +25 -0
  153. package/src/tools/polygon/__tests__/polygon.test.jsx +44 -0
  154. package/src/tools/polygon/component.jsx +39 -11
  155. package/src/tools/polygon/line.jsx +15 -7
  156. package/src/tools/polygon/polygon.jsx +7 -3
  157. package/src/tools/ray/__tests__/__snapshots__/component.test.jsx.snap +23 -0
  158. package/src/tools/ray/__tests__/component.test.jsx +29 -0
  159. package/src/tools/ray/component.jsx +2 -1
  160. package/src/tools/segment/__tests__/__snapshots__/component.test.jsx.snap +14 -0
  161. package/src/tools/segment/__tests__/component.test.jsx +28 -0
  162. package/src/tools/segment/component.jsx +2 -1
  163. package/src/tools/shared/__tests__/__snapshots__/arrow-head.test.jsx.snap +27 -0
  164. package/src/tools/shared/__tests__/arrow-head.test.jsx +34 -0
  165. package/src/tools/shared/icons/CorrectSVG.jsx +22 -0
  166. package/src/tools/shared/icons/IncorrectSVG.jsx +20 -0
  167. package/src/tools/shared/icons/MissingSVG.jsx +21 -0
  168. package/src/tools/shared/line/__tests__/__snapshots__/index.test.jsx.snap +360 -0
  169. package/src/tools/shared/line/__tests__/__snapshots__/line-path.test.jsx.snap +58 -0
  170. package/src/tools/shared/line/__tests__/__snapshots__/with-root-edge.test.jsx.snap +63 -0
  171. package/src/tools/shared/line/__tests__/index.test.jsx +255 -0
  172. package/src/tools/shared/line/__tests__/line-path.test.jsx +53 -0
  173. package/src/tools/shared/line/__tests__/with-root-edge.test.jsx +73 -0
  174. package/src/tools/shared/line/index.jsx +39 -13
  175. package/src/tools/shared/line/line-path.jsx +18 -7
  176. package/src/tools/shared/line/with-root-edge.jsx +10 -3
  177. package/src/tools/shared/point/__tests__/__snapshots__/arrow-point.test.jsx.snap +56 -0
  178. package/src/tools/shared/point/__tests__/__snapshots__/base-point.test.jsx.snap +44 -0
  179. package/src/tools/shared/point/__tests__/arrow-point.test.jsx +87 -0
  180. package/src/tools/shared/point/__tests__/base-point.test.jsx +84 -0
  181. package/src/tools/shared/point/arrow-point.jsx +4 -1
  182. package/src/tools/shared/point/arrow.jsx +4 -1
  183. package/src/tools/shared/point/base-point.jsx +28 -3
  184. package/src/tools/shared/point/index.jsx +7 -2
  185. package/src/tools/shared/styles.js +8 -3
  186. package/src/tools/sine/__tests__/component.test.jsx +51 -0
  187. package/src/tools/sine/component.jsx +7 -7
  188. package/src/tools/vector/__tests__/__snapshots__/component.test.jsx.snap +12 -0
  189. package/src/tools/vector/__tests__/component.test.jsx +26 -0
  190. package/src/tools/vector/component.jsx +2 -1
  191. package/src/undo-redo.jsx +0 -1
  192. package/src/utils.js +1 -1
  193. package/legacy.png +0 -0
@@ -0,0 +1,255 @@
1
+ import { lineTool, lineToolComponent, lineBase } from '../index';
2
+ import { utils } from '@pie-lib/plot';
3
+ import { shallow } from 'enzyme';
4
+ import React from 'react';
5
+ import { graphProps as getGraphProps } from '../../../../__tests__/utils';
6
+
7
+ const { xy } = utils;
8
+ const xyLabel = (x, y, label) => ({ x, y, label });
9
+
10
+ describe('lineTool', () => {
11
+ describe('addPoint', () => {
12
+ let toolbar;
13
+ beforeEach(() => {
14
+ toolbar = lineTool('lineType', () => <div />)();
15
+ });
16
+ it('returns a building mark', () => {
17
+ const result = toolbar.addPoint(xy(1, 1));
18
+ expect(result).toEqual({
19
+ type: 'lineType',
20
+ building: true,
21
+ from: xy(1, 1),
22
+ });
23
+ });
24
+
25
+ it('returns a complete mark', () => {
26
+ const result = toolbar.addPoint(xy(1, 1), { from: xy(0, 0) });
27
+ expect(result).toEqual({
28
+ building: false,
29
+ from: xy(0, 0),
30
+ to: xy(1, 1),
31
+ });
32
+ });
33
+ });
34
+ });
35
+
36
+ describe('lineToolComponent', () => {
37
+ let Comp;
38
+ let mark;
39
+ let onChange;
40
+ let w;
41
+ const wrapper = (extras) => {
42
+ const defaults = {
43
+ mark,
44
+ onChange: jest.fn(),
45
+ graphProps: getGraphProps(),
46
+ };
47
+ const props = { ...defaults, ...extras };
48
+
49
+ return shallow(<Comp {...props} />);
50
+ };
51
+
52
+ beforeEach(() => {
53
+ Comp = lineToolComponent(() => <text />);
54
+ mark = { from: xy(0, 0), to: xy(1, 1) };
55
+ });
56
+
57
+ describe('snapshot', () => {
58
+ it('renders', () => {
59
+ w = wrapper();
60
+ expect(w).toMatchSnapshot();
61
+ });
62
+ });
63
+ describe('logic', () => {
64
+ describe('startDrag', () => {
65
+ it('sets state', () => {
66
+ w = wrapper();
67
+ w.instance().startDrag();
68
+ expect(w.state('mark')).toEqual(mark);
69
+ });
70
+ });
71
+
72
+ describe('stopDrag/changeMark', () => {
73
+ let update = { from: xy(2, 2), to: xy(4, 4) };
74
+ beforeEach(() => {
75
+ w = wrapper();
76
+ w.instance().changeMark(update);
77
+ w.instance().stopDrag();
78
+ });
79
+ it('calls onChange', () => {
80
+ expect(w.instance().props.onChange).toHaveBeenCalledWith(mark, update);
81
+ });
82
+ });
83
+ });
84
+ });
85
+
86
+ describe('lineBase', () => {
87
+ let Comp;
88
+ let w;
89
+ let onChange = jest.fn();
90
+ let changeMarkProps = jest.fn();
91
+
92
+ beforeEach(() => {
93
+ Comp = lineBase(() => <text />);
94
+ });
95
+
96
+ const wrapper = (extras) => {
97
+ const defaults = {
98
+ onChange,
99
+ changeMarkProps,
100
+ graphProps: getGraphProps(),
101
+ from: xy(0, 0),
102
+ to: xy(1, 1),
103
+ };
104
+ const props = { ...defaults, ...extras };
105
+
106
+ return shallow(<Comp {...props} />);
107
+ };
108
+
109
+ // used to test items that have labels attached to points
110
+ const labelNode = document.createElement('foreignObject');
111
+ const wrapperWithLabels = (extras = {}) =>
112
+ wrapper({
113
+ ...extras,
114
+ labelNode: labelNode,
115
+ from: xyLabel(0, 0, 'A'),
116
+ to: xyLabel(1, 1, 'B'),
117
+ });
118
+
119
+ describe('render', () => {
120
+ it('renders', () => {
121
+ w = wrapper();
122
+ expect(w).toMatchSnapshot();
123
+ });
124
+
125
+ it('renders with labels', () => {
126
+ w = wrapperWithLabels();
127
+ expect(w).toMatchSnapshot();
128
+ });
129
+ });
130
+
131
+ describe('logic', () => {
132
+ const assertCallsOnChange = (fn, args, expected) => {
133
+ it('calls onChange', () => {
134
+ const w = wrapper();
135
+ w.instance()[fn](...args);
136
+ expect(w.instance().props.onChange).toBeCalledWith(expected);
137
+ });
138
+ };
139
+
140
+ const assertCallsOnChangeWithLabels = (fn, args, expected) => {
141
+ it('calls onChange with labels', () => {
142
+ const w = wrapperWithLabels();
143
+ w.instance()[fn](...args);
144
+ expect(w.instance().props.onChange).toBeCalledWith(expected);
145
+ });
146
+ };
147
+
148
+ describe('dragComp', () => {
149
+ const update = { from: xy(2, 2), to: xy(4, 4) };
150
+ assertCallsOnChange('dragComp', [update], update);
151
+ });
152
+
153
+ describe('dragComp keeps labels on both "from" and "to"', () => {
154
+ const update = { from: xy(2, 2), to: xy(4, 4) };
155
+ assertCallsOnChangeWithLabels('dragComp', [update], {
156
+ from: xyLabel(2, 2, 'A'),
157
+ to: xyLabel(4, 4, 'B'),
158
+ });
159
+ });
160
+
161
+ describe('dragFrom', () => {
162
+ assertCallsOnChange('dragFrom', [xy(2, 2)], { from: xy(2, 2), to: xy(1, 1) });
163
+ });
164
+
165
+ describe('dragFrom keeps labels on "from"', () => {
166
+ assertCallsOnChangeWithLabels('dragFrom', [xy(2, 2)], {
167
+ from: xyLabel(2, 2, 'A'),
168
+ to: xyLabel(1, 1, 'B'),
169
+ });
170
+ });
171
+
172
+ describe('dragTo', () => {
173
+ assertCallsOnChange('dragTo', [xy(2, 2)], { from: xy(0, 0), to: xy(2, 2) });
174
+ });
175
+
176
+ describe('dragTo keeps labels on "to"', () => {
177
+ assertCallsOnChangeWithLabels('dragTo', [xy(3, 3)], {
178
+ from: xyLabel(0, 0, 'A'),
179
+ to: xyLabel(3, 3, 'B'),
180
+ });
181
+ });
182
+
183
+ describe('labelChange', () => {
184
+ it('updates "label" property for point', () => {
185
+ w = wrapperWithLabels({ labelModeEnabled: true });
186
+
187
+ w.instance().labelChange(xyLabel(0, 0, 'Label A'), 'from');
188
+ expect(changeMarkProps).toBeCalledWith({
189
+ from: xyLabel(0, 0, 'Label A'),
190
+ });
191
+
192
+ w.instance().labelChange(xyLabel(0, 0, 'Label B'), 'to');
193
+ expect(changeMarkProps).toBeCalledWith({
194
+ to: xyLabel(0, 0, 'Label B'),
195
+ });
196
+ });
197
+
198
+ it('removes "label" property if the field is empty', () => {
199
+ w = wrapperWithLabels();
200
+
201
+ w.instance().labelChange(xyLabel(0, 0, ''), 'from');
202
+ expect(changeMarkProps).toBeCalledWith({
203
+ from: xy(0, 0),
204
+ });
205
+
206
+ w.instance().labelChange(xyLabel(0, 0, ''), 'to');
207
+ expect(changeMarkProps).toBeCalledWith({
208
+ to: xy(0, 0),
209
+ });
210
+ });
211
+ });
212
+
213
+ describe('clickPoint', () => {
214
+ it('adds "label" property to a point', () => {
215
+ w = wrapperWithLabels({ labelModeEnabled: true });
216
+
217
+ w.instance().clickPoint(xy(0, 0), 'from');
218
+ expect(changeMarkProps).toBeCalledWith({
219
+ from: xyLabel(0, 0, ''),
220
+ to: xyLabel(1, 1, 'B'),
221
+ });
222
+
223
+ w.instance().clickPoint(xy(1, 1), 'to');
224
+ expect(changeMarkProps).toBeCalledWith({
225
+ from: xyLabel(0, 0, 'A'),
226
+ to: xyLabel(1, 1, ''),
227
+ });
228
+ });
229
+
230
+ it('adds "label" property to a point when limit labeling', () => {
231
+ const changeMarkProps = jest.fn();
232
+ w = wrapperWithLabels({ labelModeEnabled: true, limitLabeling: true, changeMarkProps });
233
+
234
+ w.instance().clickPoint(xy(0, 0), 'from');
235
+ expect(changeMarkProps).toHaveBeenCalledTimes(0);
236
+ });
237
+
238
+ it('if point already has label, keeps that value', () => {
239
+ w = wrapperWithLabels({ labelModeEnabled: true });
240
+
241
+ w.instance().clickPoint(xyLabel(0, 0, 'Label A'), 'from');
242
+ expect(changeMarkProps).toBeCalledWith({
243
+ from: xyLabel(0, 0, 'Label A'),
244
+ to: xyLabel(1, 1, 'B'),
245
+ });
246
+
247
+ w.instance().clickPoint(xyLabel(1, 1, 'Label B'), 'to');
248
+ expect(changeMarkProps).toBeCalledWith({
249
+ from: xyLabel(0, 0, 'A'),
250
+ to: xyLabel(1, 1, 'Label B'),
251
+ });
252
+ });
253
+ });
254
+ });
255
+ });
@@ -0,0 +1,53 @@
1
+ import { shallow } from 'enzyme';
2
+ import React from 'react';
3
+ import { graphProps as getGraphProps } from '../../../../__tests__/utils';
4
+ import { gridDraggable, utils } from '@pie-lib/plot';
5
+ const { xy } = utils;
6
+
7
+ import * as lineUtils from '../../../../utils';
8
+
9
+ const { bounds, pointsToArea } = lineUtils;
10
+ jest.mock('../../../../utils', () => {
11
+ const a = jest.requireActual('../../../../utils');
12
+ return {
13
+ pointsToArea: jest.fn().mockReturnValue({}),
14
+ bounds: jest.fn().mockReturnValue({}),
15
+ point: a.point,
16
+ };
17
+ });
18
+
19
+ jest.mock('@pie-lib/plot', () => {
20
+ const a = jest.requireActual('@pie-lib/plot');
21
+ return {
22
+ gridDraggable: jest.fn((opts) => jest.fn()),
23
+ types: a.types,
24
+ utils: a.utils,
25
+ };
26
+ });
27
+
28
+ describe('LinePath', () => {
29
+ let LinePath;
30
+ let w;
31
+ let onChange = jest.fn();
32
+ beforeEach(() => {
33
+ LinePath = require('../line-path').LinePath;
34
+ });
35
+ const wrapper = (extras) => {
36
+ const defaults = {
37
+ classes: {},
38
+ className: 'className',
39
+ onChange,
40
+ graphProps: getGraphProps(),
41
+ from: xy(0, 0, 0),
42
+ to: xy(1, 1, 0),
43
+ };
44
+ const props = { ...defaults, ...extras };
45
+ return shallow(<LinePath {...props} />);
46
+ };
47
+ describe('snapshot', () => {
48
+ it('renders', () => {
49
+ const w = wrapper();
50
+ expect(w).toMatchSnapshot();
51
+ });
52
+ });
53
+ });
@@ -0,0 +1,73 @@
1
+ import { shallow } from 'enzyme';
2
+ import React from 'react';
3
+ import { rootEdgeComponent, withRootEdge, rootEdgeToFromToWrapper } from '../with-root-edge';
4
+ import { graphProps as getGraphProps } from '../../../../__tests__/utils';
5
+ import { utils } from '@pie-lib/plot';
6
+ import { lineToolComponent, LineToolMockComponent } from '../index';
7
+ const { xy } = utils;
8
+ jest.mock('../index', () => {
9
+ const out = {
10
+ lineBase: jest.fn().mockReturnValue(() => <div />),
11
+ lineToolComponent: jest.fn().mockReturnValue(() => <div />),
12
+ };
13
+ return out;
14
+ });
15
+
16
+ describe('rootEdgeToToFromWRapper', () => {
17
+ let Comp;
18
+ let w;
19
+ let onChange = jest.fn();
20
+ beforeEach(() => {
21
+ Comp = rootEdgeToFromToWrapper(() => <div />);
22
+ });
23
+ const wrapper = (extras) => {
24
+ const defaults = {
25
+ mark: { root: xy(1, 1), edge: xy(2, 2) },
26
+ onChange,
27
+ };
28
+ const props = { ...defaults, ...extras };
29
+ return shallow(<Comp {...props} />);
30
+ };
31
+
32
+ it('renders', () => {
33
+ w = wrapper();
34
+ expect(w).toMatchSnapshot();
35
+ });
36
+
37
+ it('has from/to mark', () => {
38
+ w = wrapper();
39
+ expect(w.props().mark).toEqual({ from: xy(1, 1), to: xy(2, 2) });
40
+ });
41
+
42
+ it('calls onChange with root edge ', () => {
43
+ w = wrapper();
44
+ w.props().onChange({ from: xy(1, 1), to: xy(2, 2) }, { from: xy(3, 3), to: xy(4, 4) });
45
+ expect(onChange).toHaveBeenCalledWith({ root: xy(1, 1), edge: xy(2, 2) }, { root: xy(3, 3), edge: xy(4, 4) });
46
+ });
47
+ });
48
+ describe('rootEdgeComponent', () => {
49
+ let w;
50
+ let onChange = jest.fn();
51
+ let Comp;
52
+ let mark;
53
+ beforeEach(() => {
54
+ mark = { root: xy(0, 0), edge: xy(1, 1) };
55
+ Comp = rootEdgeComponent(() => <text />);
56
+ });
57
+ const wrapper = (extras, opts) => {
58
+ const defaults = {
59
+ mark,
60
+ graphProps: getGraphProps(),
61
+ onChange,
62
+ };
63
+
64
+ const props = { ...defaults, ...extras };
65
+ return shallow(<Comp {...props} />, opts);
66
+ };
67
+ describe('snapshot', () => {
68
+ it('renders', () => {
69
+ const w = wrapper();
70
+ expect(w).toMatchSnapshot();
71
+ });
72
+ });
73
+ });
@@ -4,7 +4,7 @@ import cloneDeep from 'lodash/cloneDeep';
4
4
  import { BasePoint } from '../point';
5
5
  import { types, utils, gridDraggable, trig } from '@pie-lib/plot';
6
6
  import PropTypes from 'prop-types';
7
- import { disabled, correct, incorrect, missing } from '../styles';
7
+ import { disabled, disabledSecondary, correct, incorrect, missing } from '../styles';
8
8
  import ReactDOM from 'react-dom';
9
9
  import MarkLabel from '../../../mark-label';
10
10
  import isEmpty from 'lodash/isEmpty';
@@ -55,8 +55,13 @@ export const lineToolComponent = (Component) => {
55
55
 
56
56
  this.setState({ mark: undefined }, () => {
57
57
  const { type } = update;
58
- const shouldNotChange = type && (type === 'parabola' || type === 'sine') && sameAxes(update.from, update.to);
59
-
58
+ let shouldNotChange =
59
+ type &&
60
+ (type === 'parabola' || type === 'sine' || type === 'absolute' || type === 'exponential') &&
61
+ sameAxes(update.from, update.to);
62
+ if (!shouldNotChange && type && type === 'exponential' && update.from && update.to) {
63
+ shouldNotChange = update.from.y === 0 || update.to.y === 0 || update.from.y * update.to.y < 0;
64
+ }
60
65
  if (!isEqual(mark, update) && !shouldNotChange) {
61
66
  onChange(mark, update);
62
67
  }
@@ -95,7 +100,7 @@ export const lineToolComponent = (Component) => {
95
100
  };
96
101
 
97
102
  render() {
98
- const { graphProps, onClick, labelNode, labelModeEnabled, coordinatesOnHover } = this.props;
103
+ const { graphProps, onClick, labelNode, labelModeEnabled, coordinatesOnHover, limitLabeling } = this.props;
99
104
  const mark = this.state.mark ? this.state.mark : this.props.mark;
100
105
 
101
106
  const from = cloneDeep(mark.from);
@@ -132,6 +137,7 @@ export const lineToolComponent = (Component) => {
132
137
  onDragStop={this.stopDrag}
133
138
  labelNode={labelNode}
134
139
  labelModeEnabled={labelModeEnabled}
140
+ limitLabeling={limitLabeling}
135
141
  />
136
142
  );
137
143
  }
@@ -249,8 +255,22 @@ export const lineBase = (Comp, opts) => {
249
255
  changeMarkProps({ [type]: update });
250
256
  };
251
257
 
252
- clickPoint = (point, type) => {
253
- const { changeMarkProps, from, to } = this.props;
258
+ clickPoint = (point, type, data) => {
259
+ const { changeMarkProps, disabled, from, to, labelModeEnabled, limitLabeling, onClick } = this.props;
260
+
261
+ if (!labelModeEnabled) {
262
+ onClick(point || data);
263
+ return;
264
+ }
265
+
266
+ if (disabled) {
267
+ return;
268
+ }
269
+
270
+ // limit labeling the points of the line
271
+ if (limitLabeling) {
272
+ return;
273
+ }
254
274
 
255
275
  if (type === 'middle' && !point && from && to) {
256
276
  point = { ...point, ...getMiddleOfTwoPoints(from, to) };
@@ -338,7 +358,7 @@ export const lineBase = (Comp, opts) => {
338
358
  middle={middle}
339
359
  onDrag={this.dragComp}
340
360
  {...common}
341
- onClick={labelModeEnabled ? () => this.clickPoint(middle, 'middle') : common.onClick}
361
+ onClick={(data) => this.clickPoint(middle, 'middle', data)}
342
362
  />
343
363
  )}
344
364
  {lineLabelNode}
@@ -350,7 +370,7 @@ export const lineBase = (Comp, opts) => {
350
370
  coordinatesOnHover={coordinatesOnHover}
351
371
  onDrag={this.dragFrom}
352
372
  {...common}
353
- onClick={labelModeEnabled ? () => this.clickPoint(from, 'from') : common.onClick}
373
+ onClick={(data) => this.clickPoint(from, 'from', data)}
354
374
  />
355
375
  {fromLabelNode}
356
376
 
@@ -363,7 +383,7 @@ export const lineBase = (Comp, opts) => {
363
383
  coordinatesOnHover={coordinatesOnHover}
364
384
  onDrag={this.dragTo}
365
385
  {...common}
366
- onClick={labelModeEnabled ? () => this.clickPoint(to, 'to') : common.onClick}
386
+ onClick={(data) => this.clickPoint(to, 'to', data)}
367
387
  />
368
388
  )}
369
389
  {toLabelNode}
@@ -378,19 +398,23 @@ export const lineBase = (Comp, opts) => {
378
398
  export const styles = {
379
399
  line: () => ({
380
400
  fill: 'transparent',
381
- stroke: color.primaryLight(),
401
+ stroke: color.defaults.BLACK,
382
402
  strokeWidth: 3,
383
403
  transition: 'stroke 200ms ease-in, stroke-width 200ms ease-in',
384
404
  '&:hover': {
385
405
  strokeWidth: 6,
386
- stroke: color.primaryDark(),
406
+ stroke: color.defaults.PRIMARY_DARK,
387
407
  },
388
408
  }),
389
409
  arrow: () => ({
390
- fill: color.secondary(),
410
+ fill: color.defaults.BLACK,
391
411
  }),
392
412
  disabledArrow: () => ({
393
- ...disabled(),
413
+ ...disabledSecondary(),
414
+ }),
415
+ disabledSecondary: () => ({
416
+ ...disabledSecondary('stroke'),
417
+ strokeWidth: 2,
394
418
  }),
395
419
  disabled: () => ({
396
420
  ...disabled('stroke'),
@@ -404,5 +428,7 @@ export const styles = {
404
428
  }),
405
429
  missing: (theme, key) => ({
406
430
  ...missing(key),
431
+ strokeWidth: 1,
432
+ strokeDasharray: '4 3',
407
433
  }),
408
434
  };
@@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
3
3
  import { withStyles } from '@material-ui/core/styles';
4
4
  import { types } from '@pie-lib/plot';
5
5
  import classNames from 'classnames';
6
- import { disabled, correct, incorrect, missing } from '../styles';
6
+ import { disabled, correct, incorrect, missing, disabledSecondary } from '../styles';
7
7
  import * as vx from '@vx/shape';
8
8
  import { color } from '@pie-lib/render-ui';
9
9
 
@@ -34,7 +34,12 @@ export class RawLinePath extends React.Component {
34
34
  <React.Fragment>
35
35
  <vx.LinePath
36
36
  data={data}
37
- className={classNames(classes.drawLine, disabled && classes.disabled, classes[correctness], className)}
37
+ className={classNames(
38
+ classes.drawLine,
39
+ disabled && classes.disabledSecondary,
40
+ classes[correctness],
41
+ className,
42
+ )}
38
43
  {...rest}
39
44
  />
40
45
  <vx.LinePath
@@ -42,7 +47,7 @@ export class RawLinePath extends React.Component {
42
47
  className={classNames(
43
48
  classes.line,
44
49
  isDragging && classes.dragging,
45
- disabled && classes.disabled,
50
+ disabled && classes.disabledSecondary,
46
51
  classes[correctness],
47
52
  className,
48
53
  )}
@@ -54,18 +59,18 @@ export class RawLinePath extends React.Component {
54
59
  }
55
60
 
56
61
  const dragging = () => ({
57
- strokeWidth: 7,
58
- stroke: color.secondaryLight(),
62
+ strokeWidth: 4,
63
+ stroke: color.defaults.BLACK,
59
64
  });
60
65
 
61
66
  export const LinePath = withStyles((theme) => ({
62
67
  drawLine: {
63
68
  fill: 'none',
64
69
  strokeWidth: 2,
65
- stroke: color.secondaryLight(),
70
+ stroke: color.black(),
66
71
  },
67
72
  line: {
68
- strokeWidth: 6,
73
+ strokeWidth: 3,
69
74
  fill: 'none',
70
75
  transition: 'stroke-width 200ms ease-in, stroke 200ms ease-in',
71
76
  stroke: 'transparent',
@@ -76,6 +81,10 @@ export const LinePath = withStyles((theme) => ({
76
81
  ...disabled('stroke'),
77
82
  strokeWidth: 2,
78
83
  },
84
+ disabledSecondary: {
85
+ ...disabledSecondary('stroke'),
86
+ strokeWidth: 2,
87
+ },
79
88
  correct: {
80
89
  ...correct('stroke'),
81
90
  },
@@ -84,5 +93,7 @@ export const LinePath = withStyles((theme) => ({
84
93
  },
85
94
  missing: {
86
95
  ...missing('stroke'),
96
+ strokeWidth: 1,
97
+ strokeDasharray: '4 3',
87
98
  },
88
99
  }))(RawLinePath);
@@ -1,7 +1,7 @@
1
1
  import React from 'react';
2
2
  import PropTypes from 'prop-types';
3
3
  import { types } from '@pie-lib/plot';
4
- import { LinePath } from '../line/line-path';
4
+ import { LinePath } from './line-path';
5
5
  import { curveMonotoneX } from '@vx/curve';
6
6
  import { lineBase, lineToolComponent } from './index';
7
7
 
@@ -51,11 +51,12 @@ const withPointsGenerationLinePath = (getPoints) => {
51
51
  const LinePathComponent = (props) => {
52
52
  const { graphProps, from, to, onClick, onDragStart, onDragStop, onChange, disabled, correctness, ...rest } = props;
53
53
 
54
- const { dataPoints } = getPoints({
54
+ const { dataPoints, enableCurve = true } = getPoints({
55
55
  graphProps: props.graphProps,
56
56
  root: from,
57
57
  edge: to,
58
58
  });
59
+
59
60
  const raw = dataPoints.map((d) => [graphProps.scale.x(d.x), graphProps.scale.y(d.y)]);
60
61
 
61
62
  const common = {
@@ -68,8 +69,13 @@ const withPointsGenerationLinePath = (getPoints) => {
68
69
  correctness,
69
70
  };
70
71
 
71
- return <LinePath data={raw} from={from} to={to} curve={curveMonotoneX} {...common} {...rest} />;
72
+ if (!enableCurve) {
73
+ return <LinePath data={raw} from={from} to={to} {...common} {...rest} />;
74
+ } else {
75
+ return <LinePath data={raw} from={from} to={to} curve={curveMonotoneX} {...common} {...rest} />;
76
+ }
72
77
  };
78
+
73
79
  LinePathComponent.propTypes = {
74
80
  graphProps: types.GraphPropsType.isRequired,
75
81
  from: types.PointType.isRequired,
@@ -81,6 +87,7 @@ const withPointsGenerationLinePath = (getPoints) => {
81
87
  disabled: PropTypes.bool,
82
88
  correctness: PropTypes.string,
83
89
  };
90
+
84
91
  return LinePathComponent;
85
92
  };
86
93
 
@@ -0,0 +1,56 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`ArrowPoint snapshot renders 1`] = `
4
+ <RawArrow
5
+ className="className"
6
+ classes={
7
+ Object {
8
+ "correct": "RawArrow-correct-4",
9
+ "disabled": "RawArrow-disabled-2",
10
+ "disabledSecondary": "RawArrow-disabledSecondary-3",
11
+ "incorrect": "RawArrow-incorrect-5",
12
+ "missing": "RawArrow-missing-6",
13
+ "point": "RawArrow-point-1",
14
+ }
15
+ }
16
+ from={
17
+ Object {
18
+ "x": 0,
19
+ "y": 0,
20
+ }
21
+ }
22
+ graphProps={
23
+ Object {
24
+ "domain": Object {
25
+ "max": 1,
26
+ "min": 0,
27
+ "step": 1,
28
+ },
29
+ "range": Object {
30
+ "max": 1,
31
+ "min": 0,
32
+ "step": 1,
33
+ },
34
+ "scale": Object {
35
+ "x": [MockFunction],
36
+ "y": [MockFunction],
37
+ },
38
+ "size": Object {
39
+ "height": 400,
40
+ "width": 400,
41
+ },
42
+ "snap": Object {
43
+ "x": [MockFunction],
44
+ "y": [MockFunction],
45
+ },
46
+ }
47
+ }
48
+ onChange={[MockFunction]}
49
+ to={
50
+ Object {
51
+ "x": 1,
52
+ "y": 1,
53
+ }
54
+ }
55
+ />
56
+ `;