@pie-lib/graphing 2.14.22-next.0 → 2.16.0-beta.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 (259) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/NEXT.CHANGELOG.json +1 -0
  3. package/lib/__tests__/graph-with-controls.test.js +215 -0
  4. package/lib/__tests__/graph.test.js +290 -0
  5. package/lib/__tests__/grid.test.js +40 -0
  6. package/lib/__tests__/labels.test.js +59 -0
  7. package/lib/__tests__/mark-label.test.js +154 -0
  8. package/lib/__tests__/toggle-bar.test.js +54 -0
  9. package/lib/__tests__/tool-menu.test.js +43 -0
  10. package/lib/__tests__/undo-redo.test.js +42 -0
  11. package/lib/__tests__/use-debounce.test.js +28 -0
  12. package/lib/__tests__/utils.js +72 -0
  13. package/lib/__tests__/utils.test.js +133 -0
  14. package/lib/axis/__tests__/arrow.test.js +68 -0
  15. package/lib/axis/__tests__/axes.test.js +214 -0
  16. package/lib/axis/arrow.js +1 -1
  17. package/lib/axis/axes.js +6 -6
  18. package/lib/axis/index.js +1 -1
  19. package/lib/bg.js +1 -1
  20. package/lib/container/actions.js +1 -1
  21. package/lib/container/index.js +2 -5
  22. package/lib/container/marks.js +1 -1
  23. package/lib/container/middleware.js +1 -1
  24. package/lib/container/reducer.js +1 -1
  25. package/lib/coordinates-label.js +6 -4
  26. package/lib/graph-with-controls.js +9 -16
  27. package/lib/graph.js +30 -13
  28. package/lib/grid-setup.js +1 -1
  29. package/lib/grid.js +7 -15
  30. package/lib/index.js +9 -1
  31. package/lib/key-legend.js +246 -0
  32. package/lib/label-svg-icon.js +56 -0
  33. package/lib/labels.js +3 -2
  34. package/lib/mark-label.js +168 -57
  35. package/lib/toggle-bar.js +4 -5
  36. package/lib/tool-menu.js +3 -23
  37. package/lib/tools/absolute/__tests__/component.test.js +74 -0
  38. package/lib/tools/absolute/component.js +35 -0
  39. package/lib/tools/absolute/index.js +63 -0
  40. package/lib/tools/circle/__tests__/bg-circle.test.js +46 -0
  41. package/lib/tools/circle/__tests__/component.test.js +259 -0
  42. package/lib/tools/circle/bg-circle.js +5 -4
  43. package/lib/tools/circle/component.js +35 -16
  44. package/lib/tools/circle/index.js +1 -1
  45. package/lib/tools/exponential/__tests__/component.test.js +73 -0
  46. package/lib/tools/exponential/component.js +34 -0
  47. package/lib/tools/exponential/index.js +71 -0
  48. package/lib/tools/index.js +27 -7
  49. package/lib/tools/line/__tests__/component.test.js +56 -0
  50. package/lib/tools/line/component.js +3 -2
  51. package/lib/tools/line/index.js +1 -1
  52. package/lib/tools/parabola/__tests__/component.test.js +73 -0
  53. package/lib/tools/parabola/component.js +7 -6
  54. package/lib/tools/parabola/index.js +1 -1
  55. package/lib/tools/point/__tests__/component.test.js +97 -0
  56. package/lib/tools/point/component.js +15 -10
  57. package/lib/tools/point/index.js +1 -1
  58. package/lib/tools/polygon/__tests__/component.test.js +255 -0
  59. package/lib/tools/polygon/__tests__/index.test.js +95 -0
  60. package/lib/tools/polygon/__tests__/line.test.js +43 -0
  61. package/lib/tools/polygon/__tests__/polygon.test.js +73 -0
  62. package/lib/tools/polygon/component.js +26 -13
  63. package/lib/tools/polygon/index.js +1 -1
  64. package/lib/tools/polygon/line.js +13 -7
  65. package/lib/tools/polygon/polygon.js +7 -4
  66. package/lib/tools/ray/__tests__/component.test.js +48 -0
  67. package/lib/tools/ray/component.js +3 -2
  68. package/lib/tools/ray/index.js +1 -1
  69. package/lib/tools/segment/__tests__/component.test.js +48 -0
  70. package/lib/tools/segment/component.js +3 -2
  71. package/lib/tools/segment/index.js +1 -1
  72. package/lib/tools/shared/__tests__/arrow-head.test.js +62 -0
  73. package/lib/tools/shared/arrow-head.js +1 -1
  74. package/lib/tools/shared/icons/CorrectSVG.js +36 -0
  75. package/lib/tools/shared/icons/IncorrectSVG.js +36 -0
  76. package/lib/tools/shared/icons/MissingSVG.js +35 -0
  77. package/lib/tools/shared/line/__tests__/index.test.js +301 -0
  78. package/lib/tools/shared/line/__tests__/line-path.test.js +78 -0
  79. package/lib/tools/shared/line/__tests__/with-root-edge.test.js +122 -0
  80. package/lib/tools/shared/line/index.js +52 -20
  81. package/lib/tools/shared/line/line-path.js +14 -8
  82. package/lib/tools/shared/line/with-root-edge.js +20 -9
  83. package/lib/tools/shared/point/__tests__/arrow-point.test.js +137 -0
  84. package/lib/tools/shared/point/__tests__/base-point.test.js +134 -0
  85. package/lib/tools/shared/point/arrow-point.js +2 -2
  86. package/lib/tools/shared/point/arrow.js +2 -2
  87. package/lib/tools/shared/point/base-point.js +44 -8
  88. package/lib/tools/shared/point/index.js +5 -2
  89. package/lib/tools/shared/styles.js +17 -8
  90. package/lib/tools/shared/types.js +1 -1
  91. package/lib/tools/sine/__tests__/component.test.js +81 -0
  92. package/lib/tools/sine/component.js +14 -5
  93. package/lib/tools/sine/index.js +1 -1
  94. package/lib/tools/vector/__tests__/component.test.js +45 -0
  95. package/lib/tools/vector/component.js +3 -2
  96. package/lib/tools/vector/index.js +1 -1
  97. package/lib/undo-redo.js +1 -2
  98. package/lib/use-debounce.js +1 -1
  99. package/lib/utils.js +2 -2
  100. package/package.json +7 -7
  101. package/src/__tests__/__snapshots__/graph-with-controls.test.jsx.snap +237 -0
  102. package/src/__tests__/__snapshots__/graph.test.jsx.snap +211 -0
  103. package/src/__tests__/__snapshots__/grid.test.jsx.snap +54 -0
  104. package/src/__tests__/__snapshots__/labels.test.jsx.snap +30 -0
  105. package/src/__tests__/__snapshots__/mark-label.test.jsx.snap +45 -0
  106. package/src/__tests__/__snapshots__/toggle-bar.test.jsx.snap +7 -0
  107. package/src/__tests__/__snapshots__/tool-menu.test.jsx.snap +13 -0
  108. package/src/__tests__/__snapshots__/undo-redo.test.jsx.snap +14 -0
  109. package/src/__tests__/graph-with-controls.test.jsx +147 -0
  110. package/src/__tests__/graph.test.jsx +230 -0
  111. package/src/__tests__/grid.test.jsx +20 -0
  112. package/src/__tests__/labels.test.jsx +38 -0
  113. package/src/__tests__/mark-label.test.jsx +68 -0
  114. package/src/__tests__/toggle-bar.test.jsx +36 -0
  115. package/src/__tests__/tool-menu.test.jsx +29 -0
  116. package/src/__tests__/undo-redo.test.jsx +25 -0
  117. package/src/__tests__/use-debounce.test.js +21 -0
  118. package/src/__tests__/utils.js +38 -0
  119. package/src/__tests__/utils.test.js +151 -0
  120. package/src/axis/__tests__/__snapshots__/arrow.test.jsx.snap +33 -0
  121. package/src/axis/__tests__/__snapshots__/axes.test.jsx.snap +122 -0
  122. package/src/axis/__tests__/arrow.test.jsx +39 -0
  123. package/src/axis/__tests__/axes.test.jsx +220 -0
  124. package/src/axis/axes.jsx +5 -5
  125. package/src/container/index.jsx +2 -4
  126. package/src/coordinates-label.jsx +4 -3
  127. package/src/graph-with-controls.jsx +8 -10
  128. package/src/graph.jsx +22 -10
  129. package/src/grid-setup.jsx +9 -6
  130. package/src/grid.jsx +8 -10
  131. package/src/index.js +2 -2
  132. package/src/key-legend.jsx +115 -0
  133. package/src/label-svg-icon.jsx +39 -0
  134. package/src/labels.jsx +2 -1
  135. package/src/mark-label.jsx +149 -52
  136. package/src/toggle-bar.jsx +1 -2
  137. package/src/tool-menu.jsx +3 -26
  138. package/src/tools/absolute/__tests__/component.test.jsx +54 -0
  139. package/src/tools/absolute/component.jsx +23 -0
  140. package/src/tools/absolute/index.js +31 -0
  141. package/src/tools/circle/__tests__/__snapshots__/bg-circle.test.jsx.snap +46 -0
  142. package/src/tools/circle/__tests__/__snapshots__/component.test.jsx.snap +293 -0
  143. package/src/tools/circle/__tests__/bg-circle.test.jsx +28 -0
  144. package/src/tools/circle/__tests__/component.test.jsx +228 -0
  145. package/src/tools/circle/bg-circle.jsx +5 -4
  146. package/src/tools/circle/component.jsx +22 -8
  147. package/src/tools/exponential/__tests__/component.test.jsx +54 -0
  148. package/src/tools/exponential/component.jsx +23 -0
  149. package/src/tools/exponential/index.js +39 -0
  150. package/src/tools/index.js +38 -5
  151. package/src/tools/line/__tests__/__snapshots__/component.test.jsx.snap +20 -0
  152. package/src/tools/line/__tests__/component.test.jsx +36 -0
  153. package/src/tools/line/component.jsx +2 -1
  154. package/src/tools/parabola/__tests__/component.test.jsx +49 -0
  155. package/src/tools/parabola/component.jsx +7 -6
  156. package/src/tools/point/__tests__/__snapshots__/component.test.jsx.snap +40 -0
  157. package/src/tools/point/__tests__/component.test.jsx +66 -0
  158. package/src/tools/point/component.jsx +12 -6
  159. package/src/tools/polygon/__tests__/__snapshots__/component.test.jsx.snap +415 -0
  160. package/src/tools/polygon/__tests__/__snapshots__/line.test.jsx.snap +45 -0
  161. package/src/tools/polygon/__tests__/__snapshots__/polygon.test.jsx.snap +52 -0
  162. package/src/tools/polygon/__tests__/component.test.jsx +226 -0
  163. package/src/tools/polygon/__tests__/index.test.js +65 -0
  164. package/src/tools/polygon/__tests__/line.test.jsx +25 -0
  165. package/src/tools/polygon/__tests__/polygon.test.jsx +44 -0
  166. package/src/tools/polygon/component.jsx +39 -11
  167. package/src/tools/polygon/line.jsx +15 -7
  168. package/src/tools/polygon/polygon.jsx +7 -3
  169. package/src/tools/ray/__tests__/__snapshots__/component.test.jsx.snap +23 -0
  170. package/src/tools/ray/__tests__/component.test.jsx +29 -0
  171. package/src/tools/ray/component.jsx +2 -1
  172. package/src/tools/segment/__tests__/__snapshots__/component.test.jsx.snap +14 -0
  173. package/src/tools/segment/__tests__/component.test.jsx +28 -0
  174. package/src/tools/segment/component.jsx +2 -1
  175. package/src/tools/shared/__tests__/__snapshots__/arrow-head.test.jsx.snap +27 -0
  176. package/src/tools/shared/__tests__/arrow-head.test.jsx +34 -0
  177. package/src/tools/shared/icons/CorrectSVG.jsx +22 -0
  178. package/src/tools/shared/icons/IncorrectSVG.jsx +20 -0
  179. package/src/tools/shared/icons/MissingSVG.jsx +21 -0
  180. package/src/tools/shared/line/__tests__/__snapshots__/index.test.jsx.snap +360 -0
  181. package/src/tools/shared/line/__tests__/__snapshots__/line-path.test.jsx.snap +58 -0
  182. package/src/tools/shared/line/__tests__/__snapshots__/with-root-edge.test.jsx.snap +63 -0
  183. package/src/tools/shared/line/__tests__/index.test.jsx +255 -0
  184. package/src/tools/shared/line/__tests__/line-path.test.jsx +53 -0
  185. package/src/tools/shared/line/__tests__/with-root-edge.test.jsx +73 -0
  186. package/src/tools/shared/line/index.jsx +39 -13
  187. package/src/tools/shared/line/line-path.jsx +18 -7
  188. package/src/tools/shared/line/with-root-edge.jsx +10 -3
  189. package/src/tools/shared/point/__tests__/__snapshots__/arrow-point.test.jsx.snap +56 -0
  190. package/src/tools/shared/point/__tests__/__snapshots__/base-point.test.jsx.snap +44 -0
  191. package/src/tools/shared/point/__tests__/arrow-point.test.jsx +87 -0
  192. package/src/tools/shared/point/__tests__/base-point.test.jsx +84 -0
  193. package/src/tools/shared/point/arrow-point.jsx +4 -1
  194. package/src/tools/shared/point/arrow.jsx +4 -1
  195. package/src/tools/shared/point/base-point.jsx +28 -3
  196. package/src/tools/shared/point/index.jsx +7 -2
  197. package/src/tools/shared/styles.js +8 -3
  198. package/src/tools/sine/__tests__/component.test.jsx +51 -0
  199. package/src/tools/sine/component.jsx +7 -7
  200. package/src/tools/vector/__tests__/__snapshots__/component.test.jsx.snap +12 -0
  201. package/src/tools/vector/__tests__/component.test.jsx +26 -0
  202. package/src/tools/vector/component.jsx +2 -1
  203. package/src/undo-redo.jsx +0 -1
  204. package/src/utils.js +1 -1
  205. package/legacy.png +0 -0
  206. package/lib/axis/arrow.js.map +0 -1
  207. package/lib/axis/axes.js.map +0 -1
  208. package/lib/axis/index.js.map +0 -1
  209. package/lib/bg.js.map +0 -1
  210. package/lib/container/actions.js.map +0 -1
  211. package/lib/container/index.js.map +0 -1
  212. package/lib/container/marks.js.map +0 -1
  213. package/lib/container/middleware.js.map +0 -1
  214. package/lib/container/reducer.js.map +0 -1
  215. package/lib/coordinates-label.js.map +0 -1
  216. package/lib/graph-with-controls.js.map +0 -1
  217. package/lib/graph.js.map +0 -1
  218. package/lib/grid-setup.js.map +0 -1
  219. package/lib/grid.js.map +0 -1
  220. package/lib/index.js.map +0 -1
  221. package/lib/labels.js.map +0 -1
  222. package/lib/mark-label.js.map +0 -1
  223. package/lib/toggle-bar.js.map +0 -1
  224. package/lib/tool-menu.js.map +0 -1
  225. package/lib/tools/circle/bg-circle.js.map +0 -1
  226. package/lib/tools/circle/component.js.map +0 -1
  227. package/lib/tools/circle/index.js.map +0 -1
  228. package/lib/tools/index.js.map +0 -1
  229. package/lib/tools/line/component.js.map +0 -1
  230. package/lib/tools/line/index.js.map +0 -1
  231. package/lib/tools/parabola/component.js.map +0 -1
  232. package/lib/tools/parabola/index.js.map +0 -1
  233. package/lib/tools/point/component.js.map +0 -1
  234. package/lib/tools/point/index.js.map +0 -1
  235. package/lib/tools/polygon/component.js.map +0 -1
  236. package/lib/tools/polygon/index.js.map +0 -1
  237. package/lib/tools/polygon/line.js.map +0 -1
  238. package/lib/tools/polygon/polygon.js.map +0 -1
  239. package/lib/tools/ray/component.js.map +0 -1
  240. package/lib/tools/ray/index.js.map +0 -1
  241. package/lib/tools/segment/component.js.map +0 -1
  242. package/lib/tools/segment/index.js.map +0 -1
  243. package/lib/tools/shared/arrow-head.js.map +0 -1
  244. package/lib/tools/shared/line/index.js.map +0 -1
  245. package/lib/tools/shared/line/line-path.js.map +0 -1
  246. package/lib/tools/shared/line/with-root-edge.js.map +0 -1
  247. package/lib/tools/shared/point/arrow-point.js.map +0 -1
  248. package/lib/tools/shared/point/arrow.js.map +0 -1
  249. package/lib/tools/shared/point/base-point.js.map +0 -1
  250. package/lib/tools/shared/point/index.js.map +0 -1
  251. package/lib/tools/shared/styles.js.map +0 -1
  252. package/lib/tools/shared/types.js.map +0 -1
  253. package/lib/tools/sine/component.js.map +0 -1
  254. package/lib/tools/sine/index.js.map +0 -1
  255. package/lib/tools/vector/component.js.map +0 -1
  256. package/lib/tools/vector/index.js.map +0 -1
  257. package/lib/undo-redo.js.map +0 -1
  258. package/lib/use-debounce.js.map +0 -1
  259. package/lib/utils.js.map +0 -1
@@ -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
+ `;