@genspectrum/dashboard-components 1.16.0 → 1.17.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 +3 -3
- package/dist/components.d.ts +4 -4
- package/dist/components.js +449 -246
- package/dist/components.js.map +1 -1
- package/dist/util.d.ts +6 -6
- package/package.json +1 -1
- package/src/preact/MutationAnnotationsContext.tsx +1 -1
- package/src/preact/components/csv-download-button.tsx +22 -14
- package/src/preact/components/features-over-time-grid.tsx +189 -43
- package/src/preact/components/mutations-over-time-mutations-filter.stories.tsx +1 -1
- package/src/preact/components/mutations-over-time-mutations-filter.tsx +1 -1
- package/src/preact/mutationsOverTime/__mockData__/aminoAcidMutationsByDay/aminoAcidMutationsOverTimePage1.json +52 -0
- package/src/preact/mutationsOverTime/__mockData__/byWeek/mutationsOverTimePage1.json +76 -0
- package/src/preact/mutationsOverTime/__mockData__/defaultMockData/mockDefaultMutationsOverTimeWithFilter.json +43 -0
- package/src/preact/mutationsOverTime/__mockData__/defaultMockData/mutationsOverTimePage1.json +126 -0
- package/src/preact/mutationsOverTime/__mockData__/defaultMockData/mutationsOverTimePage2.json +116 -0
- package/src/preact/mutationsOverTime/__mockData__/defaultMockData/mutationsOverTimePageSize20.json +216 -0
- package/src/preact/mutationsOverTime/getFilteredMutationCodes.spec.ts +236 -0
- package/src/preact/mutationsOverTime/{getFilteredMutationsOverTimeData.ts → getFilteredMutationCodes.ts} +29 -44
- package/src/preact/mutationsOverTime/mutations-over-time.stories.tsx +128 -23
- package/src/preact/mutationsOverTime/mutations-over-time.tsx +139 -74
- package/src/preact/mutationsOverTime/useMutationsOverTimePageData.ts +111 -0
- package/src/preact/shared/tanstackTable/pagination-context.tsx +5 -2
- package/src/preact/shared/tanstackTable/pagination.tsx +11 -9
- package/src/preact/shared/tanstackTable/tanstackTable.tsx +7 -4
- package/src/preact/wastewater/mutationsOverTime/wastewater-mutations-over-time.tsx +1 -1
- package/src/query/queryMutationsOverTime.spec.ts +187 -662
- package/src/query/queryMutationsOverTime.ts +46 -33
- package/src/utils/useControlledState.ts +15 -0
- package/src/web-components/visualization/gs-mutations-over-time.stories.ts +78 -22
- package/standalone-bundle/dashboard-components.js +6872 -6690
- package/standalone-bundle/dashboard-components.js.map +1 -1
- package/src/preact/mutationsOverTime/__mockData__/aminoAcidMutationsByDay/aminoAcidMutationsOverTime.json +0 -5496
- package/src/preact/mutationsOverTime/__mockData__/byWeek/mutationsOverTime.json +0 -7100
- package/src/preact/mutationsOverTime/__mockData__/defaultMockData/mutationsOverTime.json +0 -12646
- package/src/preact/mutationsOverTime/getFilteredMutationsOverTime.spec.ts +0 -417
package/dist/util.d.ts
CHANGED
|
@@ -848,11 +848,11 @@ declare const queriesOverTimeSchema: default_2.ZodObject<{
|
|
|
848
848
|
max: number;
|
|
849
849
|
};
|
|
850
850
|
height?: string | undefined;
|
|
851
|
-
hideGaps?: boolean | undefined;
|
|
852
851
|
customColumns?: {
|
|
853
852
|
values: Record<string, string | number>;
|
|
854
853
|
header: string;
|
|
855
854
|
}[] | undefined;
|
|
855
|
+
hideGaps?: boolean | undefined;
|
|
856
856
|
}, {
|
|
857
857
|
lapisFilter: Record<string, string | number | boolean | string[] | null | undefined> & {
|
|
858
858
|
nucleotideMutations?: string[] | undefined;
|
|
@@ -876,11 +876,11 @@ declare const queriesOverTimeSchema: default_2.ZodObject<{
|
|
|
876
876
|
max: number;
|
|
877
877
|
};
|
|
878
878
|
height?: string | undefined;
|
|
879
|
-
hideGaps?: boolean | undefined;
|
|
880
879
|
customColumns?: {
|
|
881
880
|
values: Record<string, string | number>;
|
|
882
881
|
header: string;
|
|
883
882
|
}[] | undefined;
|
|
883
|
+
hideGaps?: boolean | undefined;
|
|
884
884
|
}>;
|
|
885
885
|
|
|
886
886
|
export declare type QueriesOverTimeView = default_2.infer<typeof queriesOverTimeViewSchema>;
|
|
@@ -1188,7 +1188,7 @@ declare global {
|
|
|
1188
1188
|
|
|
1189
1189
|
declare global {
|
|
1190
1190
|
interface HTMLElementTagNameMap {
|
|
1191
|
-
'gs-
|
|
1191
|
+
'gs-aggregate': AggregateComponent;
|
|
1192
1192
|
}
|
|
1193
1193
|
}
|
|
1194
1194
|
|
|
@@ -1196,7 +1196,7 @@ declare global {
|
|
|
1196
1196
|
declare global {
|
|
1197
1197
|
namespace React.JSX {
|
|
1198
1198
|
interface IntrinsicElements {
|
|
1199
|
-
'gs-
|
|
1199
|
+
'gs-aggregate': AggregateComponent;
|
|
1200
1200
|
}
|
|
1201
1201
|
}
|
|
1202
1202
|
}
|
|
@@ -1204,7 +1204,7 @@ declare global {
|
|
|
1204
1204
|
|
|
1205
1205
|
declare global {
|
|
1206
1206
|
interface HTMLElementTagNameMap {
|
|
1207
|
-
'gs-
|
|
1207
|
+
'gs-number-sequences-over-time': NumberSequencesOverTimeComponent;
|
|
1208
1208
|
}
|
|
1209
1209
|
}
|
|
1210
1210
|
|
|
@@ -1212,7 +1212,7 @@ declare global {
|
|
|
1212
1212
|
declare global {
|
|
1213
1213
|
namespace React.JSX {
|
|
1214
1214
|
interface IntrinsicElements {
|
|
1215
|
-
'gs-
|
|
1215
|
+
'gs-number-sequences-over-time': NumberSequencesOverTimeComponent;
|
|
1216
1216
|
}
|
|
1217
1217
|
}
|
|
1218
1218
|
}
|
package/package.json
CHANGED
|
@@ -98,7 +98,7 @@ export function useRawMutationAnnotations() {
|
|
|
98
98
|
export function useMutationAnnotationsProvider() {
|
|
99
99
|
const mutationAnnotations = useContext(MutationAnnotationsContext);
|
|
100
100
|
|
|
101
|
-
return getMutationAnnotationsProvider(mutationAnnotations);
|
|
101
|
+
return useMemo(() => getMutationAnnotationsProvider(mutationAnnotations), [mutationAnnotations]);
|
|
102
102
|
}
|
|
103
103
|
|
|
104
104
|
export function getMutationAnnotationsProvider(mutationAnnotations: MutationAnnotationsContextValue) {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type FunctionComponent } from 'preact';
|
|
2
|
+
import { useState } from 'preact/hooks';
|
|
2
3
|
|
|
3
4
|
type ToStringable = {
|
|
4
5
|
toString: () => string;
|
|
@@ -9,7 +10,7 @@ export type DataValue = string | number | boolean | null | undefined | ToStringa
|
|
|
9
10
|
export interface CsvDownloadButtonProps {
|
|
10
11
|
label?: string;
|
|
11
12
|
filename?: string;
|
|
12
|
-
getData: () => Record<string, DataValue>[]
|
|
13
|
+
getData: () => Record<string, DataValue>[] | Promise<Record<string, DataValue>[]>;
|
|
13
14
|
className?: string;
|
|
14
15
|
}
|
|
15
16
|
|
|
@@ -19,19 +20,26 @@ export const CsvDownloadButton: FunctionComponent<CsvDownloadButtonProps> = ({
|
|
|
19
20
|
getData,
|
|
20
21
|
className,
|
|
21
22
|
}) => {
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
23
|
+
const [isDownloading, setIsDownloading] = useState(false);
|
|
24
|
+
|
|
25
|
+
const download = async () => {
|
|
26
|
+
setIsDownloading(true);
|
|
27
|
+
try {
|
|
28
|
+
const content = await getDownloadContent();
|
|
29
|
+
const blob = new Blob([content], { type: 'text/csv' });
|
|
30
|
+
const url = URL.createObjectURL(blob);
|
|
31
|
+
const a = document.createElement('a');
|
|
32
|
+
a.href = url;
|
|
33
|
+
a.download = filename;
|
|
34
|
+
a.click();
|
|
35
|
+
URL.revokeObjectURL(url);
|
|
36
|
+
} finally {
|
|
37
|
+
setIsDownloading(false);
|
|
38
|
+
}
|
|
31
39
|
};
|
|
32
40
|
|
|
33
|
-
const getDownloadContent = () => {
|
|
34
|
-
const data = getData();
|
|
41
|
+
const getDownloadContent = async () => {
|
|
42
|
+
const data = await getData();
|
|
35
43
|
const keys = getDataKeys(data);
|
|
36
44
|
const header = keys.join(',');
|
|
37
45
|
const rows = data.map((row) => keys.map((key) => row[key]).join(',')).join('\n');
|
|
@@ -50,8 +58,8 @@ export const CsvDownloadButton: FunctionComponent<CsvDownloadButtonProps> = ({
|
|
|
50
58
|
};
|
|
51
59
|
|
|
52
60
|
return (
|
|
53
|
-
<button className={className} onClick={download}>
|
|
54
|
-
{label}
|
|
61
|
+
<button className={className} onClick={() => void download()} disabled={isDownloading}>
|
|
62
|
+
{isDownloading ? 'Downloading...' : label}
|
|
55
63
|
</button>
|
|
56
64
|
);
|
|
57
65
|
};
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
import { createColumnHelper, getCoreRowModel, getPaginationRowModel } from '@tanstack/table-core';
|
|
2
|
+
import type { Table } from '@tanstack/table-core';
|
|
1
3
|
import { type FunctionComponent, type JSX } from 'preact';
|
|
2
|
-
import { useMemo } from 'preact/hooks';
|
|
4
|
+
import { type Dispatch, type StateUpdater, useMemo } from 'preact/hooks';
|
|
3
5
|
import z from 'zod';
|
|
4
6
|
|
|
5
7
|
import { type ColorScale, getColorWithinScale, getTextColorForScale } from './color-scale-selector';
|
|
@@ -11,13 +13,7 @@ import { type TemporalDataMap } from '../mutationsOverTime/MutationOverTimeData'
|
|
|
11
13
|
import { formatProportion } from '../shared/table/formatProportion';
|
|
12
14
|
import { type PageSizes, Pagination } from '../shared/tanstackTable/pagination';
|
|
13
15
|
import { usePageSizeContext } from '../shared/tanstackTable/pagination-context';
|
|
14
|
-
import {
|
|
15
|
-
createColumnHelper,
|
|
16
|
-
flexRender,
|
|
17
|
-
getCoreRowModel,
|
|
18
|
-
getPaginationRowModel,
|
|
19
|
-
usePreactTable,
|
|
20
|
-
} from '../shared/tanstackTable/tanstackTable';
|
|
16
|
+
import { flexRender, usePreactTable } from '../shared/tanstackTable/tanstackTable';
|
|
21
17
|
|
|
22
18
|
const NON_BREAKING_SPACE = '\u00A0';
|
|
23
19
|
|
|
@@ -60,18 +56,118 @@ function FeaturesOverTimeGrid<F>({
|
|
|
60
56
|
featureRenderer,
|
|
61
57
|
tooltipPortalTarget,
|
|
62
58
|
}: FeaturesOverTimeGridProps<F>) {
|
|
63
|
-
const tableData =
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
59
|
+
const tableData = useGridTableData(data, customColumns, featureRenderer);
|
|
60
|
+
const columns = useGridColumns(
|
|
61
|
+
data.getSecondAxisKeys(),
|
|
62
|
+
rowLabelHeader,
|
|
63
|
+
customColumns,
|
|
64
|
+
colorScale,
|
|
65
|
+
tooltipPortalTarget,
|
|
66
|
+
featureRenderer,
|
|
67
|
+
);
|
|
68
|
+
const { pageSize } = usePageSizeContext();
|
|
69
|
+
|
|
70
|
+
const table = usePreactTable({
|
|
71
|
+
data: tableData,
|
|
72
|
+
columns,
|
|
73
|
+
getCoreRowModel: getCoreRowModel(),
|
|
74
|
+
getPaginationRowModel: getPaginationRowModel(),
|
|
75
|
+
initialState: {
|
|
76
|
+
pagination: { pageIndex: 0, pageSize },
|
|
77
|
+
},
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
return <FeaturesOverTimeGridDisplay table={table} pageSizes={pageSizes} />;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export interface FeaturesOverTimeGridServerPaginatedProps<F> {
|
|
84
|
+
rowLabelHeader: string;
|
|
85
|
+
data: TemporalDataMap<F> | null;
|
|
86
|
+
isLoading: boolean;
|
|
87
|
+
/** Labels to show in the row label column while the page data is loading. */
|
|
88
|
+
loadingRowLabels: string[];
|
|
89
|
+
/** Date columns to show in the header while loading */
|
|
90
|
+
requestedDateRanges: Temporal[];
|
|
91
|
+
colorScale: ColorScale;
|
|
92
|
+
pageSizes: PageSizes;
|
|
93
|
+
/** Controlled page index (0-based). */
|
|
94
|
+
pageIndex: number;
|
|
95
|
+
/** Total number of rows across all pages. */
|
|
96
|
+
totalRows: number;
|
|
97
|
+
onPageChange: Dispatch<StateUpdater<number>>;
|
|
98
|
+
customColumns?: CustomColumn[];
|
|
99
|
+
featureRenderer: FeatureRenderer<F>;
|
|
100
|
+
tooltipPortalTarget: HTMLElement | null;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export function FeaturesOverTimeGridServerPaginated<F>({
|
|
104
|
+
rowLabelHeader,
|
|
105
|
+
data,
|
|
106
|
+
isLoading,
|
|
107
|
+
loadingRowLabels,
|
|
108
|
+
requestedDateRanges,
|
|
109
|
+
colorScale,
|
|
110
|
+
pageSizes,
|
|
111
|
+
pageIndex,
|
|
112
|
+
totalRows,
|
|
113
|
+
onPageChange,
|
|
114
|
+
customColumns = EMPTY_COLUMNS,
|
|
115
|
+
featureRenderer,
|
|
116
|
+
tooltipPortalTarget,
|
|
117
|
+
}: FeaturesOverTimeGridServerPaginatedProps<F>) {
|
|
118
|
+
const tableData = useGridTableData(data, customColumns, featureRenderer);
|
|
119
|
+
const columns = useGridColumns(
|
|
120
|
+
data?.getSecondAxisKeys() ?? requestedDateRanges,
|
|
121
|
+
rowLabelHeader,
|
|
122
|
+
customColumns,
|
|
123
|
+
colorScale,
|
|
124
|
+
tooltipPortalTarget,
|
|
125
|
+
featureRenderer,
|
|
126
|
+
);
|
|
127
|
+
const { pageSize, setPageSize } = usePageSizeContext();
|
|
128
|
+
|
|
129
|
+
const table = usePreactTable({
|
|
130
|
+
data: tableData,
|
|
131
|
+
columns,
|
|
132
|
+
getCoreRowModel: getCoreRowModel(),
|
|
133
|
+
// getPaginationRowModel not needed with manualPagination: true
|
|
134
|
+
manualPagination: true,
|
|
135
|
+
pageCount: Math.ceil(totalRows / pageSize),
|
|
136
|
+
state: {
|
|
137
|
+
pagination: { pageIndex, pageSize },
|
|
138
|
+
},
|
|
139
|
+
onPaginationChange: (updater) => {
|
|
140
|
+
const current = { pageIndex, pageSize };
|
|
141
|
+
const next = typeof updater === 'function' ? updater(current) : updater;
|
|
142
|
+
if (next.pageIndex !== current.pageIndex) {
|
|
143
|
+
onPageChange(next.pageIndex);
|
|
144
|
+
}
|
|
145
|
+
if (next.pageSize !== current.pageSize) {
|
|
146
|
+
setPageSize(next.pageSize);
|
|
147
|
+
}
|
|
148
|
+
},
|
|
149
|
+
});
|
|
71
150
|
|
|
72
|
-
|
|
151
|
+
return (
|
|
152
|
+
<FeaturesOverTimeGridDisplay
|
|
153
|
+
table={table}
|
|
154
|
+
pageSizes={pageSizes}
|
|
155
|
+
loadingState={{ isLoading, loadingRowLabels }}
|
|
156
|
+
totalRows={totalRows}
|
|
157
|
+
/>
|
|
158
|
+
);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
function useGridColumns<F>(
|
|
162
|
+
dates: Temporal[],
|
|
163
|
+
rowLabelHeader: string,
|
|
164
|
+
customColumns: CustomColumn[],
|
|
165
|
+
colorScale: ColorScale,
|
|
166
|
+
tooltipPortalTarget: HTMLElement | null,
|
|
167
|
+
featureRenderer: FeatureRenderer<F>,
|
|
168
|
+
) {
|
|
169
|
+
return useMemo(() => {
|
|
73
170
|
const columnHelper = createColumnHelper<RowType<F>>();
|
|
74
|
-
const dates = data.getSecondAxisKeys();
|
|
75
171
|
|
|
76
172
|
const featureHeader = columnHelper.accessor((row) => row.feature, {
|
|
77
173
|
id: 'feature',
|
|
@@ -137,21 +233,48 @@ function FeaturesOverTimeGrid<F>({
|
|
|
137
233
|
});
|
|
138
234
|
|
|
139
235
|
return [featureHeader, ...customColumnHeaders, ...dateHeaders];
|
|
140
|
-
}, [colorScale,
|
|
236
|
+
}, [colorScale, dates, customColumns, tooltipPortalTarget, featureRenderer, rowLabelHeader]);
|
|
237
|
+
}
|
|
141
238
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
239
|
+
function useGridTableData<F>(
|
|
240
|
+
data: TemporalDataMap<F> | null | undefined,
|
|
241
|
+
customColumns: CustomColumn[],
|
|
242
|
+
featureRenderer: FeatureRenderer<F>,
|
|
243
|
+
) {
|
|
244
|
+
return useMemo(() => {
|
|
245
|
+
if (!data) {
|
|
246
|
+
return [];
|
|
247
|
+
}
|
|
248
|
+
const firstAxisKeys = data.getFirstAxisKeys();
|
|
249
|
+
return data.getAsArray().map((row, index): RowType<F> => {
|
|
250
|
+
const firstAxisKey = firstAxisKeys[index];
|
|
251
|
+
const customValues = customColumns.map((col) => col.values[featureRenderer.asString(firstAxisKey)]);
|
|
252
|
+
return { feature: firstAxisKey, values: [...row], customValues };
|
|
253
|
+
});
|
|
254
|
+
}, [data, customColumns, featureRenderer]);
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
type FeaturesOverTimeGridDisplayProps<F> = {
|
|
258
|
+
table: Table<RowType<F>>;
|
|
259
|
+
pageSizes: PageSizes;
|
|
260
|
+
/** Override for the pagination row count (server-driven pagination). */
|
|
261
|
+
totalRows?: number;
|
|
262
|
+
loadingState?:
|
|
263
|
+
| {
|
|
264
|
+
isLoading: boolean;
|
|
265
|
+
/** Labels to render in the row label column while loading. One skeleton row is shown per label. */
|
|
266
|
+
loadingRowLabels: string[];
|
|
267
|
+
}
|
|
268
|
+
| { isLoading: false; loadingRowLabels?: never };
|
|
269
|
+
};
|
|
270
|
+
|
|
271
|
+
function FeaturesOverTimeGridDisplay<F>({
|
|
272
|
+
table,
|
|
273
|
+
pageSizes,
|
|
274
|
+
loadingState,
|
|
275
|
+
totalRows,
|
|
276
|
+
}: FeaturesOverTimeGridDisplayProps<F>) {
|
|
277
|
+
const displayedTotalRows = totalRows ?? table.getCoreRowModel().rows.length;
|
|
155
278
|
|
|
156
279
|
return (
|
|
157
280
|
<div className='w-full'>
|
|
@@ -170,22 +293,45 @@ function FeaturesOverTimeGrid<F>({
|
|
|
170
293
|
))}
|
|
171
294
|
</thead>
|
|
172
295
|
<tbody>
|
|
173
|
-
{
|
|
174
|
-
|
|
175
|
-
{
|
|
176
|
-
<td
|
|
296
|
+
{loadingState?.isLoading ? (
|
|
297
|
+
loadingState.loadingRowLabels.map((label, rowIndex) => (
|
|
298
|
+
<tr key={label}>
|
|
299
|
+
<td className='text-center'>{label}</td>
|
|
300
|
+
{rowIndex === 0 && (
|
|
301
|
+
<td
|
|
302
|
+
rowSpan={loadingState.loadingRowLabels.length}
|
|
303
|
+
colSpan={table.getFlatHeaders().length - 1}
|
|
304
|
+
className='text-center'
|
|
305
|
+
>
|
|
306
|
+
<span className='loading loading-spinner loading-sm' />
|
|
307
|
+
</td>
|
|
308
|
+
)}
|
|
309
|
+
</tr>
|
|
310
|
+
))
|
|
311
|
+
) : (
|
|
312
|
+
<>
|
|
313
|
+
{table.getRowModel().rows.map((row) => (
|
|
314
|
+
<tr key={row.id}>
|
|
315
|
+
{row.getVisibleCells().map((cell) => (
|
|
316
|
+
<td key={cell.id}>
|
|
317
|
+
{flexRender(cell.column.columnDef.cell, cell.getContext())}
|
|
318
|
+
</td>
|
|
319
|
+
))}
|
|
320
|
+
</tr>
|
|
177
321
|
))}
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
322
|
+
{table.getRowModel().rows.length === 0 && (
|
|
323
|
+
<tr>
|
|
324
|
+
<td colSpan={table.getFlatHeaders().length}>
|
|
325
|
+
<div className={'text-center'}>No data available for your filters.</div>
|
|
326
|
+
</td>
|
|
327
|
+
</tr>
|
|
328
|
+
)}
|
|
329
|
+
</>
|
|
184
330
|
)}
|
|
185
331
|
</tbody>
|
|
186
332
|
</table>
|
|
187
333
|
<div className={'mt-2'}>
|
|
188
|
-
<Pagination table={table} pageSizes={pageSizes} />
|
|
334
|
+
<Pagination table={table} pageSizes={pageSizes} totalRows={displayedTotalRows} />
|
|
189
335
|
</div>
|
|
190
336
|
</div>
|
|
191
337
|
);
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
} from './mutations-over-time-mutations-filter';
|
|
10
10
|
import { type MutationAnnotations } from '../../web-components/mutation-annotations-context';
|
|
11
11
|
import { MutationAnnotationsContextProvider } from '../MutationAnnotationsContext';
|
|
12
|
-
import { type MutationFilter } from '../mutationsOverTime/
|
|
12
|
+
import { type MutationFilter } from '../mutationsOverTime/getFilteredMutationCodes';
|
|
13
13
|
|
|
14
14
|
const meta: Meta = {
|
|
15
15
|
title: 'Component/Mutations over time mutations filter',
|
|
@@ -3,7 +3,7 @@ import { type Dispatch, type StateUpdater, useCallback, useEffect, useState } fr
|
|
|
3
3
|
|
|
4
4
|
import { Dropdown } from './dropdown';
|
|
5
5
|
import { useRawMutationAnnotations } from '../MutationAnnotationsContext';
|
|
6
|
-
import { type MutationFilter } from '../mutationsOverTime/
|
|
6
|
+
import { type MutationFilter } from '../mutationsOverTime/getFilteredMutationCodes';
|
|
7
7
|
import { DeleteIcon } from '../shared/icons/DeleteIcon';
|
|
8
8
|
|
|
9
9
|
export type MutationsOverTimeMutationsFilterProps = {
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
{
|
|
2
|
+
"data": {
|
|
3
|
+
"mutations": ["ORF1a:T170I", "ORF1a:F499L", "S:T572I"],
|
|
4
|
+
"dateRanges": [
|
|
5
|
+
{ "dateFrom": "2024-01-20", "dateTo": "2024-01-20" },
|
|
6
|
+
{ "dateFrom": "2024-01-21", "dateTo": "2024-01-21" },
|
|
7
|
+
{ "dateFrom": "2024-01-22", "dateTo": "2024-01-22" },
|
|
8
|
+
{ "dateFrom": "2024-01-23", "dateTo": "2024-01-23" },
|
|
9
|
+
{ "dateFrom": "2024-01-24", "dateTo": "2024-01-24" },
|
|
10
|
+
{ "dateFrom": "2024-01-25", "dateTo": "2024-01-25" },
|
|
11
|
+
{ "dateFrom": "2024-01-26", "dateTo": "2024-01-26" }
|
|
12
|
+
],
|
|
13
|
+
"data": [
|
|
14
|
+
[
|
|
15
|
+
{ "count": 121, "coverage": 455 },
|
|
16
|
+
{ "count": 155, "coverage": 535 },
|
|
17
|
+
{ "count": 314, "coverage": 1100 },
|
|
18
|
+
{ "count": 245, "coverage": 1032 },
|
|
19
|
+
{ "count": 225, "coverage": 968 },
|
|
20
|
+
{ "count": 197, "coverage": 839 },
|
|
21
|
+
{ "count": 171, "coverage": 635 }
|
|
22
|
+
],
|
|
23
|
+
[
|
|
24
|
+
{ "count": 20, "coverage": 459 },
|
|
25
|
+
{ "count": 33, "coverage": 536 },
|
|
26
|
+
{ "count": 79, "coverage": 1149 },
|
|
27
|
+
{ "count": 71, "coverage": 1061 },
|
|
28
|
+
{ "count": 66, "coverage": 995 },
|
|
29
|
+
{ "count": 49, "coverage": 857 },
|
|
30
|
+
{ "count": 42, "coverage": 668 }
|
|
31
|
+
],
|
|
32
|
+
[
|
|
33
|
+
{ "count": 26, "coverage": 456 },
|
|
34
|
+
{ "count": 37, "coverage": 541 },
|
|
35
|
+
{ "count": 83, "coverage": 1141 },
|
|
36
|
+
{ "count": 81, "coverage": 1051 },
|
|
37
|
+
{ "count": 70, "coverage": 986 },
|
|
38
|
+
{ "count": 64, "coverage": 848 },
|
|
39
|
+
{ "count": 48, "coverage": 664 }
|
|
40
|
+
]
|
|
41
|
+
],
|
|
42
|
+
"totalCountsByDateRange": [466, 548, 1155, 1067, 1007, 865, 671]
|
|
43
|
+
},
|
|
44
|
+
"info": {
|
|
45
|
+
"dataVersion": "1774200829",
|
|
46
|
+
"requestId": "74b55554-9ee9-4776-ba5f-48b93782ed51",
|
|
47
|
+
"requestInfo": "sars_cov-2_nextstrain_open on lapis.cov-spectrum.org at 2026-03-24T08:59:15.215671655",
|
|
48
|
+
"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.",
|
|
49
|
+
"lapisVersion": "0.7.0",
|
|
50
|
+
"siloVersion": "0.10.0"
|
|
51
|
+
}
|
|
52
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
{
|
|
2
|
+
"data": {
|
|
3
|
+
"mutations": ["C44T", "C774T", "C1762A", "C11747T", "G17562T", "T18453C", "G21641T", "C23277T", "C29870A"],
|
|
4
|
+
"dateRanges": [
|
|
5
|
+
{ "dateFrom": "2024-01-15", "dateTo": "2024-01-21" },
|
|
6
|
+
{ "dateFrom": "2024-01-22", "dateTo": "2024-01-28" },
|
|
7
|
+
{ "dateFrom": "2024-01-29", "dateTo": "2024-02-04" },
|
|
8
|
+
{ "dateFrom": "2024-02-05", "dateTo": "2024-02-11" }
|
|
9
|
+
],
|
|
10
|
+
"data": [
|
|
11
|
+
[
|
|
12
|
+
{ "count": 548, "coverage": 923 },
|
|
13
|
+
{ "count": 605, "coverage": 1040 },
|
|
14
|
+
{ "count": 571, "coverage": 916 },
|
|
15
|
+
{ "count": 481, "coverage": 858 }
|
|
16
|
+
],
|
|
17
|
+
[
|
|
18
|
+
{ "count": 1404, "coverage": 5260 },
|
|
19
|
+
{ "count": 1358, "coverage": 5415 },
|
|
20
|
+
{ "count": 1473, "coverage": 5404 },
|
|
21
|
+
{ "count": 1370, "coverage": 5120 }
|
|
22
|
+
],
|
|
23
|
+
[
|
|
24
|
+
{ "count": 348, "coverage": 5345 },
|
|
25
|
+
{ "count": 360, "coverage": 5592 },
|
|
26
|
+
{ "count": 273, "coverage": 5470 },
|
|
27
|
+
{ "count": 214, "coverage": 5158 }
|
|
28
|
+
],
|
|
29
|
+
[
|
|
30
|
+
{ "count": 322, "coverage": 5006 },
|
|
31
|
+
{ "count": 323, "coverage": 5215 },
|
|
32
|
+
{ "count": 259, "coverage": 5214 },
|
|
33
|
+
{ "count": 191, "coverage": 4831 }
|
|
34
|
+
],
|
|
35
|
+
[
|
|
36
|
+
{ "count": 381, "coverage": 5383 },
|
|
37
|
+
{ "count": 402, "coverage": 5618 },
|
|
38
|
+
{ "count": 353, "coverage": 5500 },
|
|
39
|
+
{ "count": 303, "coverage": 5194 }
|
|
40
|
+
],
|
|
41
|
+
[
|
|
42
|
+
{ "count": 1175, "coverage": 5348 },
|
|
43
|
+
{ "count": 1104, "coverage": 5557 },
|
|
44
|
+
{ "count": 1156, "coverage": 5474 },
|
|
45
|
+
{ "count": 1100, "coverage": 5176 }
|
|
46
|
+
],
|
|
47
|
+
[
|
|
48
|
+
{ "count": 300, "coverage": 4800 },
|
|
49
|
+
{ "count": 512, "coverage": 4860 },
|
|
50
|
+
{ "count": 311, "coverage": 4833 },
|
|
51
|
+
{ "count": 124, "coverage": 4390 }
|
|
52
|
+
],
|
|
53
|
+
[
|
|
54
|
+
{ "count": 337, "coverage": 5391 },
|
|
55
|
+
{ "count": 431, "coverage": 5615 },
|
|
56
|
+
{ "count": 565, "coverage": 5497 },
|
|
57
|
+
{ "count": 662, "coverage": 5193 }
|
|
58
|
+
],
|
|
59
|
+
[
|
|
60
|
+
{ "count": 17, "coverage": 251 },
|
|
61
|
+
{ "count": 7, "coverage": 260 },
|
|
62
|
+
{ "count": 17, "coverage": 237 },
|
|
63
|
+
{ "count": 13, "coverage": 185 }
|
|
64
|
+
]
|
|
65
|
+
],
|
|
66
|
+
"totalCountsByDateRange": [5395, 5624, 5506, 5200]
|
|
67
|
+
},
|
|
68
|
+
"info": {
|
|
69
|
+
"dataVersion": "1774200829",
|
|
70
|
+
"requestId": "84c09426-1724-49bb-8e8e-fcc0d98d2c89",
|
|
71
|
+
"requestInfo": "sars_cov-2_nextstrain_open on lapis.cov-spectrum.org at 2026-03-24T08:56:49.830150373",
|
|
72
|
+
"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.",
|
|
73
|
+
"lapisVersion": "0.7.0",
|
|
74
|
+
"siloVersion": "0.10.0"
|
|
75
|
+
}
|
|
76
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
"data": {
|
|
3
|
+
"mutations": ["T21653-", "T21655-"],
|
|
4
|
+
"dateRanges": [
|
|
5
|
+
{ "dateFrom": "2024-01-01", "dateTo": "2024-01-31" },
|
|
6
|
+
{ "dateFrom": "2024-02-01", "dateTo": "2024-02-29" },
|
|
7
|
+
{ "dateFrom": "2024-03-01", "dateTo": "2024-03-31" },
|
|
8
|
+
{ "dateFrom": "2024-04-01", "dateTo": "2024-04-30" },
|
|
9
|
+
{ "dateFrom": "2024-05-01", "dateTo": "2024-05-31" },
|
|
10
|
+
{ "dateFrom": "2024-06-01", "dateTo": "2024-06-30" },
|
|
11
|
+
{ "dateFrom": "2024-07-01", "dateTo": "2024-07-31" }
|
|
12
|
+
],
|
|
13
|
+
"data": [
|
|
14
|
+
[
|
|
15
|
+
{ "count": 13, "coverage": 13948 },
|
|
16
|
+
{ "count": 15, "coverage": 17359 },
|
|
17
|
+
{ "count": 41, "coverage": 8319 },
|
|
18
|
+
{ "count": 237, "coverage": 6564 },
|
|
19
|
+
{ "count": 1370, "coverage": 9054 },
|
|
20
|
+
{ "count": 5079, "coverage": 16077 },
|
|
21
|
+
{ "count": 3245, "coverage": 7342 }
|
|
22
|
+
],
|
|
23
|
+
[
|
|
24
|
+
{ "count": 12, "coverage": 13941 },
|
|
25
|
+
{ "count": 14, "coverage": 17360 },
|
|
26
|
+
{ "count": 41, "coverage": 8327 },
|
|
27
|
+
{ "count": 235, "coverage": 6596 },
|
|
28
|
+
{ "count": 1376, "coverage": 9143 },
|
|
29
|
+
{ "count": 5089, "coverage": 16368 },
|
|
30
|
+
{ "count": 3256, "coverage": 7477 }
|
|
31
|
+
]
|
|
32
|
+
],
|
|
33
|
+
"totalCountsByDateRange": [14065, 17583, 8432, 6680, 9252, 16512, 7508]
|
|
34
|
+
},
|
|
35
|
+
"info": {
|
|
36
|
+
"dataVersion": "1774200829",
|
|
37
|
+
"requestId": "dcc96846-d1d8-4ae2-afbe-60fcda8e64f0",
|
|
38
|
+
"requestInfo": "sars_cov-2_nextstrain_open on lapis.cov-spectrum.org at 2026-03-24T09:25:28.706437897",
|
|
39
|
+
"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.",
|
|
40
|
+
"lapisVersion": "0.7.0",
|
|
41
|
+
"siloVersion": "0.10.0"
|
|
42
|
+
}
|
|
43
|
+
}
|