@genome-spy/core 0.29.0 → 0.30.2

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 (234) hide show
  1. package/dist/index.es.js +16373 -0
  2. package/dist/index.js +43 -43
  3. package/package.json +10 -7
  4. package/src/data/collector.js +0 -183
  5. package/src/data/collector.test.js +0 -84
  6. package/src/data/dataFlow.js +0 -148
  7. package/src/data/dataFlow.test.js +0 -5
  8. package/src/data/facetNode.js +0 -17
  9. package/src/data/flow.test.js +0 -72
  10. package/src/data/flowBatch.d.ts +0 -40
  11. package/src/data/flowNode.js +0 -283
  12. package/src/data/flowNode.test.js +0 -50
  13. package/src/data/flowOptimizer.js +0 -123
  14. package/src/data/flowOptimizer.test.js +0 -193
  15. package/src/data/flowTestUtils.js +0 -63
  16. package/src/data/formats/fasta.js +0 -32
  17. package/src/data/formats/fasta.test.js +0 -27
  18. package/src/data/sources/dataSource.js +0 -22
  19. package/src/data/sources/dataSourceFactory.js +0 -24
  20. package/src/data/sources/dataUtils.js +0 -78
  21. package/src/data/sources/dynamicCallbackSource.js +0 -57
  22. package/src/data/sources/dynamicSource.js +0 -37
  23. package/src/data/sources/inlineSource.js +0 -67
  24. package/src/data/sources/inlineSource.test.js +0 -56
  25. package/src/data/sources/namedSource.js +0 -79
  26. package/src/data/sources/sequenceSource.js +0 -46
  27. package/src/data/sources/sequenceSource.test.js +0 -46
  28. package/src/data/sources/urlSource.js +0 -74
  29. package/src/data/transforms/aggregate.js +0 -70
  30. package/src/data/transforms/clone.js +0 -40
  31. package/src/data/transforms/clone.test.js +0 -11
  32. package/src/data/transforms/coverage.js +0 -187
  33. package/src/data/transforms/coverage.test.js +0 -123
  34. package/src/data/transforms/filter.js +0 -37
  35. package/src/data/transforms/filter.test.js +0 -18
  36. package/src/data/transforms/filterScoredLabels.js +0 -134
  37. package/src/data/transforms/flattenCompressedExons.js +0 -57
  38. package/src/data/transforms/flattenDelimited.js +0 -74
  39. package/src/data/transforms/flattenDelimited.test.js +0 -87
  40. package/src/data/transforms/flattenSequence.js +0 -39
  41. package/src/data/transforms/flattenSequence.test.js +0 -34
  42. package/src/data/transforms/formula.js +0 -39
  43. package/src/data/transforms/formula.test.js +0 -19
  44. package/src/data/transforms/identifier.js +0 -108
  45. package/src/data/transforms/identifier.test.js +0 -83
  46. package/src/data/transforms/linearizeGenomicCoordinate.js +0 -101
  47. package/src/data/transforms/measureText.js +0 -44
  48. package/src/data/transforms/pileup.js +0 -128
  49. package/src/data/transforms/pileup.test.js +0 -70
  50. package/src/data/transforms/project.js +0 -41
  51. package/src/data/transforms/project.test.js +0 -32
  52. package/src/data/transforms/regexExtract.js +0 -61
  53. package/src/data/transforms/regexExtract.test.js +0 -67
  54. package/src/data/transforms/regexFold.js +0 -141
  55. package/src/data/transforms/regexFold.test.js +0 -160
  56. package/src/data/transforms/sample.js +0 -101
  57. package/src/data/transforms/sample.test.js +0 -38
  58. package/src/data/transforms/stack.js +0 -137
  59. package/src/data/transforms/stack.test.js +0 -91
  60. package/src/data/transforms/transformFactory.js +0 -60
  61. package/src/embedApi.d.ts +0 -67
  62. package/src/encoder/accessor.js +0 -82
  63. package/src/encoder/accessor.test.js +0 -47
  64. package/src/encoder/encoder.js +0 -394
  65. package/src/encoder/encoder.test.js +0 -98
  66. package/src/fonts/Lato-Regular.json +0 -1267
  67. package/src/fonts/Lato-Regular.png +0 -0
  68. package/src/fonts/OFL.txt +0 -93
  69. package/src/fonts/README.md +0 -3
  70. package/src/fonts/bmFont.d.ts +0 -58
  71. package/src/fonts/bmFontManager.js +0 -357
  72. package/src/fonts/bmFontMetrics.js +0 -108
  73. package/src/genome/genome.js +0 -317
  74. package/src/genome/genome.test.js +0 -188
  75. package/src/genome/genomeStore.js +0 -54
  76. package/src/genome/locusFormat.js +0 -31
  77. package/src/genome/scaleIndex.d.ts +0 -38
  78. package/src/genome/scaleIndex.js +0 -166
  79. package/src/genome/scaleIndex.test.js +0 -78
  80. package/src/genome/scaleLocus.d.ts +0 -11
  81. package/src/genome/scaleLocus.js +0 -108
  82. package/src/genome/scaleLocus.test.js +0 -4
  83. package/src/genomeSpy.js +0 -784
  84. package/src/gl/arrayBuilder.js +0 -199
  85. package/src/gl/dataToVertices.js +0 -636
  86. package/src/gl/includes/common.glsl +0 -63
  87. package/src/gl/includes/picking.fragment.glsl +0 -1
  88. package/src/gl/includes/picking.vertex.glsl +0 -27
  89. package/src/gl/includes/sampleFacet.glsl +0 -107
  90. package/src/gl/includes/scales.glsl +0 -112
  91. package/src/gl/link.fragment.glsl +0 -18
  92. package/src/gl/link.vertex.glsl +0 -111
  93. package/src/gl/point.fragment.glsl +0 -123
  94. package/src/gl/point.vertex.glsl +0 -129
  95. package/src/gl/rect.fragment.glsl +0 -51
  96. package/src/gl/rect.vertex.glsl +0 -114
  97. package/src/gl/rule.fragment.glsl +0 -52
  98. package/src/gl/rule.vertex.glsl +0 -89
  99. package/src/gl/text.fragment.glsl +0 -31
  100. package/src/gl/text.vertex.glsl +0 -246
  101. package/src/gl/webGLHelper.js +0 -489
  102. package/src/img/bowtie.svg +0 -1
  103. package/src/img/genomespy-favicon.svg +0 -34
  104. package/src/index.html +0 -11
  105. package/src/index.js +0 -128
  106. package/src/marks/link.js +0 -175
  107. package/src/marks/mark.js +0 -975
  108. package/src/marks/markUtils.js +0 -125
  109. package/src/marks/pointMark.js +0 -251
  110. package/src/marks/rectMark.js +0 -241
  111. package/src/marks/rule.js +0 -250
  112. package/src/marks/text.js +0 -278
  113. package/src/node_modules/.vitest/results.json +0 -1
  114. package/src/scale/colorUtils.js +0 -184
  115. package/src/scale/glslScaleGenerator.js +0 -488
  116. package/src/scale/scale.js +0 -451
  117. package/src/scale/scale.test.js +0 -324
  118. package/src/scale/ticks.js +0 -203
  119. package/src/scale/ticks.test.js +0 -40
  120. package/src/singlePageApp.js +0 -13
  121. package/src/spec/axis.d.ts +0 -296
  122. package/src/spec/channel.d.ts +0 -430
  123. package/src/spec/data.d.ts +0 -196
  124. package/src/spec/font.d.ts +0 -15
  125. package/src/spec/genome.d.ts +0 -35
  126. package/src/spec/mark.d.ts +0 -429
  127. package/src/spec/root.d.ts +0 -17
  128. package/src/spec/sampleView.d.ts +0 -180
  129. package/src/spec/scale.d.ts +0 -273
  130. package/src/spec/title.d.ts +0 -102
  131. package/src/spec/tooltip.d.ts +0 -9
  132. package/src/spec/transform.d.ts +0 -479
  133. package/src/spec/view.d.ts +0 -201
  134. package/src/styles/genome-spy.scss +0 -153
  135. package/src/tooltip/dataTooltipHandler.js +0 -64
  136. package/src/tooltip/refseqGeneTooltipHandler.js +0 -78
  137. package/src/tooltip/tooltipHandler.ts +0 -12
  138. package/src/types/filetypes.d.ts +0 -14
  139. package/src/types/flatqueue.d.ts +0 -53
  140. package/src/types/glsl.d.ts +0 -4
  141. package/src/types/internmap.d.ts +0 -22
  142. package/src/types/object.d.ts +0 -21
  143. package/src/types/vega-loader.d.ts +0 -1
  144. package/src/types/vega-scale.d.ts +0 -60
  145. package/src/utils/addBaseUrl.js +0 -19
  146. package/src/utils/addBaseUrl.test.js +0 -22
  147. package/src/utils/animator.js +0 -83
  148. package/src/utils/arrayUtils.js +0 -61
  149. package/src/utils/binnedIndex.js +0 -167
  150. package/src/utils/binnedIndex.test.js +0 -155
  151. package/src/utils/clamp.js +0 -8
  152. package/src/utils/cloner.js +0 -34
  153. package/src/utils/cloner.test.js +0 -24
  154. package/src/utils/coalesce.js +0 -11
  155. package/src/utils/coalesce.test.js +0 -16
  156. package/src/utils/concatIterables.js +0 -26
  157. package/src/utils/concatIterables.test.js +0 -8
  158. package/src/utils/debounce.js +0 -37
  159. package/src/utils/domainArray.js +0 -216
  160. package/src/utils/domainArray.test.js +0 -130
  161. package/src/utils/eerp.js +0 -13
  162. package/src/utils/expression.js +0 -32
  163. package/src/utils/field.js +0 -28
  164. package/src/utils/formatObject.js +0 -31
  165. package/src/utils/indexer.js +0 -43
  166. package/src/utils/indexer.test.js +0 -47
  167. package/src/utils/inertia.js +0 -124
  168. package/src/utils/interactionEvent.js +0 -33
  169. package/src/utils/iterateNestedMaps.js +0 -21
  170. package/src/utils/iterateNestedMaps.test.js +0 -33
  171. package/src/utils/kWayMerge.js +0 -42
  172. package/src/utils/kWayMerge.test.js +0 -26
  173. package/src/utils/layout/flexLayout.js +0 -368
  174. package/src/utils/layout/flexLayout.test.js +0 -311
  175. package/src/utils/layout/grid.js +0 -95
  176. package/src/utils/layout/grid.test.js +0 -71
  177. package/src/utils/layout/padding.js +0 -120
  178. package/src/utils/layout/point.js +0 -23
  179. package/src/utils/layout/rectangle.js +0 -288
  180. package/src/utils/layout/rectangle.test.js +0 -172
  181. package/src/utils/mergeObjects.js +0 -99
  182. package/src/utils/mergeObjects.test.js +0 -42
  183. package/src/utils/numberExtractor.js +0 -24
  184. package/src/utils/numberExtractor.test.js +0 -6
  185. package/src/utils/point.js +0 -14
  186. package/src/utils/propertyCacher.js +0 -70
  187. package/src/utils/propertyCacher.test.js +0 -85
  188. package/src/utils/propertyCoalescer.js +0 -42
  189. package/src/utils/propertyCoalescer.test.js +0 -22
  190. package/src/utils/reservationMap.js +0 -103
  191. package/src/utils/reservationMap.test.js +0 -20
  192. package/src/utils/scaleNull.js +0 -19
  193. package/src/utils/setOperations.js +0 -75
  194. package/src/utils/smoothstep.js +0 -10
  195. package/src/utils/throttle.js +0 -34
  196. package/src/utils/topK.js +0 -76
  197. package/src/utils/topK.test.js +0 -64
  198. package/src/utils/transition.js +0 -74
  199. package/src/utils/ui/tooltip.js +0 -189
  200. package/src/utils/url.js +0 -22
  201. package/src/utils/variableTools.js +0 -24
  202. package/src/utils/variableTools.test.js +0 -13
  203. package/src/view/axisResolution.js +0 -140
  204. package/src/view/axisResolution.test.js +0 -201
  205. package/src/view/axisView.js +0 -747
  206. package/src/view/concatView.js +0 -45
  207. package/src/view/containerView.js +0 -159
  208. package/src/view/facetView.js +0 -491
  209. package/src/view/flowBuilder.js +0 -367
  210. package/src/view/flowBuilder.test.js +0 -125
  211. package/src/view/gridView.js +0 -786
  212. package/src/view/implicitRootView.js +0 -14
  213. package/src/view/importView.js +0 -19
  214. package/src/view/layerView.js +0 -74
  215. package/src/view/rendering.d.ts +0 -44
  216. package/src/view/renderingContext/compositeViewRenderingContext.js +0 -51
  217. package/src/view/renderingContext/deferredViewRenderingContext.js +0 -176
  218. package/src/view/renderingContext/layoutRecorderViewRenderingContext.js +0 -128
  219. package/src/view/renderingContext/simpleViewRenderingContext.js +0 -64
  220. package/src/view/renderingContext/svgViewRenderingContext.js +0 -125
  221. package/src/view/renderingContext/viewRenderingContext.js +0 -41
  222. package/src/view/scaleResolution.js +0 -791
  223. package/src/view/scaleResolution.test.js +0 -572
  224. package/src/view/scaleResolutionApi.d.ts +0 -40
  225. package/src/view/testUtils.js +0 -51
  226. package/src/view/title.js +0 -165
  227. package/src/view/unitView.js +0 -382
  228. package/src/view/view.js +0 -612
  229. package/src/view/view.test.js +0 -214
  230. package/src/view/viewContext.d.ts +0 -62
  231. package/src/view/viewFactory.js +0 -181
  232. package/src/view/viewFactory.test.js +0 -17
  233. package/src/view/viewUtils.js +0 -327
  234. package/src/view/zoom.js +0 -89
