@genspectrum/dashboard-components 0.11.6 → 0.12.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/custom-elements.json +50 -15
- package/dist/{dateRangeOption-Bh2p78z0.js → LocationChangedEvent-CORvQvXv.js} +11 -1
- package/dist/LocationChangedEvent-CORvQvXv.js.map +1 -0
- package/dist/assets/{mutationOverTimeWorker-CWneD7i5.js.map → mutationOverTimeWorker-DTv93Ere.js.map} +1 -1
- package/dist/components.d.ts +79 -51
- package/dist/components.js +3951 -621
- package/dist/components.js.map +1 -1
- package/dist/style.css +151 -4
- package/dist/util.d.ts +78 -44
- package/dist/util.js +2 -1
- package/package.json +2 -1
- package/src/preact/components/csv-download-button.tsx +2 -2
- package/src/preact/downshift_types.d.ts +3 -0
- package/src/preact/locationFilter/LocationChangedEvent.ts +11 -0
- package/src/preact/locationFilter/fetchAutocompletionList.spec.ts +5 -5
- package/src/preact/locationFilter/fetchAutocompletionList.ts +9 -2
- package/src/preact/locationFilter/location-filter.stories.tsx +94 -10
- package/src/preact/locationFilter/location-filter.tsx +183 -62
- package/src/preact/mutationFilter/mutation-filter-info.tsx +73 -10
- package/src/preact/mutations/__mockData__/baselineNucleotideMutations.json +337412 -0
- package/src/preact/mutations/__mockData__/overallVariantCount.json +14 -0
- package/src/preact/mutations/getMutationsTableData.spec.ts +20 -3
- package/src/preact/mutations/getMutationsTableData.ts +37 -2
- package/src/preact/mutations/mutations-table.tsx +47 -27
- package/src/preact/mutations/mutations.stories.tsx +41 -9
- package/src/preact/mutations/mutations.tsx +22 -6
- package/src/preact/mutations/queryMutations.ts +28 -8
- package/src/preact/mutationsOverTime/__mockData__/aminoAcidMutationsByDay.ts +11077 -3062
- package/src/preact/mutationsOverTime/__mockData__/byWeek.ts +3883 -6606
- package/src/preact/mutationsOverTime/__mockData__/defaultMockData.ts +17624 -2203
- package/src/preact/mutationsOverTime/mutations-over-time.tsx +1 -1
- package/src/query/queryMutationsOverTime.spec.ts +144 -4
- package/src/query/queryMutationsOverTime.ts +17 -1
- package/src/utilEntrypoint.ts +2 -0
- package/src/web-components/input/gs-location-filter.stories.ts +34 -29
- package/src/web-components/input/gs-location-filter.tsx +6 -13
- package/src/web-components/visualization/gs-mutations.stories.ts +62 -4
- package/src/web-components/visualization/gs-mutations.tsx +44 -0
- package/standalone-bundle/assets/{mutationOverTimeWorker-x1ipPFL0.js.map → mutationOverTimeWorker-DEybsZ5r.js.map} +1 -1
- package/standalone-bundle/dashboard-components.js +11021 -8621
- package/standalone-bundle/dashboard-components.js.map +1 -1
- package/standalone-bundle/style.css +1 -1
- package/dist/dateRangeOption-Bh2p78z0.js.map +0 -1
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"data": [
|
|
3
|
+
{
|
|
4
|
+
"count": 16616
|
|
5
|
+
}
|
|
6
|
+
],
|
|
7
|
+
"info": {
|
|
8
|
+
"dataVersion": "1736354557",
|
|
9
|
+
"requestId": "a11bb8e3-cd57-4178-8f51-7ff1210ffebf",
|
|
10
|
+
"requestInfo": "sars_cov-2_nextstrain_open on lapis.cov-spectrum.org at 2025-01-09T08:05:35.534992279",
|
|
11
|
+
"reportTo": "Please report to https://github.com/GenSpectrum/LAPIS/issues in case you encounter any unexpected issues. Please include the request ID and the requestInfo in your report.",
|
|
12
|
+
"lapisVersion": "0.3.10"
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -22,9 +22,24 @@ describe('getMutationsTableData', () => {
|
|
|
22
22
|
|
|
23
23
|
const proportionInterval = { min: 0, max: 1 };
|
|
24
24
|
|
|
25
|
-
const result = getMutationsTableData(data, proportionInterval);
|
|
25
|
+
const result = getMutationsTableData(data, data, 2, proportionInterval);
|
|
26
26
|
|
|
27
|
-
expect(result).toEqual(
|
|
27
|
+
expect(result).toEqual([
|
|
28
|
+
{
|
|
29
|
+
type: 'substitution' as const,
|
|
30
|
+
mutation: new SubstitutionClass('segment1', 'A', 'T', 123),
|
|
31
|
+
count: 1,
|
|
32
|
+
proportion: 0.1,
|
|
33
|
+
jaccardSimilarity: 0.5,
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
type: 'deletion' as const,
|
|
37
|
+
mutation: new DeletionClass('segment2', 'C', 123),
|
|
38
|
+
count: 2,
|
|
39
|
+
proportion: 0.2,
|
|
40
|
+
jaccardSimilarity: 1,
|
|
41
|
+
},
|
|
42
|
+
]);
|
|
28
43
|
});
|
|
29
44
|
|
|
30
45
|
test('should filter out data below/above proportionInterval', () => {
|
|
@@ -64,7 +79,7 @@ describe('getMutationsTableData', () => {
|
|
|
64
79
|
|
|
65
80
|
const proportionInterval = { min: 0.05, max: 0.9 };
|
|
66
81
|
|
|
67
|
-
const result = getMutationsTableData(data, proportionInterval);
|
|
82
|
+
const result = getMutationsTableData(data, data, 2, proportionInterval);
|
|
68
83
|
|
|
69
84
|
expect(result).toEqual([
|
|
70
85
|
{
|
|
@@ -72,12 +87,14 @@ describe('getMutationsTableData', () => {
|
|
|
72
87
|
type: 'substitution',
|
|
73
88
|
count: 1,
|
|
74
89
|
proportion: inInterval,
|
|
90
|
+
jaccardSimilarity: 0.5,
|
|
75
91
|
},
|
|
76
92
|
{
|
|
77
93
|
mutation: deletionInInterval,
|
|
78
94
|
type: 'deletion',
|
|
79
95
|
count: 2,
|
|
80
96
|
proportion: inInterval,
|
|
97
|
+
jaccardSimilarity: 1,
|
|
81
98
|
},
|
|
82
99
|
]);
|
|
83
100
|
});
|
|
@@ -1,12 +1,17 @@
|
|
|
1
1
|
import { type SubstitutionOrDeletionEntry } from '../../types';
|
|
2
2
|
import { type ProportionInterval } from '../components/proportion-selector';
|
|
3
3
|
|
|
4
|
-
export function getMutationsTableData(
|
|
4
|
+
export function getMutationsTableData(
|
|
5
|
+
data: SubstitutionOrDeletionEntry[],
|
|
6
|
+
baselineSubstitutionsOrDeletions: SubstitutionOrDeletionEntry[] | undefined,
|
|
7
|
+
overallVariantCount: number,
|
|
8
|
+
proportionInterval: ProportionInterval,
|
|
9
|
+
) {
|
|
5
10
|
const byProportion = (mutationEntry: SubstitutionOrDeletionEntry) => {
|
|
6
11
|
return mutationEntry.proportion >= proportionInterval.min && mutationEntry.proportion <= proportionInterval.max;
|
|
7
12
|
};
|
|
8
13
|
|
|
9
|
-
|
|
14
|
+
const tableData = data.filter(byProportion).map((mutationEntry) => {
|
|
10
15
|
return {
|
|
11
16
|
mutation: mutationEntry.mutation,
|
|
12
17
|
type: mutationEntry.type,
|
|
@@ -14,4 +19,34 @@ export function getMutationsTableData(data: SubstitutionOrDeletionEntry[], propo
|
|
|
14
19
|
proportion: mutationEntry.proportion,
|
|
15
20
|
};
|
|
16
21
|
});
|
|
22
|
+
|
|
23
|
+
if (baselineSubstitutionsOrDeletions === undefined) {
|
|
24
|
+
return tableData;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const baselineMutationCounts = baselineSubstitutionsOrDeletions.reduce((baselineMutationCounts, mutation) => {
|
|
28
|
+
baselineMutationCounts.set(mutation.mutation.code, mutation.count);
|
|
29
|
+
return baselineMutationCounts;
|
|
30
|
+
}, new Map<string, number>());
|
|
31
|
+
|
|
32
|
+
return tableData.map((datum) => {
|
|
33
|
+
const baselineMutationCount = baselineMutationCounts.get(datum.mutation.code) || 0;
|
|
34
|
+
const jaccardSimilarity = calculateJaccardSimilarity(overallVariantCount, baselineMutationCount, datum.count);
|
|
35
|
+
|
|
36
|
+
return {
|
|
37
|
+
...datum,
|
|
38
|
+
jaccardSimilarity,
|
|
39
|
+
};
|
|
40
|
+
});
|
|
17
41
|
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Taken from https://github.com/GenSpectrum/cov-spectrum-website/blob/9372a618dfd2d0dc5106fb07dce4e9f02fe24471/src/components/VariantMutations.tsx#L484-L486
|
|
45
|
+
*
|
|
46
|
+
* @param variantCount The number of sequences of the variant
|
|
47
|
+
* @param mutationCount The number of sequences with the mutation
|
|
48
|
+
* @param variantWithMutationCount The number of sequences that belong to the variant and have the mutation
|
|
49
|
+
*/
|
|
50
|
+
const calculateJaccardSimilarity = (variantCount: number, mutationCount: number, variantWithMutationCount: number) => {
|
|
51
|
+
return variantWithMutationCount / (variantCount + mutationCount - variantWithMutationCount);
|
|
52
|
+
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type FunctionComponent } from 'preact';
|
|
2
|
+
import { useMemo } from 'preact/hooks';
|
|
2
3
|
|
|
3
4
|
import { getMutationsTableData } from './getMutationsTableData';
|
|
4
5
|
import { type SubstitutionOrDeletionEntry } from '../../types';
|
|
@@ -10,41 +11,60 @@ import { formatProportion } from '../shared/table/formatProportion';
|
|
|
10
11
|
|
|
11
12
|
export interface MutationsTableProps {
|
|
12
13
|
data: SubstitutionOrDeletionEntry[];
|
|
14
|
+
baselineSubstitutionsOrDeletions: SubstitutionOrDeletionEntry[] | undefined;
|
|
15
|
+
overallVariantCount: number;
|
|
13
16
|
proportionInterval: ProportionInterval;
|
|
14
17
|
pageSize: boolean | number;
|
|
15
18
|
}
|
|
16
19
|
|
|
17
|
-
const MutationsTable: FunctionComponent<MutationsTableProps> = ({
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
20
|
+
const MutationsTable: FunctionComponent<MutationsTableProps> = ({
|
|
21
|
+
data,
|
|
22
|
+
baselineSubstitutionsOrDeletions,
|
|
23
|
+
overallVariantCount,
|
|
24
|
+
proportionInterval,
|
|
25
|
+
pageSize,
|
|
26
|
+
}) => {
|
|
27
|
+
const headers = [
|
|
28
|
+
{
|
|
29
|
+
name: 'Mutation',
|
|
30
|
+
sort: {
|
|
31
|
+
compare: (a: SubstitutionClass | DeletionClass, b: SubstitutionClass | DeletionClass) => {
|
|
32
|
+
return sortSubstitutionsAndDeletions(a, b);
|
|
26
33
|
},
|
|
27
|
-
formatter: (cell: SubstitutionClass | DeletionClass) => cell.toString(),
|
|
28
34
|
},
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
35
|
+
formatter: (cell: SubstitutionClass | DeletionClass) => cell.toString(),
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
name: 'Type',
|
|
39
|
+
sort: true,
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
name: 'Count',
|
|
43
|
+
sort: true,
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
name: 'Proportion',
|
|
47
|
+
sort: true,
|
|
48
|
+
formatter: (cell: number) => formatProportion(cell),
|
|
49
|
+
},
|
|
50
|
+
];
|
|
51
|
+
if (baselineSubstitutionsOrDeletions !== undefined) {
|
|
52
|
+
headers.push({
|
|
53
|
+
name: 'Jaccard similarity',
|
|
54
|
+
sort: true,
|
|
55
|
+
formatter: (cell: number) => cell.toFixed(2),
|
|
56
|
+
});
|
|
57
|
+
}
|
|
44
58
|
|
|
45
|
-
const tableData =
|
|
59
|
+
const tableData = useMemo(
|
|
60
|
+
() =>
|
|
61
|
+
getMutationsTableData(data, baselineSubstitutionsOrDeletions, overallVariantCount, proportionInterval).map(
|
|
62
|
+
(row) => Object.values(row),
|
|
63
|
+
),
|
|
64
|
+
[data, baselineSubstitutionsOrDeletions, overallVariantCount, proportionInterval],
|
|
65
|
+
);
|
|
46
66
|
|
|
47
|
-
return <Table data={tableData} columns={
|
|
67
|
+
return <Table data={tableData} columns={headers} pageSize={pageSize} />;
|
|
48
68
|
};
|
|
49
69
|
|
|
50
70
|
export default MutationsTable;
|
|
@@ -4,8 +4,15 @@ import { expect, waitFor, within } from '@storybook/test';
|
|
|
4
4
|
import nucleotideInsertions from './__mockData__/nucleotideInsertions.json';
|
|
5
5
|
import nucleotideMutations from './__mockData__/nucleotideMutations.json';
|
|
6
6
|
import { Mutations, type MutationsProps } from './mutations';
|
|
7
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
AGGREGATED_ENDPOINT,
|
|
9
|
+
LAPIS_URL,
|
|
10
|
+
NUCLEOTIDE_INSERTIONS_ENDPOINT,
|
|
11
|
+
NUCLEOTIDE_MUTATIONS_ENDPOINT,
|
|
12
|
+
} from '../../constants';
|
|
8
13
|
import referenceGenome from '../../lapisApi/__mockData__/referenceGenome.json';
|
|
14
|
+
import baselineNucleotideMutations from '../../preact/mutations/__mockData__/baselineNucleotideMutations.json';
|
|
15
|
+
import overallVariantCount from '../../preact/mutations/__mockData__/overallVariantCount.json';
|
|
9
16
|
import { LapisUrlContext } from '../LapisUrlContext';
|
|
10
17
|
import { ReferenceGenomeContext } from '../ReferenceGenomeContext';
|
|
11
18
|
|
|
@@ -34,14 +41,7 @@ const Template = {
|
|
|
34
41
|
render: (args: MutationsProps) => (
|
|
35
42
|
<LapisUrlContext.Provider value={LAPIS_URL}>
|
|
36
43
|
<ReferenceGenomeContext.Provider value={referenceGenome}>
|
|
37
|
-
<Mutations
|
|
38
|
-
lapisFilter={args.lapisFilter}
|
|
39
|
-
sequenceType={args.sequenceType}
|
|
40
|
-
views={args.views}
|
|
41
|
-
width={args.width}
|
|
42
|
-
height={args.height}
|
|
43
|
-
pageSize={args.pageSize}
|
|
44
|
-
/>
|
|
44
|
+
<Mutations {...args} />
|
|
45
45
|
</ReferenceGenomeContext.Provider>
|
|
46
46
|
</LapisUrlContext.Provider>
|
|
47
47
|
),
|
|
@@ -51,6 +51,7 @@ export const Default: StoryObj<MutationsProps> = {
|
|
|
51
51
|
...Template,
|
|
52
52
|
args: {
|
|
53
53
|
lapisFilter: { country: 'Switzerland', pangoLineage: 'B.1.1.7', dateTo: '2022-01-01' },
|
|
54
|
+
baselineLapisFilter: { country: 'Switzerland', dateTo: '2022-01-01' },
|
|
54
55
|
sequenceType: 'nucleotide',
|
|
55
56
|
views: ['grid', 'table', 'insertions'],
|
|
56
57
|
width: '100%',
|
|
@@ -76,6 +77,37 @@ export const Default: StoryObj<MutationsProps> = {
|
|
|
76
77
|
body: nucleotideMutations,
|
|
77
78
|
},
|
|
78
79
|
},
|
|
80
|
+
{
|
|
81
|
+
matcher: {
|
|
82
|
+
name: 'baselineNucleotideMutations',
|
|
83
|
+
url: NUCLEOTIDE_MUTATIONS_ENDPOINT,
|
|
84
|
+
body: {
|
|
85
|
+
country: 'Switzerland',
|
|
86
|
+
dateTo: '2022-01-01',
|
|
87
|
+
minProportion: 0,
|
|
88
|
+
},
|
|
89
|
+
},
|
|
90
|
+
response: {
|
|
91
|
+
status: 200,
|
|
92
|
+
body: baselineNucleotideMutations,
|
|
93
|
+
},
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
matcher: {
|
|
97
|
+
name: 'overallVariantCount',
|
|
98
|
+
url: AGGREGATED_ENDPOINT,
|
|
99
|
+
body: {
|
|
100
|
+
country: 'Switzerland',
|
|
101
|
+
pangoLineage: 'B.1.1.7',
|
|
102
|
+
dateTo: '2022-01-01',
|
|
103
|
+
fields: [],
|
|
104
|
+
},
|
|
105
|
+
},
|
|
106
|
+
response: {
|
|
107
|
+
status: 200,
|
|
108
|
+
body: overallVariantCount,
|
|
109
|
+
},
|
|
110
|
+
},
|
|
79
111
|
{
|
|
80
112
|
matcher: {
|
|
81
113
|
name: 'nucleotideInsertions',
|
|
@@ -7,7 +7,7 @@ import { getMutationsTableData } from './getMutationsTableData';
|
|
|
7
7
|
import { MutationsGrid } from './mutations-grid';
|
|
8
8
|
import { InsertionsTable } from './mutations-insertions-table';
|
|
9
9
|
import MutationsTable from './mutations-table';
|
|
10
|
-
import { filterMutationsData, queryMutationsData } from './queryMutations';
|
|
10
|
+
import { filterMutationsData, type QueriedMutationsData, queryMutationsData } from './queryMutations';
|
|
11
11
|
import {
|
|
12
12
|
type InsertionEntry,
|
|
13
13
|
lapisFilterSchema,
|
|
@@ -35,6 +35,7 @@ export type MutationsView = z.infer<typeof mutationsViewSchema>;
|
|
|
35
35
|
|
|
36
36
|
const mutationsPropsSchema = z.object({
|
|
37
37
|
lapisFilter: lapisFilterSchema,
|
|
38
|
+
baselineLapisFilter: lapisFilterSchema.optional(),
|
|
38
39
|
sequenceType: sequenceTypeSchema,
|
|
39
40
|
views: mutationsViewSchema.array(),
|
|
40
41
|
pageSize: z.union([z.boolean(), z.number()]),
|
|
@@ -58,11 +59,11 @@ export const Mutations: FunctionComponent<MutationsProps> = (componentProps) =>
|
|
|
58
59
|
|
|
59
60
|
export const MutationsInner: FunctionComponent<MutationsProps> = (componentProps) => {
|
|
60
61
|
const lapis = useContext(LapisUrlContext);
|
|
61
|
-
const { lapisFilter, sequenceType } = componentProps;
|
|
62
|
+
const { lapisFilter, baselineLapisFilter, sequenceType } = componentProps;
|
|
62
63
|
|
|
63
64
|
const { data, error, isLoading } = useQuery(async () => {
|
|
64
|
-
return queryMutationsData(lapisFilter, sequenceType, lapis);
|
|
65
|
-
}, [lapisFilter, sequenceType, lapis]);
|
|
65
|
+
return queryMutationsData(lapisFilter, baselineLapisFilter, sequenceType, lapis);
|
|
66
|
+
}, [lapisFilter, baselineLapisFilter, sequenceType, lapis]);
|
|
66
67
|
|
|
67
68
|
if (isLoading) {
|
|
68
69
|
return <LoadingDisplay />;
|
|
@@ -80,7 +81,7 @@ export const MutationsInner: FunctionComponent<MutationsProps> = (componentProps
|
|
|
80
81
|
};
|
|
81
82
|
|
|
82
83
|
type MutationTabsProps = {
|
|
83
|
-
mutationsData:
|
|
84
|
+
mutationsData: QueriedMutationsData;
|
|
84
85
|
originalComponentProps: MutationsProps;
|
|
85
86
|
};
|
|
86
87
|
|
|
@@ -103,6 +104,8 @@ const MutationsTabs: FunctionComponent<MutationTabsProps> = ({ mutationsData, or
|
|
|
103
104
|
content: (
|
|
104
105
|
<MutationsTable
|
|
105
106
|
data={filteredData.tableData}
|
|
107
|
+
baselineSubstitutionsOrDeletions={mutationsData.baselineSubstitutionsOrDeletions}
|
|
108
|
+
overallVariantCount={mutationsData.overallVariantCount}
|
|
106
109
|
proportionInterval={proportionInterval}
|
|
107
110
|
pageSize={originalComponentProps.pageSize}
|
|
108
111
|
/>
|
|
@@ -143,6 +146,8 @@ const MutationsTabs: FunctionComponent<MutationTabsProps> = ({ mutationsData, or
|
|
|
143
146
|
proportionInterval={proportionInterval}
|
|
144
147
|
setProportionInterval={setProportionInterval}
|
|
145
148
|
originalComponentProps={originalComponentProps}
|
|
149
|
+
baselineSubstitutionsOrDeletions={mutationsData.baselineSubstitutionsOrDeletions}
|
|
150
|
+
overallVariantCount={mutationsData.overallVariantCount}
|
|
146
151
|
/>
|
|
147
152
|
);
|
|
148
153
|
|
|
@@ -159,6 +164,8 @@ type ToolbarProps = {
|
|
|
159
164
|
proportionInterval: ProportionInterval;
|
|
160
165
|
setProportionInterval: Dispatch<StateUpdater<ProportionInterval>>;
|
|
161
166
|
originalComponentProps: MutationsProps;
|
|
167
|
+
baselineSubstitutionsOrDeletions: SubstitutionOrDeletionEntry[] | undefined;
|
|
168
|
+
overallVariantCount: number;
|
|
162
169
|
};
|
|
163
170
|
|
|
164
171
|
const Toolbar: FunctionComponent<ToolbarProps> = ({
|
|
@@ -171,6 +178,8 @@ const Toolbar: FunctionComponent<ToolbarProps> = ({
|
|
|
171
178
|
proportionInterval,
|
|
172
179
|
setProportionInterval,
|
|
173
180
|
originalComponentProps,
|
|
181
|
+
baselineSubstitutionsOrDeletions,
|
|
182
|
+
overallVariantCount,
|
|
174
183
|
}) => {
|
|
175
184
|
return (
|
|
176
185
|
<>
|
|
@@ -190,7 +199,14 @@ const Toolbar: FunctionComponent<ToolbarProps> = ({
|
|
|
190
199
|
/>
|
|
191
200
|
<CsvDownloadButton
|
|
192
201
|
className='mx-1 btn btn-xs'
|
|
193
|
-
getData={() =>
|
|
202
|
+
getData={() =>
|
|
203
|
+
getMutationsTableData(
|
|
204
|
+
filteredData.tableData,
|
|
205
|
+
baselineSubstitutionsOrDeletions,
|
|
206
|
+
overallVariantCount,
|
|
207
|
+
proportionInterval,
|
|
208
|
+
)
|
|
209
|
+
}
|
|
194
210
|
filename='substitutions_and_deletions.csv'
|
|
195
211
|
/>
|
|
196
212
|
</>
|
|
@@ -1,30 +1,49 @@
|
|
|
1
|
+
import { FetchAggregatedOperator } from '../../operator/FetchAggregatedOperator';
|
|
1
2
|
import { queryInsertions } from '../../query/queryInsertions';
|
|
2
3
|
import { querySubstitutionsOrDeletions } from '../../query/querySubstitutionsOrDeletions';
|
|
3
|
-
import {
|
|
4
|
-
type InsertionEntry,
|
|
5
|
-
type LapisFilter,
|
|
6
|
-
type MutationEntry,
|
|
7
|
-
type SubstitutionOrDeletionEntry,
|
|
8
|
-
} from '../../types';
|
|
4
|
+
import type { InsertionEntry, LapisFilter, MutationEntry, SubstitutionOrDeletionEntry } from '../../types';
|
|
9
5
|
import { type DisplayedMutationType } from '../components/mutation-type-selector';
|
|
10
6
|
import { type DisplayedSegment } from '../components/segment-selector';
|
|
11
7
|
|
|
8
|
+
export type QueriedMutationsData = {
|
|
9
|
+
insertions: InsertionEntry[];
|
|
10
|
+
substitutionsOrDeletions: SubstitutionOrDeletionEntry[];
|
|
11
|
+
baselineSubstitutionsOrDeletions: SubstitutionOrDeletionEntry[] | undefined;
|
|
12
|
+
overallVariantCount: number;
|
|
13
|
+
};
|
|
14
|
+
|
|
12
15
|
export async function queryMutationsData(
|
|
13
16
|
lapisFilter: LapisFilter,
|
|
17
|
+
baselineLapisFilter: LapisFilter | undefined,
|
|
14
18
|
sequenceType: 'nucleotide' | 'amino acid',
|
|
15
19
|
lapis: string,
|
|
16
|
-
) {
|
|
20
|
+
): Promise<QueriedMutationsData> {
|
|
17
21
|
const substitutionsOrDeletions = (await querySubstitutionsOrDeletions(lapisFilter, sequenceType, lapis)).content;
|
|
22
|
+
const baselineSubstitutionsOrDeletions =
|
|
23
|
+
baselineLapisFilter === undefined
|
|
24
|
+
? undefined
|
|
25
|
+
: (await querySubstitutionsOrDeletions(baselineLapisFilter, sequenceType, lapis)).content;
|
|
18
26
|
const insertions = (await queryInsertions(lapisFilter, sequenceType, lapis)).content;
|
|
19
27
|
|
|
28
|
+
const aggregatedData = await new FetchAggregatedOperator<Record<string, string | null | number>>(
|
|
29
|
+
lapisFilter,
|
|
30
|
+
[],
|
|
31
|
+
).evaluate(lapis);
|
|
32
|
+
if (aggregatedData.content.length === 0) {
|
|
33
|
+
throw new Error('No aggregated data found for the given filters - did LAPIS respond properly?');
|
|
34
|
+
}
|
|
35
|
+
const overallVariantCount = aggregatedData.content[0].count;
|
|
36
|
+
|
|
20
37
|
return {
|
|
21
38
|
substitutionsOrDeletions,
|
|
39
|
+
baselineSubstitutionsOrDeletions,
|
|
22
40
|
insertions,
|
|
41
|
+
overallVariantCount,
|
|
23
42
|
};
|
|
24
43
|
}
|
|
25
44
|
|
|
26
45
|
export function filterMutationsData(
|
|
27
|
-
data:
|
|
46
|
+
data: QueriedMutationsData,
|
|
28
47
|
displayedSegments: DisplayedSegment[],
|
|
29
48
|
displayedMutationTypes: DisplayedMutationType[],
|
|
30
49
|
) {
|
|
@@ -51,5 +70,6 @@ export function filterMutationsData(
|
|
|
51
70
|
insertions: data.insertions.filter(bySelectedSegments),
|
|
52
71
|
tableData: filteredSubstitutionsOrDeletions.filter(byDisplayedMutationTypes),
|
|
53
72
|
gridData: filteredSubstitutionsOrDeletions,
|
|
73
|
+
baselineSubstitutionsOrDeletions: data.baselineSubstitutionsOrDeletions,
|
|
54
74
|
};
|
|
55
75
|
}
|