@pie-lib/graphing-solution-set 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 (151) hide show
  1. package/CHANGELOG.json +1 -0
  2. package/CHANGELOG.md +16 -0
  3. package/LICENSE.md +5 -0
  4. package/NEXT.CHANGELOG.json +1 -0
  5. package/lib/__tests__/graph-with-controls.test.js +191 -0
  6. package/lib/__tests__/graph.test.js +290 -0
  7. package/lib/__tests__/grid.test.js +40 -0
  8. package/lib/__tests__/labels.test.js +59 -0
  9. package/lib/__tests__/mark-label.test.js +154 -0
  10. package/lib/__tests__/toggle-bar.test.js +54 -0
  11. package/lib/__tests__/tool-menu.test.js +43 -0
  12. package/lib/__tests__/undo-redo.test.js +42 -0
  13. package/lib/__tests__/use-debounce.test.js +28 -0
  14. package/lib/__tests__/utils.js +72 -0
  15. package/lib/__tests__/utils.test.js +133 -0
  16. package/lib/axis/__tests__/arrow.test.js +68 -0
  17. package/lib/axis/__tests__/axes.test.js +214 -0
  18. package/lib/axis/arrow.js +115 -0
  19. package/lib/axis/axes.js +415 -0
  20. package/lib/axis/index.js +26 -0
  21. package/lib/bg.js +139 -0
  22. package/lib/container/actions.js +24 -0
  23. package/lib/container/index.js +166 -0
  24. package/lib/container/marks.js +27 -0
  25. package/lib/container/middleware.js +25 -0
  26. package/lib/container/reducer.js +25 -0
  27. package/lib/coordinates-label.js +109 -0
  28. package/lib/graph-with-controls.js +372 -0
  29. package/lib/graph.js +419 -0
  30. package/lib/grid-setup.js +462 -0
  31. package/lib/grid.js +176 -0
  32. package/lib/index.js +51 -0
  33. package/lib/labels.js +299 -0
  34. package/lib/mark-label.js +208 -0
  35. package/lib/toggle-bar.js +336 -0
  36. package/lib/tool-menu.js +325 -0
  37. package/lib/tools/index.js +29 -0
  38. package/lib/tools/line/__tests__/component.test.js +56 -0
  39. package/lib/tools/line/component.js +106 -0
  40. package/lib/tools/line/index.js +16 -0
  41. package/lib/tools/polygon/__tests__/component.test.js +245 -0
  42. package/lib/tools/polygon/__tests__/index.test.js +95 -0
  43. package/lib/tools/polygon/__tests__/line.test.js +43 -0
  44. package/lib/tools/polygon/__tests__/polygon.test.js +73 -0
  45. package/lib/tools/polygon/component.js +457 -0
  46. package/lib/tools/polygon/index.js +106 -0
  47. package/lib/tools/polygon/line.js +151 -0
  48. package/lib/tools/polygon/polygon.js +171 -0
  49. package/lib/tools/shared/__tests__/arrow-head.test.js +62 -0
  50. package/lib/tools/shared/arrow-head.js +75 -0
  51. package/lib/tools/shared/line/__tests__/index.test.js +291 -0
  52. package/lib/tools/shared/line/__tests__/line-path.test.js +78 -0
  53. package/lib/tools/shared/line/__tests__/with-root-edge.test.js +122 -0
  54. package/lib/tools/shared/line/index.js +637 -0
  55. package/lib/tools/shared/line/line-path.js +145 -0
  56. package/lib/tools/shared/line/with-root-edge.js +155 -0
  57. package/lib/tools/shared/point/__tests__/arrow-point.test.js +137 -0
  58. package/lib/tools/shared/point/__tests__/base-point.test.js +134 -0
  59. package/lib/tools/shared/point/arrow-point.js +113 -0
  60. package/lib/tools/shared/point/arrow.js +96 -0
  61. package/lib/tools/shared/point/base-point.js +151 -0
  62. package/lib/tools/shared/point/index.js +94 -0
  63. package/lib/tools/shared/styles.js +49 -0
  64. package/lib/tools/shared/types.js +19 -0
  65. package/lib/undo-redo.js +107 -0
  66. package/lib/use-debounce.js +32 -0
  67. package/lib/utils.js +314 -0
  68. package/package.json +50 -0
  69. package/src/__tests__/__snapshots__/graph-with-controls.test.jsx.snap +114 -0
  70. package/src/__tests__/__snapshots__/graph.test.jsx.snap +213 -0
  71. package/src/__tests__/__snapshots__/grid.test.jsx.snap +54 -0
  72. package/src/__tests__/__snapshots__/labels.test.jsx.snap +30 -0
  73. package/src/__tests__/__snapshots__/mark-label.test.jsx.snap +37 -0
  74. package/src/__tests__/__snapshots__/toggle-bar.test.jsx.snap +7 -0
  75. package/src/__tests__/__snapshots__/tool-menu.test.jsx.snap +35 -0
  76. package/src/__tests__/__snapshots__/undo-redo.test.jsx.snap +15 -0
  77. package/src/__tests__/graph-with-controls.test.jsx +131 -0
  78. package/src/__tests__/graph.test.jsx +230 -0
  79. package/src/__tests__/grid.test.jsx +20 -0
  80. package/src/__tests__/labels.test.jsx +38 -0
  81. package/src/__tests__/mark-label.test.jsx +68 -0
  82. package/src/__tests__/toggle-bar.test.jsx +36 -0
  83. package/src/__tests__/tool-menu.test.jsx +29 -0
  84. package/src/__tests__/undo-redo.test.jsx +25 -0
  85. package/src/__tests__/use-debounce.test.js +21 -0
  86. package/src/__tests__/utils.js +38 -0
  87. package/src/__tests__/utils.test.js +151 -0
  88. package/src/axis/__tests__/__snapshots__/arrow.test.jsx.snap +33 -0
  89. package/src/axis/__tests__/__snapshots__/axes.test.jsx.snap +122 -0
  90. package/src/axis/__tests__/arrow.test.jsx +39 -0
  91. package/src/axis/__tests__/axes.test.jsx +220 -0
  92. package/src/axis/arrow.jsx +62 -0
  93. package/src/axis/axes.jsx +307 -0
  94. package/src/axis/index.js +2 -0
  95. package/src/bg.jsx +96 -0
  96. package/src/container/actions.js +8 -0
  97. package/src/container/index.jsx +86 -0
  98. package/src/container/marks.js +14 -0
  99. package/src/container/middleware.js +7 -0
  100. package/src/container/reducer.js +5 -0
  101. package/src/coordinates-label.jsx +73 -0
  102. package/src/graph-with-controls.jsx +263 -0
  103. package/src/graph.jsx +334 -0
  104. package/src/grid-setup.jsx +427 -0
  105. package/src/grid.jsx +135 -0
  106. package/src/index.js +7 -0
  107. package/src/labels.jsx +214 -0
  108. package/src/mark-label.jsx +136 -0
  109. package/src/toggle-bar.jsx +242 -0
  110. package/src/tool-menu.jsx +294 -0
  111. package/src/tools/index.js +8 -0
  112. package/src/tools/line/__tests__/__snapshots__/component.test.jsx.snap +20 -0
  113. package/src/tools/line/__tests__/component.test.jsx +36 -0
  114. package/src/tools/line/component.jsx +77 -0
  115. package/src/tools/line/index.js +4 -0
  116. package/src/tools/polygon/__tests__/__snapshots__/component.test.jsx.snap +94 -0
  117. package/src/tools/polygon/__tests__/__snapshots__/line.test.jsx.snap +44 -0
  118. package/src/tools/polygon/__tests__/__snapshots__/polygon.test.jsx.snap +53 -0
  119. package/src/tools/polygon/__tests__/component.test.jsx +214 -0
  120. package/src/tools/polygon/__tests__/index.test.js +65 -0
  121. package/src/tools/polygon/__tests__/line.test.jsx +25 -0
  122. package/src/tools/polygon/__tests__/polygon.test.jsx +44 -0
  123. package/src/tools/polygon/component.jsx +336 -0
  124. package/src/tools/polygon/index.js +52 -0
  125. package/src/tools/polygon/line.jsx +78 -0
  126. package/src/tools/polygon/polygon.jsx +101 -0
  127. package/src/tools/shared/__tests__/__snapshots__/arrow-head.test.jsx.snap +32 -0
  128. package/src/tools/shared/__tests__/arrow-head.test.jsx +34 -0
  129. package/src/tools/shared/arrow-head.jsx +46 -0
  130. package/src/tools/shared/line/__tests__/__snapshots__/index.test.jsx.snap +360 -0
  131. package/src/tools/shared/line/__tests__/__snapshots__/line-path.test.jsx.snap +57 -0
  132. package/src/tools/shared/line/__tests__/__snapshots__/with-root-edge.test.jsx.snap +63 -0
  133. package/src/tools/shared/line/__tests__/index.test.jsx +247 -0
  134. package/src/tools/shared/line/__tests__/line-path.test.jsx +53 -0
  135. package/src/tools/shared/line/__tests__/with-root-edge.test.jsx +73 -0
  136. package/src/tools/shared/line/index.jsx +473 -0
  137. package/src/tools/shared/line/line-path.jsx +88 -0
  138. package/src/tools/shared/line/with-root-edge.jsx +97 -0
  139. package/src/tools/shared/point/__tests__/__snapshots__/arrow-point.test.jsx.snap +55 -0
  140. package/src/tools/shared/point/__tests__/__snapshots__/base-point.test.jsx.snap +43 -0
  141. package/src/tools/shared/point/__tests__/arrow-point.test.jsx +87 -0
  142. package/src/tools/shared/point/__tests__/base-point.test.jsx +84 -0
  143. package/src/tools/shared/point/arrow-point.jsx +60 -0
  144. package/src/tools/shared/point/arrow.jsx +40 -0
  145. package/src/tools/shared/point/base-point.jsx +86 -0
  146. package/src/tools/shared/point/index.jsx +60 -0
  147. package/src/tools/shared/styles.js +20 -0
  148. package/src/tools/shared/types.js +8 -0
  149. package/src/undo-redo.jsx +47 -0
  150. package/src/use-debounce.js +13 -0
  151. package/src/utils.js +234 -0
