@genspectrum/dashboard-components 0.6.18 → 0.7.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.
- package/README.md +5 -12
- package/custom-elements.json +22 -22
- package/dist/assets/mutationOverTimeWorker-BOCXtKzd.js.map +1 -0
- package/dist/dashboard-components.js +301 -302
- package/dist/dashboard-components.js.map +1 -1
- package/dist/genspectrum-components.d.ts +60 -10
- package/dist/style.css +3 -2
- package/package.json +13 -4
- package/src/index.ts +1 -0
- package/src/operator/FetchInsertionsOperator.ts +2 -2
- package/src/operator/FetchSubstitutionsOrDeletionsOperator.ts +3 -3
- package/src/preact/dateRangeSelector/computeInitialValues.spec.ts +53 -38
- package/src/preact/dateRangeSelector/computeInitialValues.ts +17 -23
- package/src/preact/dateRangeSelector/date-range-selector.stories.tsx +46 -32
- package/src/preact/dateRangeSelector/date-range-selector.tsx +24 -26
- package/src/preact/dateRangeSelector/dateRangeOption.ts +65 -0
- package/src/preact/dateRangeSelector/selectableOptions.ts +17 -66
- package/src/preact/mutationComparison/fetchMutationData.spec.ts +3 -3
- package/src/preact/mutationComparison/getMutationComparisonTableData.spec.ts +11 -11
- package/src/preact/mutationComparison/getMutationComparisonTableData.ts +4 -4
- package/src/preact/mutationComparison/mutation-comparison-table.tsx +2 -2
- package/src/preact/mutationFilter/mutation-filter.tsx +27 -18
- package/src/preact/mutationFilter/parseAndValidateMutation.ts +4 -4
- package/src/preact/mutationFilter/parseMutation.spec.ts +17 -17
- package/src/preact/mutations/getInsertionsTableData.spec.ts +3 -3
- package/src/preact/mutations/getMutationsGridData.spec.ts +9 -9
- package/src/preact/mutations/getMutationsTableData.spec.ts +7 -7
- package/src/preact/mutations/mutations-insertions-table.tsx +3 -3
- package/src/preact/mutations/mutations-table.tsx +3 -3
- package/src/preact/mutationsOverTime/MutationOverTimeData.ts +20 -0
- package/src/preact/mutationsOverTime/__mockData__/aminoAcidMutationsByDay.ts +45686 -0
- package/src/preact/mutationsOverTime/__mockData__/byWeek.ts +58989 -0
- package/src/preact/mutationsOverTime/__mockData__/defaultMockData.ts +103991 -0
- package/src/preact/mutationsOverTime/__mockData__/mockConversion.ts +54 -0
- package/src/preact/mutationsOverTime/__mockData__/showsMessageWhenTooManyMutations.ts +63690 -0
- package/src/preact/mutationsOverTime/getFilteredMutationsOverTime.spec.ts +177 -161
- package/src/preact/mutationsOverTime/getFilteredMutationsOverTimeData.ts +17 -59
- package/src/preact/mutationsOverTime/mutationOverTimeWorker.mock.ts +27 -0
- package/src/preact/mutationsOverTime/mutationOverTimeWorker.ts +29 -0
- package/src/preact/mutationsOverTime/mutations-over-time-grid.tsx +13 -14
- package/src/preact/mutationsOverTime/mutations-over-time.stories.tsx +9 -334
- package/src/preact/mutationsOverTime/mutations-over-time.tsx +59 -54
- package/src/preact/numberSequencesOverTime/getNumberOfSequencesOverTimeTableData.ts +3 -3
- package/src/preact/prevalenceOverTime/getPrevalenceOverTimeTableData.spec.ts +5 -5
- package/src/preact/prevalenceOverTime/prevalence-over-time-bubble-chart.tsx +1 -1
- package/src/preact/relativeGrowthAdvantage/relative-growth-advantage-chart.tsx +2 -2
- package/src/preact/shared/sort/sortInsertions.spec.ts +11 -11
- package/src/preact/shared/sort/sortInsertions.ts +2 -2
- package/src/preact/shared/sort/sortSubstitutionsAndDeletions.spec.ts +13 -13
- package/src/preact/shared/sort/sortSubstitutionsAndDeletions.ts +7 -4
- package/src/preact/webWorkers/useWebWorker.ts +51 -0
- package/src/preact/webWorkers/workerFunction.ts +14 -0
- package/src/query/queryAggregatedDataOverTime.ts +3 -3
- package/src/query/queryMutationsOverTime.spec.ts +272 -51
- package/src/query/queryMutationsOverTime.ts +114 -47
- package/src/query/queryPrevalenceOverTime.ts +2 -2
- package/src/query/queryRelativeGrowthAdvantage.ts +3 -3
- package/src/types.ts +25 -5
- package/src/utils/map2d.spec.ts +79 -12
- package/src/utils/map2d.ts +25 -5
- package/src/utils/mutations.spec.ts +20 -20
- package/src/utils/mutations.ts +80 -17
- package/src/utils/sort.ts +5 -2
- package/src/utils/temporal.spec.ts +27 -24
- package/src/utils/{temporal.ts → temporalClass.ts} +170 -72
- package/src/utils/temporalTestHelpers.ts +3 -3
- package/src/web-components/input/gs-date-range-selector.stories.ts +16 -28
- package/src/web-components/input/gs-date-range-selector.tsx +17 -32
- package/src/web-components/introduction.mdx +46 -0
- package/src/web-components/visualization/gs-mutations-over-time.stories.ts +6 -699
- package/src/web-components/visualization/gs-mutations-over-time.tsx +2 -2
- package/standalone-bundle/dashboard-components.js +12011 -12778
- package/standalone-bundle/dashboard-components.js.map +1 -1
- package/src/preact/mutationsOverTime/__mockData__/aggregated_2024_01.json +0 -13
- package/src/preact/mutationsOverTime/__mockData__/aggregated_2024_02.json +0 -13
- package/src/preact/mutationsOverTime/__mockData__/aggregated_2024_03.json +0 -13
- package/src/preact/mutationsOverTime/__mockData__/aggregated_2024_04.json +0 -13
- package/src/preact/mutationsOverTime/__mockData__/aggregated_2024_05.json +0 -13
- package/src/preact/mutationsOverTime/__mockData__/aggregated_2024_06.json +0 -13
- package/src/preact/mutationsOverTime/__mockData__/aggregated_2024_07.json +0 -13
- package/src/preact/mutationsOverTime/__mockData__/aggregated_20_01_2024.json +0 -13
- package/src/preact/mutationsOverTime/__mockData__/aggregated_21_01_2024.json +0 -13
- package/src/preact/mutationsOverTime/__mockData__/aggregated_22_01_2024.json +0 -13
- package/src/preact/mutationsOverTime/__mockData__/aggregated_23_01_2024.json +0 -13
- package/src/preact/mutationsOverTime/__mockData__/aggregated_24_01_2024.json +0 -13
- package/src/preact/mutationsOverTime/__mockData__/aggregated_25_01_2024.json +0 -13
- package/src/preact/mutationsOverTime/__mockData__/aggregated_26_01_2024.json +0 -13
- package/src/preact/mutationsOverTime/__mockData__/aggregated_byDay.json +0 -38
- package/src/preact/mutationsOverTime/__mockData__/aggregated_byWeek.json +0 -122
- package/src/preact/mutationsOverTime/__mockData__/aggregated_date.json +0 -642
- package/src/preact/mutationsOverTime/__mockData__/aggregated_tooManyMutations.json +0 -1470
- package/src/preact/mutationsOverTime/__mockData__/aggregated_tooManyMutations_total.json +0 -13
- package/src/preact/mutationsOverTime/__mockData__/aggregated_week3_2024.json +0 -13
- package/src/preact/mutationsOverTime/__mockData__/aggregated_week4_2024.json +0 -13
- package/src/preact/mutationsOverTime/__mockData__/aggregated_week5_2024.json +0 -13
- package/src/preact/mutationsOverTime/__mockData__/aggregated_week6_2024.json +0 -13
- package/src/preact/mutationsOverTime/__mockData__/aminoAcidMutations_20_01_2024.json +0 -6778
- package/src/preact/mutationsOverTime/__mockData__/aminoAcidMutations_21_01_2024.json +0 -7129
- package/src/preact/mutationsOverTime/__mockData__/aminoAcidMutations_22_01_2024.json +0 -4681
- package/src/preact/mutationsOverTime/__mockData__/aminoAcidMutations_23_01_2024.json +0 -10738
- package/src/preact/mutationsOverTime/__mockData__/aminoAcidMutations_24_01_2024.json +0 -11710
- package/src/preact/mutationsOverTime/__mockData__/aminoAcidMutations_25_01_2024.json +0 -11557
- package/src/preact/mutationsOverTime/__mockData__/aminoAcidMutations_26_01_2024.json +0 -8596
- package/src/preact/mutationsOverTime/__mockData__/aminoAcidMutations_byDayOverall.json +0 -4726
- package/src/preact/mutationsOverTime/__mockData__/nucleotideMutations_2024_01.json +0 -1747
- package/src/preact/mutationsOverTime/__mockData__/nucleotideMutations_2024_02.json +0 -1774
- package/src/preact/mutationsOverTime/__mockData__/nucleotideMutations_2024_03.json +0 -1819
- package/src/preact/mutationsOverTime/__mockData__/nucleotideMutations_2024_04.json +0 -1864
- package/src/preact/mutationsOverTime/__mockData__/nucleotideMutations_2024_05.json +0 -1927
- package/src/preact/mutationsOverTime/__mockData__/nucleotideMutations_2024_06.json +0 -1864
- package/src/preact/mutationsOverTime/__mockData__/nucleotideMutations_2024_07.json +0 -9
- package/src/preact/mutationsOverTime/__mockData__/nucleotideMutations_byMonthOverall.json +0 -11143
- package/src/preact/mutationsOverTime/__mockData__/nucleotideMutations_byWeekOverall.json +0 -9154
- package/src/preact/mutationsOverTime/__mockData__/nucleotideMutations_tooManyMutations.json +0 -16453
- package/src/preact/mutationsOverTime/__mockData__/nucleotideMutations_week3_2024.json +0 -8812
- package/src/preact/mutationsOverTime/__mockData__/nucleotideMutations_week4_2024.json +0 -9730
- package/src/preact/mutationsOverTime/__mockData__/nucleotideMutations_week5_2024.json +0 -9865
- package/src/preact/mutationsOverTime/__mockData__/nucleotideMutations_week6_2024.json +0 -11314
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
import { describe, expect, test } from 'vitest';
|
|
2
2
|
|
|
3
3
|
import { sortInsertions } from './sortInsertions';
|
|
4
|
-
import {
|
|
4
|
+
import { InsertionClass } from '../../../utils/mutations';
|
|
5
5
|
|
|
6
6
|
describe('sortInsertions with no segments', () => {
|
|
7
7
|
test('should sort for positions first', () => {
|
|
8
|
-
const a = new
|
|
9
|
-
const b = new
|
|
8
|
+
const a = new InsertionClass(undefined, 1, 'A');
|
|
9
|
+
const b = new InsertionClass(undefined, 2, 'A');
|
|
10
10
|
|
|
11
11
|
expect(sortInsertions(a, b)).toBeLessThan(0);
|
|
12
12
|
expect(sortInsertions(b, a)).toBeGreaterThan(0);
|
|
13
13
|
});
|
|
14
14
|
|
|
15
15
|
test('should sort for symbols second', () => {
|
|
16
|
-
const a = new
|
|
17
|
-
const b = new
|
|
16
|
+
const a = new InsertionClass(undefined, 1, 'A');
|
|
17
|
+
const b = new InsertionClass(undefined, 1, 'B');
|
|
18
18
|
|
|
19
19
|
expect(sortInsertions(a, b)).toBeLessThan(0);
|
|
20
20
|
expect(sortInsertions(b, a)).toBeGreaterThan(0);
|
|
@@ -23,24 +23,24 @@ describe('sortInsertions with no segments', () => {
|
|
|
23
23
|
|
|
24
24
|
describe('sortInsertions with segments', () => {
|
|
25
25
|
test('should sort for segments first', () => {
|
|
26
|
-
const a = new
|
|
27
|
-
const b = new
|
|
26
|
+
const a = new InsertionClass('AA1', 1, 'A');
|
|
27
|
+
const b = new InsertionClass('BB1', 1, 'A');
|
|
28
28
|
|
|
29
29
|
expect(sortInsertions(a, b)).toBeLessThan(0);
|
|
30
30
|
expect(sortInsertions(b, a)).toBeGreaterThan(0);
|
|
31
31
|
});
|
|
32
32
|
|
|
33
33
|
test('should sort for positions second', () => {
|
|
34
|
-
const a = new
|
|
35
|
-
const b = new
|
|
34
|
+
const a = new InsertionClass('AA1', 1, 'A');
|
|
35
|
+
const b = new InsertionClass('AA1', 2, 'A');
|
|
36
36
|
|
|
37
37
|
expect(sortInsertions(a, b)).toBeLessThan(0);
|
|
38
38
|
expect(sortInsertions(b, a)).toBeGreaterThan(0);
|
|
39
39
|
});
|
|
40
40
|
|
|
41
41
|
test('should sort for symbols third', () => {
|
|
42
|
-
const a = new
|
|
43
|
-
const b = new
|
|
42
|
+
const a = new InsertionClass('AA1', 1, 'A');
|
|
43
|
+
const b = new InsertionClass('AA1', 1, 'B');
|
|
44
44
|
|
|
45
45
|
expect(sortInsertions(a, b)).toBeLessThan(0);
|
|
46
46
|
expect(sortInsertions(b, a)).toBeGreaterThan(0);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { comparePositions, compareSegments } from './sortSubstitutionsAndDeletions';
|
|
2
|
-
import { type
|
|
2
|
+
import { type InsertionClass } from '../../../utils/mutations';
|
|
3
3
|
|
|
4
|
-
export const sortInsertions = (a:
|
|
4
|
+
export const sortInsertions = (a: InsertionClass, b: InsertionClass) => {
|
|
5
5
|
if (a.segment !== b.segment) {
|
|
6
6
|
return compareSegments(a.segment, b.segment);
|
|
7
7
|
}
|
|
@@ -1,28 +1,28 @@
|
|
|
1
1
|
import { describe, expect, test } from 'vitest';
|
|
2
2
|
|
|
3
3
|
import { sortSubstitutionsAndDeletions } from './sortSubstitutionsAndDeletions';
|
|
4
|
-
import {
|
|
4
|
+
import { DeletionClass, SubstitutionClass } from '../../../utils/mutations';
|
|
5
5
|
|
|
6
6
|
describe('sortSubstitutionsAndDeletions with no segments', () => {
|
|
7
7
|
test('should sort for positions first', () => {
|
|
8
|
-
const a = new
|
|
9
|
-
const b = new
|
|
8
|
+
const a = new SubstitutionClass(undefined, 'A', 'B', 123);
|
|
9
|
+
const b = new SubstitutionClass(undefined, 'A', 'B', 234);
|
|
10
10
|
|
|
11
11
|
expect(sortSubstitutionsAndDeletions(a, b)).toBeLessThan(0);
|
|
12
12
|
expect(sortSubstitutionsAndDeletions(b, a)).toBeGreaterThan(0);
|
|
13
13
|
});
|
|
14
14
|
|
|
15
15
|
test('should sort for substitutionValue second', () => {
|
|
16
|
-
const a = new
|
|
17
|
-
const b = new
|
|
16
|
+
const a = new SubstitutionClass(undefined, 'A', 'A', 123);
|
|
17
|
+
const b = new SubstitutionClass(undefined, 'A', 'B', 123);
|
|
18
18
|
|
|
19
19
|
expect(sortSubstitutionsAndDeletions(a, b)).toBeLessThan(0);
|
|
20
20
|
expect(sortSubstitutionsAndDeletions(b, a)).toBeGreaterThan(0);
|
|
21
21
|
});
|
|
22
22
|
|
|
23
23
|
test('should sort for substitutionValue over deletion', () => {
|
|
24
|
-
const a = new
|
|
25
|
-
const b = new
|
|
24
|
+
const a = new SubstitutionClass(undefined, 'A', 'A', 123);
|
|
25
|
+
const b = new DeletionClass(undefined, 'A', 123);
|
|
26
26
|
|
|
27
27
|
expect(sortSubstitutionsAndDeletions(a, b)).toBeLessThan(0);
|
|
28
28
|
expect(sortSubstitutionsAndDeletions(b, a)).toBeGreaterThan(0);
|
|
@@ -31,24 +31,24 @@ describe('sortSubstitutionsAndDeletions with no segments', () => {
|
|
|
31
31
|
|
|
32
32
|
describe('sortSubstitutionsAndDeletions with segments', () => {
|
|
33
33
|
test('should sort for segment first', () => {
|
|
34
|
-
const a = new
|
|
35
|
-
const b = new
|
|
34
|
+
const a = new SubstitutionClass('AA1', 'A', 'B', 123);
|
|
35
|
+
const b = new SubstitutionClass('BB1', 'A', 'B', 123);
|
|
36
36
|
|
|
37
37
|
expect(sortSubstitutionsAndDeletions(a, b)).toBeLessThan(0);
|
|
38
38
|
expect(sortSubstitutionsAndDeletions(b, a)).toBeGreaterThan(0);
|
|
39
39
|
});
|
|
40
40
|
|
|
41
41
|
test('should sort for position second', () => {
|
|
42
|
-
const a = new
|
|
43
|
-
const b = new
|
|
42
|
+
const a = new SubstitutionClass('AA1', 'A', 'B', 123);
|
|
43
|
+
const b = new SubstitutionClass('AA1', 'A', 'B', 234);
|
|
44
44
|
|
|
45
45
|
expect(sortSubstitutionsAndDeletions(a, b)).toBeLessThan(0);
|
|
46
46
|
expect(sortSubstitutionsAndDeletions(b, a)).toBeGreaterThan(0);
|
|
47
47
|
});
|
|
48
48
|
|
|
49
49
|
test('should sort for substitutionValue third', () => {
|
|
50
|
-
const a = new
|
|
51
|
-
const b = new
|
|
50
|
+
const a = new SubstitutionClass('AA1', 'A', 'A', 123);
|
|
51
|
+
const b = new SubstitutionClass('AA1', 'A', 'B', 123);
|
|
52
52
|
|
|
53
53
|
expect(sortSubstitutionsAndDeletions(a, b)).toBeLessThan(0);
|
|
54
54
|
expect(sortSubstitutionsAndDeletions(b, a)).toBeGreaterThan(0);
|
|
@@ -1,6 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { DeletionClass, type SubstitutionClass } from '../../../utils/mutations';
|
|
2
2
|
|
|
3
|
-
export const sortSubstitutionsAndDeletions = (
|
|
3
|
+
export const sortSubstitutionsAndDeletions = (
|
|
4
|
+
a: SubstitutionClass | DeletionClass,
|
|
5
|
+
b: SubstitutionClass | DeletionClass,
|
|
6
|
+
) => {
|
|
4
7
|
if (a.segment !== b.segment) {
|
|
5
8
|
return compareSegments(a.segment, b.segment);
|
|
6
9
|
}
|
|
@@ -9,8 +12,8 @@ export const sortSubstitutionsAndDeletions = (a: Substitution | Deletion, b: Sub
|
|
|
9
12
|
return comparePositions(a.position, b.position);
|
|
10
13
|
}
|
|
11
14
|
|
|
12
|
-
const aIsDeletion = a instanceof
|
|
13
|
-
const bIsDeletion = b instanceof
|
|
15
|
+
const aIsDeletion = a instanceof DeletionClass;
|
|
16
|
+
const bIsDeletion = b instanceof DeletionClass;
|
|
14
17
|
|
|
15
18
|
if (aIsDeletion !== bIsDeletion) {
|
|
16
19
|
return aIsDeletion ? 1 : -1;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { useEffect, useMemo, useState } from 'preact/hooks';
|
|
2
|
+
|
|
3
|
+
export function useWebWorker<Request, Response>(messageToWorker: Request, worker: Worker) {
|
|
4
|
+
const [data, setData] = useState<Response | undefined>(undefined);
|
|
5
|
+
const [error, setError] = useState<Error | undefined>(undefined);
|
|
6
|
+
const [isLoading, setIsLoading] = useState(true);
|
|
7
|
+
|
|
8
|
+
useEffect(() => {
|
|
9
|
+
worker.onmessage = (
|
|
10
|
+
event: MessageEvent<{
|
|
11
|
+
status: 'loading' | 'success' | 'error';
|
|
12
|
+
data?: Response;
|
|
13
|
+
error?: Error;
|
|
14
|
+
}>,
|
|
15
|
+
) => {
|
|
16
|
+
const { status, data, error } = event.data;
|
|
17
|
+
|
|
18
|
+
switch (status) {
|
|
19
|
+
case 'loading':
|
|
20
|
+
setIsLoading(true);
|
|
21
|
+
break;
|
|
22
|
+
case 'success':
|
|
23
|
+
setData(data);
|
|
24
|
+
setError(undefined);
|
|
25
|
+
setIsLoading(false);
|
|
26
|
+
break;
|
|
27
|
+
case 'error':
|
|
28
|
+
setError(error);
|
|
29
|
+
setIsLoading(false);
|
|
30
|
+
break;
|
|
31
|
+
default:
|
|
32
|
+
throw new Error(`Unknown status: ${status}`);
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
worker.onmessageerror = (event: MessageEvent) => {
|
|
37
|
+
setError(new Error(`Worker received a message that it cannot deserialize: ${event.data}`));
|
|
38
|
+
setIsLoading(false);
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
return () => {
|
|
42
|
+
worker.terminate();
|
|
43
|
+
};
|
|
44
|
+
}, []);
|
|
45
|
+
|
|
46
|
+
useMemo(() => {
|
|
47
|
+
worker.postMessage(messageToWorker);
|
|
48
|
+
}, [messageToWorker]);
|
|
49
|
+
|
|
50
|
+
return { data, error, isLoading };
|
|
51
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export async function workerFunction<R>(queryFunction: () => R) {
|
|
2
|
+
try {
|
|
3
|
+
postMessage({ status: 'loading' });
|
|
4
|
+
|
|
5
|
+
const workerResponse = await queryFunction();
|
|
6
|
+
|
|
7
|
+
postMessage({
|
|
8
|
+
status: 'success',
|
|
9
|
+
data: workerResponse,
|
|
10
|
+
});
|
|
11
|
+
} catch (error) {
|
|
12
|
+
postMessage({ status: 'error', error });
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -11,8 +11,8 @@ import {
|
|
|
11
11
|
generateAllInRange,
|
|
12
12
|
getMinMaxTemporal,
|
|
13
13
|
parseDateStringToTemporal,
|
|
14
|
-
type
|
|
15
|
-
} from '../utils/
|
|
14
|
+
type TemporalClass,
|
|
15
|
+
} from '../utils/temporalClass';
|
|
16
16
|
|
|
17
17
|
export function queryAggregatedDataOverTime<LapisDateField extends string>(
|
|
18
18
|
filter: LapisFilter,
|
|
@@ -46,7 +46,7 @@ export function mapDateToGranularityRange(
|
|
|
46
46
|
};
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
-
function averageSmoothing(slidingWindow: { dateRange:
|
|
49
|
+
function averageSmoothing(slidingWindow: { dateRange: TemporalClass | null; count: number }[]) {
|
|
50
50
|
const average = slidingWindow.reduce((acc, curr) => acc + curr.count, 0) / slidingWindow.length;
|
|
51
51
|
const centerIndex = Math.floor(slidingWindow.length / 2);
|
|
52
52
|
return { dateRange: slidingWindow[centerIndex].dateRange, count: average };
|