@pie-lib/graphing 2.14.21 → 2.14.22-next.1618

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 (194) hide show
  1. package/CHANGELOG.json +1 -1017
  2. package/CHANGELOG.md +159 -24
  3. package/NEXT.CHANGELOG.json +1 -0
  4. package/lib/axis/axes.js +5 -5
  5. package/lib/axis/axes.js.map +1 -1
  6. package/lib/container/index.js +1 -4
  7. package/lib/container/index.js.map +1 -1
  8. package/lib/coordinates-label.js +5 -3
  9. package/lib/coordinates-label.js.map +1 -1
  10. package/lib/graph-with-controls.js +8 -15
  11. package/lib/graph-with-controls.js.map +1 -1
  12. package/lib/graph.js +29 -12
  13. package/lib/graph.js.map +1 -1
  14. package/lib/grid.js +6 -14
  15. package/lib/grid.js.map +1 -1
  16. package/lib/index.js +8 -0
  17. package/lib/index.js.map +1 -1
  18. package/lib/key-legend.js +246 -0
  19. package/lib/key-legend.js.map +1 -0
  20. package/lib/label-svg-icon.js +56 -0
  21. package/lib/label-svg-icon.js.map +1 -0
  22. package/lib/labels.js +2 -1
  23. package/lib/labels.js.map +1 -1
  24. package/lib/mark-label.js +167 -56
  25. package/lib/mark-label.js.map +1 -1
  26. package/lib/toggle-bar.js +3 -4
  27. package/lib/toggle-bar.js.map +1 -1
  28. package/lib/tool-menu.js +2 -22
  29. package/lib/tool-menu.js.map +1 -1
  30. package/lib/tools/absolute/component.js +35 -0
  31. package/lib/tools/absolute/component.js.map +1 -0
  32. package/lib/tools/absolute/index.js +63 -0
  33. package/lib/tools/absolute/index.js.map +1 -0
  34. package/lib/tools/circle/bg-circle.js +4 -3
  35. package/lib/tools/circle/bg-circle.js.map +1 -1
  36. package/lib/tools/circle/component.js +34 -15
  37. package/lib/tools/circle/component.js.map +1 -1
  38. package/lib/tools/exponential/component.js +34 -0
  39. package/lib/tools/exponential/component.js.map +1 -0
  40. package/lib/tools/exponential/index.js +71 -0
  41. package/lib/tools/exponential/index.js.map +1 -0
  42. package/lib/tools/index.js +26 -6
  43. package/lib/tools/index.js.map +1 -1
  44. package/lib/tools/line/component.js +2 -1
  45. package/lib/tools/line/component.js.map +1 -1
  46. package/lib/tools/parabola/component.js +6 -5
  47. package/lib/tools/parabola/component.js.map +1 -1
  48. package/lib/tools/point/component.js +14 -9
  49. package/lib/tools/point/component.js.map +1 -1
  50. package/lib/tools/polygon/component.js +25 -12
  51. package/lib/tools/polygon/component.js.map +1 -1
  52. package/lib/tools/polygon/line.js +12 -6
  53. package/lib/tools/polygon/line.js.map +1 -1
  54. package/lib/tools/polygon/polygon.js +6 -3
  55. package/lib/tools/polygon/polygon.js.map +1 -1
  56. package/lib/tools/ray/component.js +2 -1
  57. package/lib/tools/ray/component.js.map +1 -1
  58. package/lib/tools/segment/component.js +2 -1
  59. package/lib/tools/segment/component.js.map +1 -1
  60. package/lib/tools/shared/icons/CorrectSVG.js +36 -0
  61. package/lib/tools/shared/icons/CorrectSVG.js.map +1 -0
  62. package/lib/tools/shared/icons/IncorrectSVG.js +36 -0
  63. package/lib/tools/shared/icons/IncorrectSVG.js.map +1 -0
  64. package/lib/tools/shared/icons/MissingSVG.js +35 -0
  65. package/lib/tools/shared/icons/MissingSVG.js.map +1 -0
  66. package/lib/tools/shared/line/index.js +51 -19
  67. package/lib/tools/shared/line/index.js.map +1 -1
  68. package/lib/tools/shared/line/line-path.js +13 -7
  69. package/lib/tools/shared/line/line-path.js.map +1 -1
  70. package/lib/tools/shared/line/with-root-edge.js +19 -8
  71. package/lib/tools/shared/line/with-root-edge.js.map +1 -1
  72. package/lib/tools/shared/point/arrow-point.js +1 -1
  73. package/lib/tools/shared/point/arrow-point.js.map +1 -1
  74. package/lib/tools/shared/point/arrow.js +1 -1
  75. package/lib/tools/shared/point/arrow.js.map +1 -1
  76. package/lib/tools/shared/point/base-point.js +43 -7
  77. package/lib/tools/shared/point/base-point.js.map +1 -1
  78. package/lib/tools/shared/point/index.js +4 -1
  79. package/lib/tools/shared/point/index.js.map +1 -1
  80. package/lib/tools/shared/styles.js +16 -7
  81. package/lib/tools/shared/styles.js.map +1 -1
  82. package/lib/tools/sine/component.js +13 -4
  83. package/lib/tools/sine/component.js.map +1 -1
  84. package/lib/tools/vector/component.js +2 -1
  85. package/lib/tools/vector/component.js.map +1 -1
  86. package/lib/undo-redo.js +0 -1
  87. package/lib/undo-redo.js.map +1 -1
  88. package/lib/utils.js +1 -1
  89. package/lib/utils.js.map +1 -1
  90. package/package.json +12 -7
  91. package/src/__tests__/__snapshots__/graph-with-controls.test.jsx.snap +237 -0
  92. package/src/__tests__/__snapshots__/graph.test.jsx.snap +211 -0
  93. package/src/__tests__/__snapshots__/grid.test.jsx.snap +54 -0
  94. package/src/__tests__/__snapshots__/labels.test.jsx.snap +30 -0
  95. package/src/__tests__/__snapshots__/mark-label.test.jsx.snap +45 -0
  96. package/src/__tests__/__snapshots__/toggle-bar.test.jsx.snap +7 -0
  97. package/src/__tests__/__snapshots__/tool-menu.test.jsx.snap +13 -0
  98. package/src/__tests__/__snapshots__/undo-redo.test.jsx.snap +14 -0
  99. package/src/__tests__/graph-with-controls.test.jsx +147 -0
  100. package/src/__tests__/graph.test.jsx +230 -0
  101. package/src/__tests__/grid.test.jsx +20 -0
  102. package/src/__tests__/labels.test.jsx +38 -0
  103. package/src/__tests__/mark-label.test.jsx +68 -0
  104. package/src/__tests__/toggle-bar.test.jsx +36 -0
  105. package/src/__tests__/tool-menu.test.jsx +29 -0
  106. package/src/__tests__/undo-redo.test.jsx +25 -0
  107. package/src/__tests__/use-debounce.test.js +21 -0
  108. package/src/__tests__/utils.js +38 -0
  109. package/src/__tests__/utils.test.js +151 -0
  110. package/src/axis/__tests__/__snapshots__/arrow.test.jsx.snap +33 -0
  111. package/src/axis/__tests__/__snapshots__/axes.test.jsx.snap +122 -0
  112. package/src/axis/__tests__/arrow.test.jsx +39 -0
  113. package/src/axis/__tests__/axes.test.jsx +220 -0
  114. package/src/axis/axes.jsx +5 -5
  115. package/src/container/index.jsx +2 -4
  116. package/src/coordinates-label.jsx +4 -3
  117. package/src/graph-with-controls.jsx +8 -10
  118. package/src/graph.jsx +22 -10
  119. package/src/grid.jsx +8 -10
  120. package/src/index.js +2 -2
  121. package/src/key-legend.jsx +145 -0
  122. package/src/label-svg-icon.jsx +39 -0
  123. package/src/labels.jsx +2 -1
  124. package/src/mark-label.jsx +149 -52
  125. package/src/toggle-bar.jsx +1 -2
  126. package/src/tool-menu.jsx +3 -26
  127. package/src/tools/absolute/__tests__/component.test.jsx +54 -0
  128. package/src/tools/absolute/component.jsx +23 -0
  129. package/src/tools/absolute/index.js +31 -0
  130. package/src/tools/circle/__tests__/__snapshots__/bg-circle.test.jsx.snap +46 -0
  131. package/src/tools/circle/__tests__/__snapshots__/component.test.jsx.snap +293 -0
  132. package/src/tools/circle/__tests__/bg-circle.test.jsx +28 -0
  133. package/src/tools/circle/__tests__/component.test.jsx +228 -0
  134. package/src/tools/circle/bg-circle.jsx +5 -4
  135. package/src/tools/circle/component.jsx +22 -8
  136. package/src/tools/exponential/__tests__/component.test.jsx +54 -0
  137. package/src/tools/exponential/component.jsx +23 -0
  138. package/src/tools/exponential/index.js +39 -0
  139. package/src/tools/index.js +38 -5
  140. package/src/tools/line/__tests__/__snapshots__/component.test.jsx.snap +20 -0
  141. package/src/tools/line/__tests__/component.test.jsx +36 -0
  142. package/src/tools/line/component.jsx +2 -1
  143. package/src/tools/parabola/__tests__/component.test.jsx +49 -0
  144. package/src/tools/parabola/component.jsx +7 -6
  145. package/src/tools/point/__tests__/__snapshots__/component.test.jsx.snap +40 -0
  146. package/src/tools/point/__tests__/component.test.jsx +66 -0
  147. package/src/tools/point/component.jsx +12 -6
  148. package/src/tools/polygon/__tests__/__snapshots__/component.test.jsx.snap +415 -0
  149. package/src/tools/polygon/__tests__/__snapshots__/line.test.jsx.snap +45 -0
  150. package/src/tools/polygon/__tests__/__snapshots__/polygon.test.jsx.snap +52 -0
  151. package/src/tools/polygon/__tests__/component.test.jsx +226 -0
  152. package/src/tools/polygon/__tests__/index.test.js +65 -0
  153. package/src/tools/polygon/__tests__/line.test.jsx +25 -0
  154. package/src/tools/polygon/__tests__/polygon.test.jsx +44 -0
  155. package/src/tools/polygon/component.jsx +39 -11
  156. package/src/tools/polygon/line.jsx +15 -7
  157. package/src/tools/polygon/polygon.jsx +7 -3
  158. package/src/tools/ray/__tests__/__snapshots__/component.test.jsx.snap +23 -0
  159. package/src/tools/ray/__tests__/component.test.jsx +29 -0
  160. package/src/tools/ray/component.jsx +2 -1
  161. package/src/tools/segment/__tests__/__snapshots__/component.test.jsx.snap +14 -0
  162. package/src/tools/segment/__tests__/component.test.jsx +28 -0
  163. package/src/tools/segment/component.jsx +2 -1
  164. package/src/tools/shared/__tests__/__snapshots__/arrow-head.test.jsx.snap +27 -0
  165. package/src/tools/shared/__tests__/arrow-head.test.jsx +34 -0
  166. package/src/tools/shared/icons/CorrectSVG.jsx +22 -0
  167. package/src/tools/shared/icons/IncorrectSVG.jsx +20 -0
  168. package/src/tools/shared/icons/MissingSVG.jsx +21 -0
  169. package/src/tools/shared/line/__tests__/__snapshots__/index.test.jsx.snap +360 -0
  170. package/src/tools/shared/line/__tests__/__snapshots__/line-path.test.jsx.snap +58 -0
  171. package/src/tools/shared/line/__tests__/__snapshots__/with-root-edge.test.jsx.snap +63 -0
  172. package/src/tools/shared/line/__tests__/index.test.jsx +255 -0
  173. package/src/tools/shared/line/__tests__/line-path.test.jsx +53 -0
  174. package/src/tools/shared/line/__tests__/with-root-edge.test.jsx +73 -0
  175. package/src/tools/shared/line/index.jsx +39 -13
  176. package/src/tools/shared/line/line-path.jsx +18 -7
  177. package/src/tools/shared/line/with-root-edge.jsx +10 -3
  178. package/src/tools/shared/point/__tests__/__snapshots__/arrow-point.test.jsx.snap +56 -0
  179. package/src/tools/shared/point/__tests__/__snapshots__/base-point.test.jsx.snap +44 -0
  180. package/src/tools/shared/point/__tests__/arrow-point.test.jsx +87 -0
  181. package/src/tools/shared/point/__tests__/base-point.test.jsx +84 -0
  182. package/src/tools/shared/point/arrow-point.jsx +4 -1
  183. package/src/tools/shared/point/arrow.jsx +4 -1
  184. package/src/tools/shared/point/base-point.jsx +28 -3
  185. package/src/tools/shared/point/index.jsx +7 -2
  186. package/src/tools/shared/styles.js +8 -3
  187. package/src/tools/sine/__tests__/component.test.jsx +51 -0
  188. package/src/tools/sine/component.jsx +7 -7
  189. package/src/tools/vector/__tests__/__snapshots__/component.test.jsx.snap +12 -0
  190. package/src/tools/vector/__tests__/component.test.jsx +26 -0
  191. package/src/tools/vector/component.jsx +2 -1
  192. package/src/undo-redo.jsx +0 -1
  193. package/src/utils.js +1 -1
  194. package/legacy.png +0 -0