package/src/utils.js ADDED
@@ -0,0 +1,234 @@
1
+ import head from 'lodash/head';
2
+ import tail from 'lodash/tail';
3
+ import { utils } from '@pie-lib/plot';
4
+ import invariant from 'invariant';
5
+ import isEqual from 'lodash/isEqual';
6
+ import isEmpty from 'lodash/isEmpty';
7
+ import cloneDeep from 'lodash/cloneDeep';
8
+
9
+ export const bounds = utils.bounds;
10
+ export const point = utils.point;
11
+
12
+ //TODO: This can be removed?
13
+ export const getAngleDeg = () => 0;
14
+ //TODO: This can be removed?
15
+ export const arrowDimensions = () => 0;
16
+
17
+ export const getTickValues = (prop) => {
18
+ const tickValues = [];
19
+ let tickVal = 0;
20
+
21
+ while (tickVal >= prop.min && tickValues.indexOf(tickVal) < 0) {
22
+ tickValues.push(tickVal);
23
+ tickVal = Math.round((tickVal - prop.step) * 10000) / 10000;
24
+ }
25
+
26
+ tickVal = Math.round(prop.step * 10000) / 10000;
27
+
28
+ while (tickVal <= prop.max && tickValues.indexOf(tickVal) < 0) {
29
+ tickValues.push(tickVal);
30
+ tickVal = Math.round((tickVal + prop.step) * 10000) / 10000;
31
+ }
32
+
33
+ // return only ticks that are inside the min-max interval
34
+ if (tickValues) {
35
+ return tickValues.filter((tV) => tV >= prop.min && tV <= prop.max);
36
+ }
37
+
38
+ return [];
39
+ };
40
+
41
+ export const countWords = (label) => {
42
+ if (label == null || isEmpty(label)) {
43
+ return 1;
44
+ }
45
+
46
+ const words = label.split(' ');
47
+ return words.length;
48
+ };
49
+
50
+ // findLongestWord is also used in plot
51
+ export const findLongestWord = (label) => {
52
+ let longestWord = (label || '')
53
+ .replace(/<[^>]+>/g, '')
54
+ .split(' ')
55
+ .sort((a, b) => b.length - a.length);
56
+
57
+ return longestWord[0].length;
58
+ };
59
+
60
+ // amountToIncreaseWidth is also used in plot
61
+ export const amountToIncreaseWidth = (longestWord) => {
62
+ if (!longestWord) {
63
+ return 0;
64
+ }
65
+
66
+ return longestWord * 10;
67
+ };
68
+
69
+ export const polygonToArea = (points) => {
70
+ const h = head(points);
71
+ const area = {
72
+ left: h.x,
73
+ top: h.y,
74
+ bottom: h.y,
75
+ right: h.x,
76
+ };
77
+ return tail(points).reduce((a, p) => {
78
+ a.left = Math.min(a.left, p.x);
79
+ a.top = Math.max(a.top, p.y);
80
+ a.bottom = Math.min(a.bottom, p.y);
81
+ a.right = Math.max(a.right, p.x);
82
+ return a;
83
+ }, area);
84
+ };
85
+
86
+ export const lineToArea = (from, to) => pointsToArea(from, to);
87
+
88
+ export const pointsToArea = (a, b) => {
89
+ invariant(!!a && !!b, 'a or b is undefined');
90
+ const left = Math.min(a.x, b.x);
91
+ const top = Math.max(a.y, b.y);
92
+ const bottom = Math.min(a.y, b.y);
93
+ const right = Math.max(a.x, b.x);
94
+ return { left, top, bottom, right };
95
+ };
96
+
97
+ export const getRightestPoints = (points) => {
98
+ const sortedPoints = cloneDeep(points);
99
+ sortedPoints.sort((a, b) => b.x - a.x);
100
+
101
+ return { a: sortedPoints[0], b: sortedPoints[1] };
102
+ };
103
+
104
+ export const getMiddleOfTwoPoints = (a, b) => ({
105
+ x: (a.x + b.x) / 2,
106
+ y: (a.y + b.y) / 2,
107
+ });
108
+
109
+ export const roundNumber = (number) => parseFloat(number.toFixed(4));
110
+
111
+ export const sameAxes = (p1, p2) =>
112
+ p1 && p2 && (roundNumber(p1.x) === roundNumber(p2.x) || roundNumber(p1.y) === roundNumber(p2.y));
113
+
114
+ export const equalPoints = (p1, p2) =>
115
+ p1 &&
116
+ p2 &&
117
+ isEqual(
118
+ {
119
+ x: roundNumber(p1.x),
120
+ y: roundNumber(p1.y),
121
+ },
122
+ {
123
+ x: roundNumber(p2.x),
124
+ y: roundNumber(p2.y),
125
+ },
126
+ );
127
+
128
+ const getDistanceBetweenTicks = (axis, size) => {
129
+ const { min, max, step } = axis;
130
+ const nbOfTicks = (max - min) / step;
131
+
132
+ return size / nbOfTicks;
133
+ };
134
+
135
+ export const thinnerShapesNeeded = (graphProps) => {
136
+ const {
137
+ domain,
138
+ range,
139
+ size: { width, height },
140
+ } = graphProps;
141
+
142
+ // 14 is the default width of a point
143
+ return getDistanceBetweenTicks(domain, width) < 14 || getDistanceBetweenTicks(range, height) < 14;
144
+ };
145
+
146
+ export const getAdjustedGraphLimits = (graphProps) => {
147
+ const {
148
+ domain,
149
+ range,
150
+ size: { width, height },
151
+ } = graphProps;
152
+ const domainTicksDistance = getDistanceBetweenTicks(domain, width);
153
+ const rangeTicksDistance = getDistanceBetweenTicks(range, height);
154
+
155
+ // 15 is the distance required for the arrow to extend the graph
156
+ const domainPadding = domain.step / (domainTicksDistance / 15);
157
+ const rangePadding = range.step / (rangeTicksDistance / 15);
158
+
159
+ return {
160
+ domain: {
161
+ min: domain.min - domainPadding,
162
+ max: domain.max + domainPadding,
163
+ },
164
+ range: {
165
+ min: range.min - rangePadding,
166
+ max: range.max + rangePadding,
167
+ },
168
+ };
169
+ };
170
+
171
+ const sortPoints = (array) => (array || []).sort((a, b) => a.x - b.x || a.y - b.y);
172
+
173
+ // check colliniarity of 3 points (source: https://www.geeksforgeeks.org/program-check-three-points-collinear/)
174
+ const checkCollinearity = (a, b, c) => (a.x - b.x) * (c.y - b.y) === (c.x - b.x) * (a.y - b.y);
175
+
176
+ // 2 lines are overlapping if all 4 points are collinear
177
+ const isSameLine = (markA, markB) =>
178
+ checkCollinearity(markA.from, markB.from, markB.to) && checkCollinearity(markA.to, markB.from, markB.to);
179
+
180
+ export const isDuplicatedMark = (mark, marks, oldMark) => {
181
+ const { type, building } = mark;
182
+
183
+ if (building) {
184
+ return false;
185
+ }
186
+
187
+ const filteredMarks = (marks || []).filter((m) => m.type === type && !m.building);
188
+ const index = filteredMarks.findIndex((m) => isEqual(m, oldMark));
189
+
190
+ if (index !== -1) {
191
+ filteredMarks.splice(index, 1);
192
+ }
193
+
194
+ const duplicated = filteredMarks.find((m) => {
195
+ if (type === 'line') {
196
+ const { from, to } = mark;
197
+ return (
198
+ (equalPoints(from, m.from) && equalPoints(to, m.to)) ||
199
+ (equalPoints(from, m.to) && equalPoints(to, m.from)) ||
200
+ (type === 'line' && isSameLine(m, mark))
201
+ );
202
+ } else if (type === 'polygon') {
203
+ return isEqual(sortPoints(cloneDeep(mark.points)), sortPoints(cloneDeep(m.points)));
204
+ }
205
+ });
206
+
207
+ return !!duplicated;
208
+ };
209
+
210
+ export const areArraysOfObjectsEqual = (array1, array2) => {
211
+ // Check if both arrays have the same length
212
+ if (array1.length !== array2.length) {
213
+ return false;
214
+ }
215
+ // Iterate through each object in the arrays
216
+ for (let i = 0; i < array1.length; i++) {
217
+ // Get the current objects in both arrays
218
+ const obj1 = array1[i];
219
+ const obj2 = array2[i];
220
+ // Check if the objects have the same number of properties
221
+ if (Object.keys(obj1).length !== Object.keys(obj2).length) {
222
+ return false;
223
+ }
224
+ // Iterate through each property in the objects
225
+ for (const key in obj1) {
226
+ // Check if the properties and their values are equal
227
+ if (obj1[key] !== obj2[key]) {
228
+ return false;
229
+ }
230
+ }
231
+ }
232
+ // If all objects are equal, the arrays are the same
233
+ return true;
234
+ };