@genome-spy/core 0.48.1 → 0.48.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.
- package/dist/bundle/index.es.js +3538 -3453
- package/dist/bundle/index.js +84 -84
- package/dist/src/data/collector.d.ts +10 -8
- package/dist/src/data/collector.d.ts.map +1 -1
- package/dist/src/data/collector.js +131 -33
- package/dist/src/data/collector.test.js +55 -1
- package/dist/src/data/transforms/identifier.d.ts +1 -1
- package/dist/src/data/transforms/identifier.d.ts.map +1 -1
- package/dist/src/data/transforms/identifier.js +2 -2
- package/dist/src/data/transforms/identifier.test.js +23 -14
- package/dist/src/genomeSpy.d.ts.map +1 -1
- package/dist/src/genomeSpy.js +14 -15
- package/dist/src/gl/dataToVertices.d.ts +1 -1
- package/dist/src/gl/dataToVertices.d.ts.map +1 -1
- package/dist/src/gl/dataToVertices.js +8 -5
- package/dist/src/gl/glslScaleGenerator.js +1 -1
- package/dist/src/gl/includes/picking.vertex.glsl.js +1 -1
- package/dist/src/utils/animator.d.ts.map +1 -1
- package/dist/src/utils/animator.js +3 -1
- package/dist/src/utils/inertia.d.ts.map +1 -1
- package/dist/src/utils/inertia.js +4 -0
- package/dist/src/utils/iterateNestedMaps.d.ts +4 -3
- package/dist/src/utils/iterateNestedMaps.d.ts.map +1 -1
- package/dist/src/utils/iterateNestedMaps.js +3 -2
- package/dist/src/utils/radixSort.d.ts +9 -0
- package/dist/src/utils/radixSort.d.ts.map +1 -0
- package/dist/src/utils/radixSort.js +130 -0
- package/dist/src/utils/radixSort.test.js +51 -0
- package/package.json +2 -2
|
@@ -37,6 +37,10 @@ export default class Inertia {
|
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
cancel() {
|
|
40
|
+
if (this.lastValue === this.targetValue) {
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
|
|
40
44
|
// decelelerate rapidly
|
|
41
45
|
this.targetValue = lerp([this.lastValue, this.targetValue], 0.3);
|
|
42
46
|
this.smoother({ x: this.targetValue });
|
|
@@ -3,9 +3,10 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Yields arrays that contain the compound key and the grouped data items.
|
|
5
5
|
*
|
|
6
|
-
* @param {Map<any,
|
|
6
|
+
* @param {Map<any, T>} map The root
|
|
7
7
|
* @param {any[]} [path] The path so far.
|
|
8
|
-
* @returns {Generator<[any[],
|
|
8
|
+
* @returns {Generator<[any[], T]>}
|
|
9
|
+
* @template T
|
|
9
10
|
*/
|
|
10
|
-
export default function iterateNestedMaps(map: Map<any,
|
|
11
|
+
export default function iterateNestedMaps<T>(map: Map<any, T>, path?: any[]): Generator<[any[], T], any, any>;
|
|
11
12
|
//# sourceMappingURL=iterateNestedMaps.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"iterateNestedMaps.d.ts","sourceRoot":"","sources":["../../../src/utils/iterateNestedMaps.js"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"iterateNestedMaps.d.ts","sourceRoot":"","sources":["../../../src/utils/iterateNestedMaps.js"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,sEAJW,GAAG,EAAE,mCAef"}
|
|
@@ -3,9 +3,10 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Yields arrays that contain the compound key and the grouped data items.
|
|
5
5
|
*
|
|
6
|
-
* @param {Map<any,
|
|
6
|
+
* @param {Map<any, T>} map The root
|
|
7
7
|
* @param {any[]} [path] The path so far.
|
|
8
|
-
* @returns {Generator<[any[],
|
|
8
|
+
* @returns {Generator<[any[], T]>}
|
|
9
|
+
* @template T
|
|
9
10
|
*/
|
|
10
11
|
export default function* iterateNestedMaps(map, path = []) {
|
|
11
12
|
for (const [key, value] of map.entries()) {
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @param {number[]} arr An array of unsigned integers
|
|
3
|
+
*/
|
|
4
|
+
export default function radixSort(arr: number[]): number[];
|
|
5
|
+
/**
|
|
6
|
+
* @param {number[]} arr An array of unsigned integers
|
|
7
|
+
*/
|
|
8
|
+
export function radixSortIntoLookupArray(arr: number[]): number[];
|
|
9
|
+
//# sourceMappingURL=radixSort.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"radixSort.d.ts","sourceRoot":"","sources":["../../../src/utils/radixSort.js"],"names":[],"mappings":"AAKA;;GAEG;AACH,uCAFW,MAAM,EAAE,YAyDlB;AAaD;;GAEG;AACH,8CAFW,MAAM,EAAE,YAoDlB"}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
const MAX_INTEGER = 2147483647;
|
|
2
|
+
const MAX_INTEGER_DIGIT = getDigits([MAX_INTEGER]);
|
|
3
|
+
|
|
4
|
+
// TODO: Optimize more! Some ideas: https://travisdowns.github.io/blog/2019/05/22/sorting.html
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @param {number[]} arr An array of unsigned integers
|
|
8
|
+
*/
|
|
9
|
+
export default function radixSort(arr) {
|
|
10
|
+
const maxDigits = getDigits(arr);
|
|
11
|
+
|
|
12
|
+
let buffer = new Array(arr.length);
|
|
13
|
+
let bufferPtr = buffer;
|
|
14
|
+
const counts = new Array(16);
|
|
15
|
+
|
|
16
|
+
for (let digitIndex = 0; digitIndex < maxDigits; digitIndex++) {
|
|
17
|
+
counts.fill(0);
|
|
18
|
+
|
|
19
|
+
const shift = digitIndex * 4;
|
|
20
|
+
const pow = Math.pow(16, digitIndex);
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* @param {*} i number
|
|
24
|
+
*/
|
|
25
|
+
// eslint-disable-next-line no-loop-func
|
|
26
|
+
const getDigit = (/** @type {number} */ i) => {
|
|
27
|
+
const value = arr[i];
|
|
28
|
+
|
|
29
|
+
// Need hacks for large numbers because JS bitwise operators only work
|
|
30
|
+
// with 32-bit integers.
|
|
31
|
+
// TODO: This could be implemented in WASM for better performance as
|
|
32
|
+
// it would be able to use 64-bit integers.
|
|
33
|
+
if (digitIndex >= MAX_INTEGER_DIGIT) {
|
|
34
|
+
if (value > MAX_INTEGER) {
|
|
35
|
+
return Math.floor(value / pow) % 16;
|
|
36
|
+
} else {
|
|
37
|
+
return 0;
|
|
38
|
+
}
|
|
39
|
+
} else {
|
|
40
|
+
return (value >> shift) & 0xf;
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
// Count occurrences of each digit
|
|
45
|
+
for (let i = 0, n = arr.length; i < n; i++) {
|
|
46
|
+
counts[getDigit(i)]++;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Prefix sum to get starting indexes
|
|
50
|
+
for (let i = 1; i < 16; i++) {
|
|
51
|
+
counts[i] += counts[i - 1];
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Sort based on current digit
|
|
55
|
+
for (let i = arr.length - 1; i >= 0; i--) {
|
|
56
|
+
bufferPtr[--counts[getDigit(i)]] = arr[i];
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Swap buffer and arr for next iteration
|
|
60
|
+
[arr, bufferPtr] = [bufferPtr, arr];
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return arr;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* @param {number[]} arr An array of unsigned integers
|
|
68
|
+
*/
|
|
69
|
+
function getDigits(arr) {
|
|
70
|
+
let max = 0;
|
|
71
|
+
for (let i = 0, n = arr.length; i < n; i++) {
|
|
72
|
+
max = Math.max(max, arr[i]);
|
|
73
|
+
}
|
|
74
|
+
return Math.floor(Math.log2(max) / 4) + 1;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* @param {number[]} arr An array of unsigned integers
|
|
79
|
+
*/
|
|
80
|
+
export function radixSortIntoLookupArray(arr) {
|
|
81
|
+
const maxDigits = getDigits(arr);
|
|
82
|
+
let indexes = Array.from({ length: arr.length }, (_, i) => i);
|
|
83
|
+
let buffer = new Array(arr.length);
|
|
84
|
+
const counts = new Array(16);
|
|
85
|
+
|
|
86
|
+
for (let digitIndex = 0; digitIndex < maxDigits; digitIndex++) {
|
|
87
|
+
counts.fill(0);
|
|
88
|
+
|
|
89
|
+
const shift = digitIndex * 4;
|
|
90
|
+
const pow = Math.pow(16, digitIndex);
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* @param {*} i number
|
|
94
|
+
*/
|
|
95
|
+
// eslint-disable-next-line no-loop-func
|
|
96
|
+
const getDigit = (i) => {
|
|
97
|
+
const value = arr[indexes[i]]; // Use index to access array value
|
|
98
|
+
|
|
99
|
+
if (digitIndex >= MAX_INTEGER_DIGIT) {
|
|
100
|
+
if (value > MAX_INTEGER) {
|
|
101
|
+
return Math.floor(value / pow) % 16;
|
|
102
|
+
} else {
|
|
103
|
+
return 0;
|
|
104
|
+
}
|
|
105
|
+
} else {
|
|
106
|
+
return (value >> shift) & 0xf;
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
// Count occurrences of each digit
|
|
111
|
+
for (let i = 0; i < arr.length; i++) {
|
|
112
|
+
counts[getDigit(i)]++;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// Prefix sum to get starting indexes
|
|
116
|
+
for (let i = 1; i < 16; i++) {
|
|
117
|
+
counts[i] += counts[i - 1];
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// Sort indexes based on current digit
|
|
121
|
+
for (let i = arr.length - 1; i >= 0; i--) {
|
|
122
|
+
buffer[--counts[getDigit(i)]] = indexes[i];
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// Swap buffer and indexes for next iteration
|
|
126
|
+
[indexes, buffer] = [buffer, indexes];
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
return indexes; // Return the sorted index array
|
|
130
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { expect, test } from "vitest";
|
|
2
|
+
import radixSort, { radixSortIntoLookupArray } from "./radixSort.js";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Checks that numbers in an array are in ascending order.
|
|
6
|
+
|
|
7
|
+
* @param {number[]} arr An array of unsigned integers
|
|
8
|
+
*/
|
|
9
|
+
function isSorted(arr) {
|
|
10
|
+
for (let i = 1; i < arr.length; i++) {
|
|
11
|
+
if (arr[i - 1] > arr[i]) {
|
|
12
|
+
return false;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
return true;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Generates a random array of unsigned integers.
|
|
21
|
+
*
|
|
22
|
+
* @param {number} length
|
|
23
|
+
*/
|
|
24
|
+
function generateArray(length) {
|
|
25
|
+
const arr = new Array(length);
|
|
26
|
+
|
|
27
|
+
for (let i = 0; i < length; i++) {
|
|
28
|
+
arr[i] = Math.floor(Math.random() * 10_000_000_000);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return arr;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
test("Radix Sort correctly sorts numbers", () => {
|
|
35
|
+
expect(isSorted(radixSort([1, 2, 3]))).toBeTruthy();
|
|
36
|
+
expect(isSorted(radixSort([3, 2, 1]))).toBeTruthy();
|
|
37
|
+
expect(isSorted(radixSort([123, 1234567, 12, 1, 1234]))).toBeTruthy();
|
|
38
|
+
expect(isSorted(radixSort(generateArray(1_000_000)))).toBeTruthy();
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
test("Lookup", () => {
|
|
42
|
+
expect(radixSortIntoLookupArray([1, 2, 3])).toEqual([0, 1, 2]);
|
|
43
|
+
expect(radixSortIntoLookupArray([3, 2, 1])).toEqual([2, 1, 0]);
|
|
44
|
+
expect(radixSortIntoLookupArray([10000, 100, 1000, 10, 1])).toEqual([
|
|
45
|
+
4, 3, 1, 2, 0,
|
|
46
|
+
]);
|
|
47
|
+
|
|
48
|
+
const arr = generateArray(1_000_000);
|
|
49
|
+
const lookup = radixSortIntoLookupArray(arr);
|
|
50
|
+
expect(isSorted(arr.map((_, i) => arr[lookup[i]]))).toBeTruthy();
|
|
51
|
+
});
|
package/package.json
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
},
|
|
8
8
|
"contributors": [],
|
|
9
9
|
"license": "MIT",
|
|
10
|
-
"version": "0.48.
|
|
10
|
+
"version": "0.48.2",
|
|
11
11
|
"jsdelivr": "dist/bundle/index.js",
|
|
12
12
|
"unpkg": "dist/bundle/index.js",
|
|
13
13
|
"browser": "dist/bundle/index.js",
|
|
@@ -64,5 +64,5 @@
|
|
|
64
64
|
"vega-scale": "^7.3.1",
|
|
65
65
|
"vega-util": "^1.17.2"
|
|
66
66
|
},
|
|
67
|
-
"gitHead": "
|
|
67
|
+
"gitHead": "f2817f82263b92e453356083f2d770b8b236f77a"
|
|
68
68
|
}
|