@@ -0,0 +1,228 @@
1
+ import { shallow } from 'enzyme';
2
+ import React from 'react';
3
+ import { graphProps, xy } from '../../../__tests__/utils';
4
+
5
+ import { RawBaseCircle } from '../component';
6
+
7
+ const xyLabel = (x, y, label) => ({ x, y, label });
8
+
9
+ describe('Component', () => {
10
+ let w;
11
+ let onChange = jest.fn();
12
+ let changeMarkProps = jest.fn();
13
+
14
+ const wrapper = (extras) => {
15
+ const defaults = {
16
+ classes: {},
17
+ className: 'className',
18
+ onChange,
19
+ changeMarkProps,
20
+ graphProps: graphProps(),
21
+ from: xy(0, 0),
22
+ to: xy(1, 1),
23
+ };
24
+ const props = { ...defaults, ...extras };
25
+
26
+ return shallow(<RawBaseCircle {...props} />);
27
+ };
28
+
29
+ // used to test items that have labels attached to points
30
+ const labelNode = document.createElement('foreignObject');
31
+ const fromWithLabel = { x: 0, y: 0, label: 'A' };
32
+ const toWithLabel = { x: 1, y: 1, label: 'B' };
33
+ const wrapperWithLabels = (extras = {}) =>
34
+ wrapper({
35
+ ...extras,
36
+ labelNode: labelNode,
37
+ from: fromWithLabel,
38
+ to: toWithLabel,
39
+ });
40
+
41
+ describe('snapshot', () => {
42
+ it('renders', () => {
43
+ w = wrapper();
44
+ expect(w).toMatchSnapshot();
45
+ });
46
+
47
+ it('renders with labels', () => {
48
+ w = wrapperWithLabels();
49
+
50
+ expect(w).toMatchSnapshot();
51
+ });
52
+ });
53
+
54
+ describe('logic', () => {
55
+ beforeEach(() => (w = wrapper()));
56
+
57
+ describe('dragFrom', () => {
58
+ it('calls onChange', () => {
59
+ w = wrapper();
60
+ w.instance().dragFrom(xy(1, 1));
61
+ expect(onChange).not.toHaveBeenCalledWith({
62
+ from: xy(1, 1),
63
+ to: xy(1, 1),
64
+ });
65
+
66
+ w.instance().dragFrom(xy(2, 2));
67
+ expect(onChange).toHaveBeenCalledWith({
68
+ from: xy(2, 2),
69
+ to: xy(1, 1),
70
+ });
71
+ });
72
+ });
73
+
74
+ describe('dragFrom keeps labels on "from"', () => {
75
+ it('calls onChange', () => {
76
+ w = wrapperWithLabels();
77
+
78
+ // drag "from" to { x: 1, y: 1 }
79
+ w.instance().dragFrom({ x: 1, y: 1 });
80
+
81
+ // won't change because points overlap
82
+ expect(onChange).not.toHaveBeenCalledWith({
83
+ from: xyLabel(1, 1, 'A'),
84
+ to: toWithLabel,
85
+ });
86
+
87
+ // wil change and will keep labels
88
+ w.instance().dragFrom({ x: 2, y: 2 });
89
+ expect(onChange).toHaveBeenCalledWith({
90
+ from: xyLabel(2, 2, 'A'),
91
+ to: toWithLabel,
92
+ });
93
+ });
94
+ });
95
+
96
+ describe('dragTo', () => {
97
+ it('calls onChange', () => {
98
+ w.instance().dragTo(xy(4, 4));
99
+ expect(onChange).toHaveBeenCalledWith({
100
+ from: xy(0, 0),
101
+ to: xy(4, 4),
102
+ });
103
+ });
104
+ });
105
+
106
+ describe('dragTo keeps labels on "to"', () => {
107
+ it('calls onChange', () => {
108
+ w = wrapperWithLabels();
109
+
110
+ // won't change because points overlap
111
+ w.instance().dragTo({ x: 0, y: 0 });
112
+ expect(onChange).not.toHaveBeenCalledWith({
113
+ from: fromWithLabel,
114
+ to: xyLabel(1, 1, 'B'),
115
+ });
116
+
117
+ // wil change and will keep labels
118
+ w.instance().dragTo({ x: 2, y: 2 });
119
+ expect(onChange).toHaveBeenCalledWith({
120
+ from: fromWithLabel,
121
+ to: xyLabel(2, 2, 'B'),
122
+ });
123
+ });
124
+ });
125
+
126
+ describe('dragCircle', () => {
127
+ it('calls onChange', () => {
128
+ w.instance().dragCircle(xy(1, 1));
129
+ expect(onChange).toHaveBeenCalledWith({
130
+ from: xy(1, 1),
131
+ to: xy(2, 2),
132
+ });
133
+ });
134
+ });
135
+
136
+ describe('dragCircle keeps labels on both "from" and "to"', () => {
137
+ it('calls onChange', () => {
138
+ w = wrapperWithLabels();
139
+
140
+ // wil change and will keep labels
141
+ w.instance().dragCircle({ x: 10, y: 10 });
142
+ expect(onChange).toHaveBeenCalledWith({
143
+ from: xyLabel(10, 10, 'A'),
144
+ to: xyLabel(11, 11, 'B'),
145
+ });
146
+
147
+ // wil change and will keep labels
148
+ w.instance().dragCircle({ x: 2, y: 2 });
149
+ expect(onChange).toHaveBeenCalledWith({
150
+ from: xyLabel(2, 2, 'A'),
151
+ to: xyLabel(3, 3, 'B'),
152
+ });
153
+ });
154
+ });
155
+
156
+ describe('labelChange', () => {
157
+ it('updates "label" property for point', () => {
158
+ w = wrapperWithLabels({ labelModeEnabled: true });
159
+
160
+ w.instance().labelChange(xyLabel(0, 0, 'Label A'), 'from');
161
+ expect(changeMarkProps).toBeCalledWith({
162
+ from: xyLabel(0, 0, 'Label A'),
163
+ });
164
+
165
+ w.instance().labelChange(xyLabel(0, 0, 'Label B'), 'to');
166
+ expect(changeMarkProps).toBeCalledWith({
167
+ to: xyLabel(0, 0, 'Label B'),
168
+ });
169
+ });
170
+
171
+ it('removes "label" property if the field is empty', () => {
172
+ w = wrapperWithLabels({ labelModeEnabled: true });
173
+
174
+ w.instance().labelChange(xyLabel(0, 0, ''), 'from');
175
+ expect(changeMarkProps).toBeCalledWith({
176
+ from: xy(0, 0),
177
+ });
178
+
179
+ w.instance().labelChange(xyLabel(0, 0, ''), 'to');
180
+ expect(changeMarkProps).toBeCalledWith({
181
+ to: xy(0, 0),
182
+ });
183
+ });
184
+ });
185
+
186
+ describe('clickPoint', () => {
187
+ it('adds "label" property to a point', () => {
188
+ w = wrapperWithLabels({ labelModeEnabled: true });
189
+
190
+ w.instance().clickPoint(xy(0, 0), 'from');
191
+ expect(changeMarkProps).toBeCalledWith({
192
+ from: xyLabel(0, 0, ''),
193
+ to: xyLabel(1, 1, 'B'),
194
+ });
195
+
196
+ w.instance().clickPoint(xy(1, 1), 'to');
197
+ expect(changeMarkProps).toBeCalledWith({
198
+ from: xyLabel(0, 0, 'A'),
199
+ to: xyLabel(1, 1, ''),
200
+ });
201
+ });
202
+
203
+ it('adds "label" property to a point when limit labeling', () => {
204
+ const changeMarkProps = jest.fn();
205
+ w = wrapperWithLabels({ labelModeEnabled: true, limitLabeling: true, changeMarkProps });
206
+
207
+ w.instance().clickPoint(xy(0, 0), 'from');
208
+ expect(changeMarkProps).toHaveBeenCalledTimes(0);
209
+ });
210
+
211
+ it('if point already has label, keeps that value', () => {
212
+ w = wrapperWithLabels({ labelModeEnabled: true });
213
+
214
+ w.instance().clickPoint(fromWithLabel, 'from');
215
+ expect(changeMarkProps).toBeCalledWith({
216
+ from: fromWithLabel,
217
+ to: xyLabel(1, 1, 'B'),
218
+ });
219
+
220
+ w.instance().clickPoint(toWithLabel, 'to');
221
+ expect(changeMarkProps).toBeCalledWith({
222
+ from: xyLabel(0, 0, 'A'),
223
+ to: toWithLabel,
224
+ });
225
+ });
226
+ });
227
+ });
228
+ });
@@ -5,7 +5,7 @@ import classNames from 'classnames';
5
5
  import { types, gridDraggable } from '@pie-lib/plot';