@@ -1,70 +0,0 @@
1
- const cacheMapKey = Symbol("cacheMap");
2
-
3
- /**
4
- * @param {object} host The object that uses caching
5
- * @param {any} key string
6
- * @param {function(key?):T} callable A function that produces a value to be cached
7
- * @returns {T}
8
- * @template T
9
- */
10
- export function getCachedOrCall(host, key, callable) {
11
- let value = getCacheMap(host).get(key);
12
- if (value === undefined) {
13
- value = callable(key);
14
- getCacheMap(host).set(key, value);
15
- }
16
- return value;
17
- }
18
-
19
- /**
20
- *
21
- * @param {object} host The object that uses caching
22
- * @param {string} key
23
- */
24
- export function invalidate(host, key) {
25
- getCacheMap(host).delete(key);
26
- }
27
-
28
- /**
29
- *
30
- * @param {object} host The object that uses caching
31
- * @param {string} keyPrefix
32
- */
33
- export function invalidatePrefix(host, keyPrefix) {
34
- const m = getCacheMap(host);
35
- for (const key of m.keys()) {
36
- if (key.startsWith(keyPrefix)) {
37
- m.delete(key);
38
- }
39
- }
40
- getCacheMap(host).delete(keyPrefix);
41
- }
42
- /**
43
- *
44
- * @param {object} host The object that uses caching
45
- */
46
- export function invalidateAll(host) {
47
- getCacheMap(host).clear();
48
- }
49
-
50
- /**
51
- * @param {any} host The object that uses caching
52
- */
53
- export function initPropertyCache(host) {
54
- /** @type {Map<string, any>} */
55
- host[cacheMapKey] = new Map();
56
- }
57
-
58
- /**
59
- * @param {any} host The object that uses caching
60
- * @returns {Map<string, any>}
61
- */
62
- function getCacheMap(host) {
63
- if (host[cacheMapKey]) {
64
- return host[cacheMapKey];
65
- }
66
-
67
- initPropertyCache(host);
68
-
69
- return host[cacheMapKey];
70
- }
@@ -1,85 +0,0 @@
1
- import { expect, test } from "vitest";
2
- import { getCachedOrCall, invalidate, invalidateAll } from "./propertyCacher";
3
-
4
- class TestClass {
5
- constructor() {
6
- /** @type {number} */
7
- this._x;
8
- /** @type {number} */
9
- this._y;
10
-
11
- this._xCalls = 0;
12
- this._yCalls = 0;
13
-
14
- this.resetAll();
15
- }
16
-
17
- get x() {
18
- return getCachedOrCall(this, "x", () => {
19
- this._xCalls++;
20
- return this._x;
21
- });
22
- }
23
-
24
- set x(x) {
25
- this._x = x;
26
- invalidate(this, "x");
27
- }
28
-
29
- get y() {
30
- return getCachedOrCall(this, "y", () => {
31
- this._yCalls++;
32
- return this._y;
33
- });
34
- }
35
-
36
- set y(y) {
37
- this._y = y;
38
- invalidate(this, "y");
39
- }
40
-
41
- resetAll() {
42
- this._x = 10;
43
- this._y = 20;
44
- invalidateAll(this);
45
- }
46
- }
47
-
48
- test("Initial cached get returns correct values and calls callable only once", () => {
49
- const instance = new TestClass();
50
-
51
- expect(instance._xCalls).toEqual(0);
52
- expect(instance.x).toEqual(10);
53
- expect(instance._xCalls).toEqual(1);
54
- expect(instance.x).toEqual(10);
55
- expect(instance._xCalls).toEqual(1);
56
- });
57
-
58
- test("Invalidate invalidates", () => {
59
- const instance = new TestClass();
60
-
61
- expect(instance._xCalls).toEqual(0);
62
- expect(instance.x).toEqual(10);
63
- expect(instance._xCalls).toEqual(1);
64
-
65
- instance.x = 123;
66
- expect(instance._xCalls).toEqual(1);
67
-
68
- expect(instance.x).toEqual(123);
69
- expect(instance._xCalls).toEqual(2);
70
- });
71
-
72
- test("InvalidateAll invalidates everything", () => {
73
- const instance = new TestClass();
74
-
75
- instance.x = 123;
76
- instance.y = 321;
77
-
78
- expect(instance.x).toEqual(123);
79
- expect(instance.y).toEqual(321);
80
-
81
- instance.resetAll();
82
-
83
- expect(instance.x).toEqual(10);
84
- expect(instance.y).toEqual(20);
85
- });
@@ -1,42 +0,0 @@
1
- /**
2
- * Coalesces properties. Allows for creating chains of defaults without
3
- * using object destructuring, which may generate piles of garbage for GC.
4
- *
5
- * Still WIP.
6
- * TODO: Efficient computed defaults.
7
- * TODO: Make sense of the types
8
- *
9
- * @param {...function():T} sources
10
- * @returns {T}
11
- *
12
- * @template {Record<string | symbol, any>} [T=object]
13
- */
14
- export default function coalesceProperties(...sources) {
15
- /** @type {ProxyHandler<T>} */
16
- const handler = {
17
- get(_target, prop, _receiver) {
18
- for (const source of sources) {
19
- const props = source();
20
- const value = props[prop];
21
- if (value !== undefined) {
22
- return value;
23
- }
24
- }
25
- return undefined;
26
- },
27
-
28
- // @ts-ignore
29
- has(target, prop, _receiver) {
30
- for (const source of sources) {
31
- const props = source();
32
- if (prop in props) {
33
- return true;
34
- }
35
- }
36
- return false;
37
- },
38
- };
39
-
40
- // @ts-ignore
41
- return new Proxy({}, handler);
42
- }
@@ -1,22 +0,0 @@
1
- import { expect, test } from "vitest";
2
- import coalesceProperties from "./propertyCoalescer";
3
-
4
- test("CoalesceProperties works as expected", () => {
5
- const defaults = { a: 10, b: 11 };
6
- const props = { a: 1, c: 2 };
7
-
8
- const coalesced = coalesceProperties(
9
- () => props,
10
- () => defaults
11
- );
12
-
13
- expect(coalesced.a).toEqual(1);
14
- expect(coalesced.b).toEqual(11);
15
- expect(coalesced.c).toEqual(2);
16
- expect(coalesced.undef).toBeUndefined();
17
-
18
- expect("a" in coalesced).toBeTruthy();
19
- expect("b" in coalesced).toBeTruthy();
20
- expect("c" in coalesced).toBeTruthy();
21
- expect("undef" in coalesced).toBeFalsy();
22
- });
@@ -1,103 +0,0 @@
1
- /**
2
- * A simple data structure for keeping track of unreserved space in one dimension.
3
- * Doesn't do any balancing, reservations must be done in random order.
4
- * Uses arrays to minimize object allocation and burden on GC.
5
- *
6
- * Note: this data structure appears to have some similarities to "Segment Tree".
7
- * TODO: Balancing ideas: https://cp-algorithms.com/data_structures/segment_tree.html
8
- */
9
- export default class ReservationMap {
10
- /**
11
- *
12
- * @param {number} maxSize Max number of free slots that can be tracked
13
- * @param {number} [lowerLimit]
14
- * @param {number} [upperLimit]
15
- */
16
- constructor(maxSize, lowerLimit = -Infinity, upperLimit = Infinity) {
17
- this.maxSize = maxSize;
18
- this.lowerLimit = lowerLimit;
19
- this.upperLimit = upperLimit;
20
-
21
- const count = this.maxSize * 2 + 1; // TODO: The factor could be lower
22
-
23
- this.lowerLimits = new Float64Array(count);
24
- this.upperLimits = new Float64Array(count);
25
- this.lowerChildren = new Int32Array(count);
26
- this.upperChildren = new Int32Array(count);
27
-
28
- this.reset();
29
- }
30
-
31
- reset() {
32
- this.lowerLimits.fill(0);
33
- this.upperLimits.fill(0);
34
- this.lowerChildren.fill(0);
35
- this.upperChildren.fill(0);
36
-
37
- // Initial node
38
- this.n = 1;
39
- this.lowerLimits[0] = this.lowerLimit;
40
- this.upperLimits[0] = this.upperLimit;
41
- }
42
-
43
- /**
44
- *
45
- * @param {number} lower
46
- * @param {number} upper
47
- * @param {number} i
48
- * @returns {number} Node index or -1 if not found
49
- */
50
- _findSlot(lower, upper, i = 0) {
51
- if (lower >= this.lowerLimits[i] && upper <= this.upperLimits[i]) {
52
- const lowerChild = this.lowerChildren[i];
53
- if (!lowerChild) {
54
- // Node has no children, found a free slot
55
- return i;
56
- } else {
57
- const lowerResult = this._findSlot(lower, upper, lowerChild);
58
- if (lowerResult >= 0) {
59
- return lowerResult;
60
- }
61
- return this._findSlot(lower, upper, this.upperChildren[i]);
62
- }
63
- } else {
64
- return -1;
65
- }
66
- }
67
-
68
- /**
69
- *
70
- * @param {number} lower
71
- * @param {number} upper
72
- * @returns {boolean} true if reservation succeeded
73
- */
74
- reserve(lower, upper) {
75
- if (upper - lower <= 0) {
76
- throw new Error("Cannot reserve an empty or negative-size slot!");
77
- }
78
-
79
- if (this.n + 1 > this.lowerLimits.length) {
80
- return false;
81
- }
82
-
83
- const i = this._findSlot(lower, upper);
84
- if (i < 0) {
85
- return false;
86
- }
87
-
88
- // TODO: if the requested range is connected to an edge of the free slot,
89
- // adjust the found slot instead
90
-
91
- const lowerIndex = this.n++;
92
- const upperIndex = this.n++;
93
-
94
- this.lowerLimits[lowerIndex] = this.lowerLimits[i];
95
- this.upperLimits[lowerIndex] = lower;
96
- this.lowerLimits[upperIndex] = upper;
97
- this.upperLimits[upperIndex] = this.upperLimits[i];
98
- this.lowerChildren[i] = lowerIndex;
99
- this.upperChildren[i] = upperIndex;
100
-
101
- return true;
102
- }
103
- }
@@ -1,20 +0,0 @@
1
- import { expect, test } from "vitest";
2
- import ReservationMap from "./reservationMap";
3
-
4
- test("ReservationMap works correctly", () => {
5
- const m = new ReservationMap(20);
6
-
7
- expect(m.reserve(0, 3)).toBeTruthy();
8
- expect(m.reserve(15, 17)).toBeTruthy();
9
- expect(m.reserve(5, 11)).toBeTruthy();
10
- expect(m.reserve(19, 22)).toBeTruthy();
11
- expect(m.reserve(23, 26)).toBeTruthy();
12
- expect(m.reserve(12, 13)).toBeTruthy();
13
- expect(m.reserve(13, 14)).toBeTruthy();
14
- expect(m.reserve(4, 5)).toBeTruthy();
15
-
16
- expect(m.reserve(6, 8)).toBeFalsy();
17
- expect(m.reserve(10, 13)).toBeFalsy();
18
- expect(m.reserve(-2, 1)).toBeFalsy();
19
- expect(m.reserve(25, 28)).toBeFalsy();
20
- });
@@ -1,19 +0,0 @@
1
- /**
2
- * Like scaleIdentity but passes everything thru. Doesn't support domains or ranges or anything.
3
- */
4
- export default function scaleNull() {
5
- /** @param {any} x */
6
- const scale = (x) => x;
7
-
8
- /** @param {any} x */
9
- scale.invert = (x) => x;
10
-
11
- scale.copy = scaleNull;
12
-
13
- /** Keep vega-scale happy */
14
- scale.invertRange = () => {
15
- //
16
- };
17
-
18
- return scale;
19
- }
@@ -1,75 +0,0 @@
1
- /*
2
- * Adapted from: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set#implementing_basic_set_operations
3
- */
4
-
5
- /**
6
- * @param {Set<T>} set
7
- * @param {Set<T>} subset
8
- * @template T
9
- */
10
- export function isSuperset(set, subset) {
11
- for (let elem of subset) {
12
- if (!set.has(elem)) {
13
- return false;
14
- }
15
- }
16
- return true;
17
- }
18
-
19
- /**
20
- * @param {Set<T>} setA
21
- * @param {Set<T>} setB
22
- * @template T
23
- */
24
- export function union(setA, setB) {
25
- let _union = new Set(setA);
26
- for (let elem of setB) {
27
- _union.add(elem);
28
- }
29
- return _union;
30
- }
31
-
32
- /**
33
- * @param {Set<T>} setA
34
- * @param {Set<T>} setB
35
- * @template T
36
- */
37
- export function intersection(setA, setB) {
38
- let _intersection = new Set();
39
- for (let elem of setB) {
40
- if (setA.has(elem)) {
41
- _intersection.add(elem);
42
- }
43
- }
44
- return _intersection;
45
- }
46
-
47
- /**
48
- * @param {Set<T>} setA
49
- * @param {Set<T>} setB
50
- * @template T
51
- */
52
- export function symmetricDifference(setA, setB) {
53
- let _difference = new Set(setA);
54
- for (let elem of setB) {
55
- if (_difference.has(elem)) {
56
- _difference.delete(elem);
57
- } else {
58
- _difference.add(elem);
59
- }
60
- }
61
- return _difference;
62
- }
63
-
64
- /**
65
- * @param {Set<T>} setA
66
- * @param {Set<T>} setB
67
- * @template T
68
- */
69
- export function difference(setA, setB) {
70
- let _difference = new Set(setA);
71
- for (let elem of setB) {
72
- _difference.delete(elem);
73
- }
74
- return _difference;
75
- }
@@ -1,10 +0,0 @@
1
- /**
2
- * @param {number} edge0
3
- * @param {number} edge1
4
- * @param {number} x
5
- */
6
- export default function smoothstep(edge0, edge1, x) {
7
- x = (x - edge0) / (edge1 - edge0);
8
- x = Math.max(0, Math.min(1, x));
9
- return x * x * (3 - 2 * x);
10
- }
@@ -1,34 +0,0 @@
1
- /* eslint-disable consistent-this */
2
-
3
- /**
4
- * https://codeburst.io/throttling-and-debouncing-in-javascript-b01cad5c8edf
5
- *
6
- * @param {function} func
7
- * @param {number} limit
8
- */
9
- export default function throttle(func, limit) {
10
- /** @type {number} */
11
- let lastFunc;
12
-
13
- /** @type {number} */
14
- let lastRan;
15
-
16
- return function () {
17
- // eslint-disable-next-line no-invalid-this
18
- const context = this;
19
- // eslint-disable-next-line prefer-rest-params
20
- const args = arguments;
21
- if (!lastRan) {
22
- func.apply(context, args);
23
- lastRan = Date.now();
24
- } else {
25
- clearTimeout(lastFunc);
26
- lastFunc = window.setTimeout(function () {
27
- if (Date.now() - lastRan >= limit) {
28
- func.apply(context, args);
29
- lastRan = Date.now();
30
- }
31
- }, limit - (Date.now() - lastRan));
32
- }
33
- };
34
- }
package/src/utils/topK.js DELETED
@@ -1,76 +0,0 @@
1
- import FlatQueue from "flatqueue";
2
-
3
- /**
4
- * Finds the top k
5
- *
6
- * Based on ideas at https://lemire.me/blog/2017/06/21/top-speed-for-top-k-queries/
7
- *
8
- * @param {T[]} data
9
- * @param {number} k
10
- * @param {(datum: T) => number} priorityAccessor
11
- * @template T
12
- */
13
- export function topK(data, k, priorityAccessor) {
14
- /** @type {FlatQueue<number>} */
15
- const queue = new FlatQueue();
16
-
17
- let i;
18
- for (i = 0; i < k && i < data.length; i++) {
19
- queue.push(i, priorityAccessor(data[i]));
20
- }
21
-
22
- for (; i < data.length; i++) {
23
- const p = priorityAccessor(data[i]);
24
- if (p >= queue.peekValue()) {
25
- queue.push(i, p);
26
- queue.pop();
27
- }
28
- }
29
-
30
- const result = [];
31
-
32
- let index;
33
- while ((index = queue.pop()) !== undefined) {
34
- result.push(data[index]);
35
- }
36
-
37
- return result.reverse();
38
- }
39
-
40
- /**
41
- * Takes an array of priorities and returns the top k indices from the
42
- * specified slice
43
- *
44
- * @param {number[]} priorities An array of priorities
45
- * @param {number} k
46
- * @param {number} [start] Default: 0
47
- * @param {number} [end] Exclusive. Default: priorities.length
48
- */
49
- export function topKSlice(priorities, k, start = 0, end = priorities.length) {
50
- /** @type {FlatQueue<number>} */
51
- const queue = new FlatQueue();
52
-
53
- const sliceLength = end - start;
54
-
55
- let i;
56
- for (i = 0; i < k && i < sliceLength; i++) {
57
- queue.push(i, priorities[start + i]);
58
- }
59
-
60
- for (; i < sliceLength; i++) {
61
- const p = priorities[start + i];
62
- if (p >= queue.peekValue()) {
63
- queue.push(i, p);
64
- queue.pop();
65
- }
66
- }
67
-
68
- const result = [];
69
-
70
- let index;
71
- while ((index = queue.pop()) !== undefined) {
72
- result.push(start + index);
73
- }
74
-
75
- return result.reverse();
76
- }
@@ -1,64 +0,0 @@
1
- import { expect, test } from "vitest";
2
- import { range } from "d3-array";
3
- import { topK, topKSlice } from "./topK";
4
-
5
- test("topK returns top k numbers in priority order", () => {
6
- /** @param {number} x */
7
- const priorityAccessor = (x) => x;
8
-
9
- expect(topK([1, 2, 3], 3, priorityAccessor)).toEqual([3, 2, 1]);
10
- expect(topK([1, 2, 3], 1, priorityAccessor)).toEqual([3]);
11
- expect(topK([1, 2, 3], 6, priorityAccessor)).toEqual([3, 2, 1]);
12
- expect(topK([1, 2, 3, 4, 5, 6], 3, priorityAccessor)).toEqual([6, 5, 4]);
13
- expect(topK([0, 9, 1, 8, 2, 7, 3, 6, 4, 5], 3, priorityAccessor)).toEqual([
14
- 9, 8, 7,
15
- ]);
16
- expect(topK([1, 1, 1], 3, priorityAccessor)).toEqual([1, 1, 1]);
17
- });
18
-
19
- test("topK returns top k objects in priority order", () => {
20
- /** @param {{priority: number}} d */
21
- const priorityAccessor = (d) => d.priority;
22
-
23
- expect(
24
- topK(
25
- [0, 9, 1, 8, 2, 7, 3, 6, 4, 5].map((x) => ({ priority: x })),
26
- 3,
27
- priorityAccessor
28
- )
29
- ).toEqual([9, 8, 7].map((x) => ({ priority: x })));
30
- });
31
-
32
- test("topK returns top k objects in priority order with large datasets", () => {
33
- /** @param {number} x */
34
- const priorityAccessor = (x) => x;
35
-
36
- const n = 10000;
37
- const bigArray = range(n).map((x) => Math.floor(Math.random() * 100));
38
- const sortedBigArray = bigArray.slice().sort((a, b) => b - a);
39
-
40
- for (let k = 0; k < 13000; k += 1000) {
41
- expect(topK(bigArray, k, priorityAccessor)).toEqual(
42
- sortedBigArray.slice(0, k)
43
- );
44
- }
45
- });
46
-
47
- test("topKSlice returns top k indexes in priority order", () => {
48
- expect(topKSlice([0, 1, 2], 3)).toEqual([2, 1, 0]);
49
- expect(topKSlice([1, 2, 3], 3)).toEqual([2, 1, 0]);
50
- expect(topKSlice([0, 1, 2], 1)).toEqual([2]);
51
- expect(topKSlice([0, 1, 2], 6)).toEqual([2, 1, 0]);
52
- expect(topKSlice([0, 1, 2, 3, 4, 5], 3)).toEqual([5, 4, 3]);
53
- expect(topKSlice([0, 9, 1, 8, 2, 7, 3, 6, 4, 5], 3)).toEqual([1, 3, 5]);
54
- expect(new Set(topKSlice([1, 1, 1, 2, 2, 2], 3))).toEqual(
55
- new Set([3, 4, 5])
56
- );
57
- });
58
-
59
- test("topKSlice returns top k indexes from a slice in priority order", () => {
60
- expect(topKSlice([0, 1, 2, 3, 4, 5], 2, 1, 5)).toEqual([4, 3]);
61
- expect(topKSlice([0, 9, 1, 8, 2, 7, 3, 6, 4, 5], 3, 1, 5)).toEqual([
62
- 1, 3, 4,
63
- ]);
64
- });
@@ -1,74 +0,0 @@
1
- /** @param {number} ms */
2
- const wait = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
3
-
4
- /**
5
- * @param {TransitionOptions} options
6
- *
7
- * @typedef {Object} TransitionOptions
8
- * @prop {number} [from] default: 0
9
- * @prop {number} [to] default: 1
10
- * @prop {number} [duration] in milliseconds, default: 1000
11
- * @prop {number} [delay] milliseconds to wait before the transition starts, default: 0
12
- * @prop {function(number):void} onUpdate
13
- * @prop {function(number):number} [easingFunction] default: linear
14
- * @prop {function(function(number):void):void} [requestAnimationFrame]
15
- * default: window.requestAnimationFrame
16
- * @prop {AbortSignal} [signal]
17
- */
18
- export default function transition(options) {
19
- const requestAnimationFrame =
20
- options.requestAnimationFrame || window.requestAnimationFrame;
21
-
22
- const signal = options.signal;
23
-
24
- const makePromise = () =>
25
- new Promise((resolve, reject) => {
26
- if (signal?.aborted) {
27
- return reject("aborted");
28
- }
29
-
30
- const beginTimestamp = performance.now();
31
- const endTimestamp = beginTimestamp + (options.duration || 1000);
32
-
33
- const from = typeof options.from == "number" ? options.from : 0;
34
- const to = typeof options.to == "number" ? options.to : 1;
35
- const ease = options.easingFunction || ((x) => x);
36
-
37
- /** @param {number} x */
38
- const toUnit = (x) =>
39
- (x - beginTimestamp) / (endTimestamp - beginTimestamp);
40
-
41
- /** @param {number} x */
42
- const toRange = (x) => x * (to - from) + from;
43
-
44
- /** @param {number} x */
45
- const clamp = (x) => Math.max(0, Math.min(1, x));
46
-
47
- /** @param {number} stamp */
48
- const step = (stamp) => {
49
- if (signal?.aborted) {
50
- reject("aborted");
51
- } else {
52
- options.onUpdate(toRange(ease(clamp(toUnit(stamp)))));
53
- if (stamp < endTimestamp) {
54
- requestAnimationFrame(step);
55
- } else {
56
- options.onUpdate(toRange(ease(1)));
57
- resolve();
58
- }
59
- }
60
- };
61
-
62
- requestAnimationFrame(step);
63
- });
64
-
65
- if (options.delay) {
66
- if (signal?.aborted) {
67
- return Promise.reject("aborted");
68
- }
69
-
70
- return wait(options.delay).then(makePromise);
71
- } else {
72
- return makePromise();
73
- }
74
- }