6
6
  import { color } from '@pie-lib/render-ui';
7
7
  import * as utils from '../../utils';
8
- import { disabled, correct, incorrect, missing } from '../shared/styles';
8
+ import { disabled, disabledSecondary, correct, incorrect, missing } from '../shared/styles';
9
9
 
10
10
  /**
11
11
  * A low level circle component
@@ -33,7 +33,7 @@ class RawCircle extends React.Component {
33
33
 
34
34
  return (
35
35
  <ellipse
36
- className={classNames(classes.bgCircle, disabled && classes.disabled, classes[correctness], className)}
36
+ className={classNames(classes.bgCircle, disabled && classes.disabledSecondary, classes[correctness], className)}
37
37
  cx={scale.x(x)}
38
38
  cy={scale.y(y)}
39
39
  rx={rx}
@@ -55,15 +55,16 @@ const applyStyle = (fn) => ({
55
55
  const styles = () => ({
56
56
  bgCircle: {
57
57
  fill: 'transparent',
58
- stroke: color.primaryLight(),
58
+ stroke: color.defaults.BLACK,
59
59
  strokeWidth: 3,
60
60
  transition: 'stroke 200ms ease-in, stroke-width 200ms ease-in',
61
61
  '&:hover': {
62
62
  strokeWidth: 6,
63
- stroke: color.primaryDark(),
63
+ stroke: color.defaults.PRIMARY_DARK,
64
64
  },
65
65
  },
66
66
  disabled: applyStyle(disabled),
67
+ disabledSecondary: applyStyle(disabledSecondary),
67
68
  correct: applyStyle(correct),
68
69
  incorrect: applyStyle(incorrect),
69
70
  missing: applyStyle(missing),
@@ -42,6 +42,7 @@ export class RawBaseCircle extends React.Component {
42
42
  labelNode: PropTypes.object,
43
43
  labelModeEnabled: PropTypes.bool,
44
44
  changeMarkProps: PropTypes.func,
45
+ limitLabeling: PropTypes.bool,
45
46
  };
46
47
 
47
48
  static defaultProps = {
@@ -128,8 +129,21 @@ export class RawBaseCircle extends React.Component {
128
129
  changeMarkProps({ [type]: update });
129
130
  };
130
131
 
131
- clickPoint = (point, type) => {
132
- const { changeMarkProps, from, to } = this.props;
132
+ clickPoint = (point, type, data) => {
133
+ const { changeMarkProps, disabled, from, to, labelModeEnabled, limitLabeling, onClick } = this.props;
134
+ if (!labelModeEnabled) {
135
+ onClick(point || data);
136
+ return;
137
+ }
138
+
139
+ if (disabled) {
140
+ return;
141
+ }
142
+
143
+ // limit labeling the points of the circle
144
+ if (limitLabeling) {
145
+ return;
146
+ }
133
147
 
134
148
  if (type === 'middle' && !point && from && to) {
135
149
  point = { ...point, ...getMiddleOfTwoPoints(from, to) };
@@ -224,7 +238,7 @@ export class RawBaseCircle extends React.Component {
224
238
  radius={radius}
225
239
  onDrag={this.dragCircle}
226
240
  {...common}
227
- onClick={labelModeEnabled ? () => this.clickPoint(middle, 'middle') : common.onClick}
241
+ onClick={(data) => this.clickPoint(middle, 'middle', data)}
228
242
  />
229
243
  {circleLabelNode}
230
244
 
@@ -237,7 +251,7 @@ export class RawBaseCircle extends React.Component {
237
251
  y={to.y}
238
252
  onDrag={this.dragTo}
239
253
  {...common}
240
- onClick={labelModeEnabled ? () => this.clickPoint(to, 'to') : common.onClick}
254
+ onClick={(data) => this.clickPoint(to, 'to', data)}
241
255
  />
242
256
  {toLabelNode}
243
257
 
@@ -251,7 +265,7 @@ export class RawBaseCircle extends React.Component {
251
265
  className={classes.from}
252
266
  onDrag={this.dragFrom}
253
267
  {...common}
254
- onClick={labelModeEnabled ? () => this.clickPoint(from, 'from') : common.onClick}
268
+ onClick={(data) => this.clickPoint(from, 'from', data)}
255
269
  />
256
270
  {fromLabelNode}
257
271
  </g>
@@ -262,16 +276,16 @@ export class RawBaseCircle extends React.Component {
262
276
  export const BaseCircle = withStyles(() => ({
263
277
  outerLine: {
264
278
  fill: 'rgb(0,0,0,0)', // TODO hardcoded color
265
- stroke: color.primaryLight(),
279
+ stroke: color.defaults.BLACK,
266
280
  strokeWidth: 4,
267
281
  '&:hover': {
268
282
  strokeWidth: 6,
269
- stroke: color.primaryDark(),
283
+ stroke: color.defaults.PRIMARY_DARK,
270
284
  },
271
285
  },
272
286
  root: {},
273
287
  bgCircleBuilding: {
274
- stroke: color.secondaryLight(),
288
+ stroke: color.defaults.BLACK,
275
289
  animation: 'opacityPulse 2s ease-out',
276
290
  animationIterationCount: 'infinite',
277
291
  opacity: 1,
@@ -0,0 +1,54 @@
1
+ import React from 'react';
2
+ import { withRootEdge } from '../../shared/line/with-root-edge';
3
+ import { buildDataPoints, exponentialFromTwoPoints } from '@pie-lib/graphing-utils';
4
+ import { utils } from '@pie-lib/plot';
5
+
6
+ import { graphProps as getGraphProps } from '../../../__tests__/utils';
7
+
8
+ const { xy } = utils;
9
+
10
+ jest.mock('@pie-lib/graphing-utils', () => ({
11
+ buildDataPoints: jest.fn().mockReturnValue([]),
12
+ exponentialFromTwoPoints: jest.fn(() => jest.fn()),
13
+ getAmplitudeAndFreq: jest.fn().mockReturnValue({ freq: 4, amplitude: 1 }),
14
+ }));
15
+
16
+ jest.mock('../../shared/line/with-root-edge', () => ({
17
+ withRootEdge: jest.fn(),
18
+ rootEdgeComponent: jest.fn(),
19
+ }));
20
+
21
+ describe('Exponential', () => {
22
+ let fnBody;
23
+ let graphProps;
24
+ let root;
25
+ let edge;
26
+ let result;
27
+
28
+ beforeEach(() => {
29
+ require('../component');
30
+ fnBody = withRootEdge.mock.calls[0][0];
31
+ graphProps = getGraphProps();
32
+ root = xy(1, 1);
33
+ edge = xy(2, 2);
34
+
35
+ result = fnBody({ graphProps, root, edge });
36
+ });
37
+
38
+ it('fnBody is not null', () => {
39
+ expect(fnBody).toBeDefined();
40
+ });
41
+
42
+ it('calls buildDataPoints', () => {
43
+ const { domain, range } = graphProps;
44
+ expect(buildDataPoints).toHaveBeenCalledWith(domain, range, root, edge, expect.anything(), true);
45
+ });
46
+
47
+ it('calls exponentialFromTwoPoints', () => {
48
+ expect(exponentialFromTwoPoints).toHaveBeenCalledWith(root, edge);
49
+ });
50
+
51
+ it('returns dataPoints', () => {
52
+ expect(result).toEqual({ root, edge, dataPoints: [] });
53
+ });
54
+ });
@@ -0,0 +1,23 @@
1
+ import debug from 'debug';
2
+ import { buildDataPoints, exponentialFromTwoPoints } from '@pie-lib/graphing-utils';
3
+ import { withRootEdge, rootEdgeComponent } from '../shared/line/with-root-edge';
4
+
5
+ const log = debug('pie-lib:graphing:exponential');
6
+
7
+ const Exponential = withRootEdge((props) => {
8
+ const { root, edge, graphProps } = props;
9
+ const { domain, range } = graphProps;
10
+
11
+ const dataPoints =
12
+ edge && edge.x === root.x
13
+ ? []
14
+ : buildDataPoints(domain, range, root, edge, exponentialFromTwoPoints(root, edge), true);
15
+
16
+ log('dataPoints:', dataPoints);
17
+
18
+ return { root: props.root, edge: props.edge, dataPoints };
19
+ });
20
+
21
+ const Component = rootEdgeComponent(Exponential);
22
+
23
+ export default Component;
@@ -0,0 +1,39 @@
1
+ import Exponential from './component';
2
+ import debug from 'debug';
3
+ import { equalPoints, sameAxes } from '../../utils';
4
+
5
+ const log = debug('pie-lib:graphing:exponential');
6
+
7
+ export const tool = () => ({
8
+ type: 'exponential',
9
+ Component: Exponential,
10
+ complete: (data, mark) => ({ ...mark, building: false, closed: true }),
11
+ addPoint: (point, mark) => {
12
+ log('add point to exponential model: ', point, 'mark: ', mark);
13
+ if (mark && (equalPoints(mark.root, point) || sameAxes(mark.root, point))) {
14
+ return mark;
15
+ }
16
+
17
+ if (mark && mark.root.y * point.y < 0) {
18
+ return mark;
19
+ }
20
+
21
+ if (point.y === 0) {
22
+ return mark;
23
+ }
24
+
25
+ if (!mark) {
26
+ return {
27
+ type: 'exponential',
28
+ root: point,
29
+ edge: undefined,
30
+ closed: false,
31
+ building: true,
32
+ };
33
+ } else if (mark && !mark.root) {
34
+ throw new Error('no root - should never happen');
35
+ } else {
36
+ return { ...mark, edge: point, closed: true, building: false };
37
+ }
38
+ },
39
+ });
@@ -1,15 +1,48 @@
1
1
  import { tool as point } from './point';
2
2
  import { tool as circle } from './circle';
3
3
  import { tool as polygon } from './polygon';
4
- import { tool as sine } from './sine/index';
5
- import { tool as parabola } from './parabola/index';
4
+ import { tool as sine } from './sine';
5
+ import { tool as parabola } from './parabola';
6
6
  import { tool as line } from './line';
7
7
  import { tool as segment } from './segment';
8
8
  import { tool as ray } from './ray';
9
9
  import { tool as vector } from './vector';
10
+ import { tool as absolute } from './absolute';
11
+ import { tool as exponential } from './exponential';
10
12
 
11
- const allTools = ['circle', 'line', 'label', 'parabola', 'point', 'polygon', 'ray', 'segment', 'sine', 'vector'];
13
+ const allTools = [
14
+ 'circle',
15
+ 'line',
16
+ 'label',
17
+ 'parabola',
18
+ 'point',
19
+ 'polygon',
20
+ 'ray',
21
+ 'segment',
22
+ 'sine',
23
+ 'vector',
24
+ 'absolute',
25
+ 'exponential',
26
+ ];
12
27
 
13
- const toolsArr = [circle(), line(), parabola(), point(), polygon(), ray(), segment(), sine(), vector()];
28
+ // need this because now we should treat label as other tools PD-3736
29
+ const labelTool = {
30
+ type: 'label',
31
+ };
14
32
 
15
- export { allTools, toolsArr, circle, line, point, parabola, polygon, ray, sine, vector };
33
+ const toolsArr = [
34
+ circle(),
35
+ line(),
36
+ parabola(),
37
+ point(),
38
+ polygon(),
39
+ ray(),
40
+ segment(),
41
+ sine(),
42
+ vector(),
43
+ absolute(),
44
+ exponential(),
45
+ labelTool,
46
+ ];
47
+
48
+ export { allTools, toolsArr, circle, line, point, parabola, polygon, ray, sine, vector, absolute, exponential };
@@ -0,0 +1,20 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`ArrowedLine snapshot renders 1`] = `
4
+ <g>
5
+ <defs>
6
+ <ArrowMarker
7
+ className=""
8
+ id="1-enabled"
9
+ size={5}
10
+ />
11
+ </defs>
12
+ <line
13
+ className="className"
14
+ markerEnd="url(#1-enabled)"
15
+ markerId="1"
16
+ markerStart="url(#1-enabled)"
17
+ onChange={[MockFunction]}
18
+ />
19
+ </g>
20
+ `;
@@ -0,0 +1,36 @@
1
+ import { shallow } from 'enzyme';
2
+ import React from 'react';
3
+ import { ArrowedLine } from '../component';
4
+ import { graphProps as getGraphProps } from '../../../__tests__/utils';
5
+ jest.mock('@pie-lib/plot', () => {
6
+ const a = jest.requireActual('@pie-lib/plot');
7
+ return {
8
+ types: a.types,
9
+ gridDraggable: a.gridDraggable,
10
+ utils: a.utils,
11
+ trig: {
12
+ edges: jest.fn(() => jest.fn().mockReturnValue([0, 0])),
13
+ },
14
+ };
15
+ });
16
+
17
+ describe('ArrowedLine', () => {
18
+ let w;
19
+ let onChange = jest.fn();
20
+ const wrapper = (extras) => {
21
+ const defaults = {
22
+ classes: {},
23
+ className: 'className',
24
+ onChange,
25
+ markerId: '1',
26
+ graphProps: getGraphProps(),
27
+ };
28
+ const props = { ...defaults, ...extras };
29
+ return shallow(<ArrowedLine {...props} />);
30
+ };
31
+ describe('snapshot', () => {
32
+ it('renders', () => {
33
+ expect(wrapper()).toMatchSnapshot();
34
+ });
35
+ });
36
+ });
@@ -12,6 +12,7 @@ const lineStyles = (theme) => ({
12
12
  enabledArrow: styles.arrow(theme),
13
13
  disabledArrow: styles.disabledArrow(theme),
14
14
  disabled: styles.disabled(theme),
15
+ disabledSecondary: styles.disabledSecondary(theme),
15
16
  correct: styles.correct(theme, 'stroke'),
16
17
  correctArrow: styles.correct(theme),
17
18
  incorrect: styles.incorrect(theme, 'stroke'),
@@ -42,7 +43,7 @@ export const ArrowedLine = (props) => {
42
43
  y1={scale.y(eFrom.y)}
43
44
  x2={scale.x(eTo.x)}
44
45
  y2={scale.y(eTo.y)}
45
- className={classNames(classes.line, disabled && classes.disabled, classes[correctness], className)}
46
+ className={classNames(classes.line, disabled && classes.disabledSecondary, classes[correctness], className)}
46
47
  markerEnd={`url(#${props.markerId || markerId}-${suffix})`}
47
48
  markerStart={`url(#${props.markerId || markerId}-${suffix})`}
48
49
  {...rest}
@@ -0,0 +1,49 @@
1
+ import React from 'react';
2
+ import { withRootEdge } from '../../shared/line/with-root-edge';
3
+ import { buildDataPoints, parabolaFromTwoPoints } from '@pie-lib/graphing-utils';
4
+ import { utils } from '@pie-lib/plot';
5
+
6
+ import { graphProps as getGraphProps } from '../../../__tests__/utils';
7
+
8
+ const { xy } = utils;
9
+ jest.mock('@pie-lib/graphing-utils', () => ({
10
+ buildDataPoints: jest.fn().mockReturnValue([]),
11
+ parabolaFromTwoPoints: jest.fn(() => jest.fn()),
12
+ getAmplitudeAndFreq: jest.fn().mockReturnValue({ freq: 4, amplitude: 1 }),
13
+ }));
14
+
15
+ jest.mock('../../shared/line/with-root-edge', () => ({
16
+ withRootEdge: jest.fn(),
17
+ rootEdgeComponent: jest.fn(),
18
+ }));
19
+ describe('Parabola', () => {
20
+ let fnBody;
21
+ let graphProps;
22
+ let root;
23
+ let edge;
24
+ let result;
25
+ beforeEach(() => {
26
+ require('../component');
27
+ fnBody = withRootEdge.mock.calls[0][0];
28
+ graphProps = getGraphProps();
29
+ root = xy(0, 0);
30
+ edge = xy(1, 1);
31
+
32
+ result = fnBody({ graphProps, root, edge });
33
+ });
34
+ it('fnBody is not null', () => {
35
+ expect(fnBody).toBeDefined();
36
+ });
37
+
38
+ it('calls buildDataPoints', () => {
39
+ const { domain, range } = graphProps;
40
+ expect(buildDataPoints).toHaveBeenCalledWith(domain, range, root, edge, expect.anything(), true);
41
+ });
42
+ it('calls parabolaFromTwoPoints', () => {
43
+ expect(parabolaFromTwoPoints).toHaveBeenCalledWith(root, edge);
44
+ });
45
+
46
+ it('returns dataPoints', () => {
47
+ expect(result).toEqual({ root, edge, dataPoints: [] });
48
+ });
49
+ });
@@ -2,21 +2,22 @@ import debug from 'debug';
2
2
  import { buildDataPoints, parabolaFromTwoPoints } from '@pie-lib/graphing-utils';
3
3
  import { withRootEdge, rootEdgeComponent } from '../shared/line/with-root-edge';
4
4
 
5
- const log = debug('pie-lib:graphing:sine');
5
+ const log = debug('pie-lib:graphing:parabola');
6
6
 
7
7
  const Parabola = withRootEdge((props) => {
8
- const { domain } = props.graphProps;
9
-
10
- const { root, edge } = props;
11
- const interval = 1;
8
+ const { root, edge, graphProps } = props;
9
+ const { domain, range } = graphProps;
12
10
 
13
11
  const dataPoints =
14
12
  edge && edge.x === root.x
15
13
  ? []
16
- : buildDataPoints(domain.min, domain.max, root, edge, domain.step || interval, parabolaFromTwoPoints(root, edge));
14
+ : buildDataPoints(domain, range, root, edge, parabolaFromTwoPoints(root, edge), true);
15
+
17
16
  log('dataPoints:', dataPoints);
17
+
18
18
  return { root: props.root, edge: props.edge, dataPoints };
19
19
  });
20
20
 
21
21
  const Component = rootEdgeComponent(Parabola);
22
+
22
23
  export default Component;