@genspectrum/dashboard-components 1.11.1 → 1.13.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 +0 -7
- package/custom-elements.json +6 -25
- package/dist/components.d.ts +24 -30
- package/dist/components.js +929 -742
- package/dist/components.js.map +1 -1
- package/dist/util.d.ts +40 -24
- package/package.json +1 -5
- package/src/lapisApi/lapisApi.ts +21 -1
- package/src/lapisApi/lapisTypes.ts +37 -0
- package/src/preact/components/annotated-mutation.tsx +2 -2
- package/src/preact/{mutationsOverTime/mutations-over-time-grid.tsx → components/features-over-time-grid.tsx} +45 -52
- package/src/preact/genomeViewer/genome-data-viewer.tsx +2 -2
- package/src/preact/mutationsOverTime/MutationOverTimeData.ts +6 -4
- package/src/preact/mutationsOverTime/__mockData__/aminoAcidMutationsByDay/aminoAcidMutations.json +5482 -0
- package/src/preact/mutationsOverTime/__mockData__/aminoAcidMutationsByDay/aminoAcidMutationsOverTime.json +5496 -0
- package/src/preact/mutationsOverTime/__mockData__/byWeek/mutationsOverTime.json +7100 -0
- package/src/preact/mutationsOverTime/__mockData__/byWeek/nucleotideMutations.json +10122 -0
- package/src/preact/mutationsOverTime/__mockData__/defaultMockData/mutationsOverTime.json +12646 -0
- package/src/preact/mutationsOverTime/__mockData__/defaultMockData/nucleotideMutations.json +12632 -0
- package/src/preact/mutationsOverTime/__mockData__/request1800s/mutationsOverTime.json +16 -0
- package/src/preact/mutationsOverTime/__mockData__/request1800s/nucleotideMutations.json +11 -0
- package/src/preact/mutationsOverTime/__mockData__/withDisplayMutations/mutationsOverTime.json +52 -0
- package/src/preact/mutationsOverTime/getFilteredMutationsOverTime.spec.ts +3 -3
- package/src/preact/mutationsOverTime/mutations-over-time-grid-tooltip.tsx +3 -6
- package/src/preact/mutationsOverTime/mutations-over-time.stories.tsx +199 -12
- package/src/preact/mutationsOverTime/mutations-over-time.tsx +30 -35
- package/src/preact/wastewater/mutationsOverTime/wastewater-mutations-over-time.tsx +30 -3
- package/src/query/queryDatesInDataset.ts +89 -0
- package/src/query/queryMutationsOverTime.spec.ts +526 -548
- package/src/query/queryMutationsOverTime.ts +22 -245
- package/src/query/queryQueriesOverTime.spec.ts +432 -0
- package/src/query/queryQueriesOverTime.ts +125 -0
- package/src/utilEntrypoint.ts +3 -1
- package/src/utils/mutations.spec.ts +6 -0
- package/src/utils/mutations.ts +1 -1
- package/src/utils/temporalClass.ts +4 -0
- package/src/web-components/visualization/gs-mutation-comparison.tsx +2 -2
- package/src/web-components/visualization/gs-mutations-over-time.spec-d.ts +0 -3
- package/src/web-components/visualization/gs-mutations-over-time.stories.ts +283 -17
- package/src/web-components/visualization/gs-mutations-over-time.tsx +0 -9
- package/standalone-bundle/dashboard-components.js +8935 -8780
- package/standalone-bundle/dashboard-components.js.map +1 -1
- package/dist/assets/mutationOverTimeWorker-CQQFRoK4.js.map +0 -1
- package/src/preact/mutationsOverTime/__mockData__/aminoAcidMutationsByDay.ts +0 -47170
- package/src/preact/mutationsOverTime/__mockData__/byWeek.ts +0 -54026
- package/src/preact/mutationsOverTime/__mockData__/defaultMockData.ts +0 -108385
- package/src/preact/mutationsOverTime/__mockData__/mockConversion.ts +0 -54
- package/src/preact/mutationsOverTime/__mockData__/noDataWhenNoMutationsAreInFilter.ts +0 -23
- package/src/preact/mutationsOverTime/__mockData__/noDataWhenThereAreNoDatesInFilter.ts +0 -23
- package/src/preact/mutationsOverTime/__mockData__/showsMessageWhenTooManyMutations.ts +0 -65527
- package/src/preact/mutationsOverTime/__mockData__/withDisplayMutations.ts +0 -352
- package/src/preact/mutationsOverTime/__mockData__/withGaps.ts +0 -298
- package/src/preact/mutationsOverTime/mutationOverTimeWorker.mock.ts +0 -33
- package/src/preact/mutationsOverTime/mutationOverTimeWorker.ts +0 -29
- package/src/preact/webWorkers/useWebWorker.ts +0 -74
- package/src/preact/webWorkers/workerFunction.ts +0 -30
- package/src/query/queryMutationsOverTimeNewEndpoint.spec.ts +0 -1179
- package/standalone-bundle/assets/mutationOverTimeWorker-DIpJukJC.js.map +0 -1
|
@@ -1,48 +1,20 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { queryDatesInDataset } from './queryDatesInDataset';
|
|
2
2
|
import { fetchMutationsOverTime } from '../lapisApi/lapisApi';
|
|
3
|
-
import { FetchAggregatedOperator } from '../operator/FetchAggregatedOperator';
|
|
4
3
|
import { FetchSubstitutionsOrDeletionsOperator } from '../operator/FetchSubstitutionsOrDeletionsOperator';
|
|
5
|
-
import { GroupByAndSumOperator } from '../operator/GroupByAndSumOperator';
|
|
6
|
-
import { MapOperator } from '../operator/MapOperator';
|
|
7
|
-
import { RenameFieldOperator } from '../operator/RenameFieldOperator';
|
|
8
|
-
import { SortOperator } from '../operator/SortOperator';
|
|
9
4
|
import { UserFacingError } from '../preact/components/error-display';
|
|
10
5
|
import { BaseMutationOverTimeDataMap } from '../preact/mutationsOverTime/MutationOverTimeData';
|
|
11
6
|
import { sortSubstitutionsAndDeletions } from '../preact/shared/sort/sortSubstitutionsAndDeletions';
|
|
12
7
|
import {
|
|
13
|
-
type DeletionEntry,
|
|
14
8
|
type LapisFilter,
|
|
15
9
|
type SequenceType,
|
|
16
|
-
type SubstitutionEntry,
|
|
17
10
|
type SubstitutionOrDeletionEntry,
|
|
18
11
|
type TemporalGranularity,
|
|
19
12
|
} from '../types';
|
|
20
13
|
import { type Map2DContents } from '../utils/map2d';
|
|
21
|
-
import {
|
|
22
|
-
|
|
23
|
-
type Substitution,
|
|
24
|
-
toSubstitutionOrDeletion,
|
|
25
|
-
DeletionClass,
|
|
26
|
-
SubstitutionClass,
|
|
27
|
-
} from '../utils/mutations';
|
|
28
|
-
import {
|
|
29
|
-
compareTemporal,
|
|
30
|
-
dateRangeCompare,
|
|
31
|
-
generateAllInRange,
|
|
32
|
-
getMinMaxTemporal,
|
|
33
|
-
parseDateStringToTemporal,
|
|
34
|
-
type Temporal,
|
|
35
|
-
type TemporalClass,
|
|
36
|
-
toTemporal,
|
|
37
|
-
} from '../utils/temporalClass';
|
|
38
|
-
|
|
39
|
-
export type MutationOverTimeData = {
|
|
40
|
-
date: TemporalClass;
|
|
41
|
-
mutations: SubstitutionOrDeletionEntry[];
|
|
42
|
-
totalCount: number;
|
|
43
|
-
};
|
|
14
|
+
import { type Deletion, type Substitution, DeletionClass, SubstitutionClass } from '../utils/mutations';
|
|
15
|
+
import { type Temporal } from '../utils/temporalClass';
|
|
44
16
|
|
|
45
|
-
export type
|
|
17
|
+
export type ProportionValue =
|
|
46
18
|
| {
|
|
47
19
|
type: 'value';
|
|
48
20
|
proportion: number;
|
|
@@ -65,7 +37,7 @@ export type MutationOverTimeMutationValue =
|
|
|
65
37
|
}
|
|
66
38
|
| null;
|
|
67
39
|
|
|
68
|
-
export function getProportion(value:
|
|
40
|
+
export function getProportion(value: ProportionValue) {
|
|
69
41
|
switch (value?.type) {
|
|
70
42
|
case 'value':
|
|
71
43
|
case 'wastewaterValue':
|
|
@@ -130,7 +102,7 @@ async function queryOverallMutationData({
|
|
|
130
102
|
includeMutations?: string[];
|
|
131
103
|
signal?: AbortSignal;
|
|
132
104
|
}) {
|
|
133
|
-
const requestedDateRanges = await
|
|
105
|
+
const requestedDateRanges = await queryDatesInDataset(lapisFilter, lapis, granularity, lapisDateField, signal);
|
|
134
106
|
|
|
135
107
|
if (requestedDateRanges.length === 0) {
|
|
136
108
|
if (includeMutations) {
|
|
@@ -170,22 +142,16 @@ async function queryOverallMutationData({
|
|
|
170
142
|
return dataPromise;
|
|
171
143
|
}
|
|
172
144
|
|
|
173
|
-
export
|
|
174
|
-
lapisFilter: LapisFilter
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
export async function queryMutationsOverTimeData(query: MutationOverTimeQuery) {
|
|
185
|
-
const { lapisFilter, displayMutations, sequenceType, lapis, lapisDateField, granularity, useNewEndpoint, signal } =
|
|
186
|
-
query;
|
|
187
|
-
|
|
188
|
-
const requestedDateRanges = await getDatesInDataset(lapisFilter, lapis, granularity, lapisDateField, signal);
|
|
145
|
+
export async function queryMutationsOverTimeData(
|
|
146
|
+
lapisFilter: LapisFilter,
|
|
147
|
+
sequenceType: SequenceType,
|
|
148
|
+
lapis: string,
|
|
149
|
+
lapisDateField: string,
|
|
150
|
+
granularity: TemporalGranularity,
|
|
151
|
+
displayMutations?: string[],
|
|
152
|
+
signal?: AbortSignal,
|
|
153
|
+
) {
|
|
154
|
+
const requestedDateRanges = await queryDatesInDataset(lapisFilter, lapis, granularity, lapisDateField, signal);
|
|
189
155
|
|
|
190
156
|
if (requestedDateRanges.length > MAX_NUMBER_OF_GRID_COLUMNS) {
|
|
191
157
|
throw new UserFacingError(
|
|
@@ -196,7 +162,7 @@ export async function queryMutationsOverTimeData(query: MutationOverTimeQuery) {
|
|
|
196
162
|
);
|
|
197
163
|
}
|
|
198
164
|
|
|
199
|
-
const overallMutationData = queryOverallMutationData({
|
|
165
|
+
const overallMutationData = await queryOverallMutationData({
|
|
200
166
|
lapisFilter,
|
|
201
167
|
sequenceType,
|
|
202
168
|
lapis,
|
|
@@ -205,77 +171,14 @@ export async function queryMutationsOverTimeData(query: MutationOverTimeQuery) {
|
|
|
205
171
|
granularity,
|
|
206
172
|
}).then((r) => r.content);
|
|
207
173
|
|
|
208
|
-
return useNewEndpoint === true
|
|
209
|
-
? queryMutationsOverTimeDataDirectEndpoint(requestedDateRanges, overallMutationData, query)
|
|
210
|
-
: queryMutationsOverTimeDataMultiQuery(requestedDateRanges, overallMutationData, query);
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
async function queryMutationsOverTimeDataMultiQuery(
|
|
214
|
-
allDates: TemporalClass[],
|
|
215
|
-
overallMutationDataPromise: Promise<SubstitutionOrDeletionEntry[]>,
|
|
216
|
-
{ lapisFilter, sequenceType, lapis, lapisDateField, signal }: MutationOverTimeQuery,
|
|
217
|
-
) {
|
|
218
|
-
const subQueries = allDates.map(async (date) => {
|
|
219
|
-
const dateFrom = date.firstDay.toString();
|
|
220
|
-
const dateTo = date.lastDay.toString();
|
|
221
|
-
|
|
222
|
-
const filter = {
|
|
223
|
-
...lapisFilter,
|
|
224
|
-
[`${lapisDateField}From`]: dateFrom,
|
|
225
|
-
[`${lapisDateField}To`]: dateTo,
|
|
226
|
-
};
|
|
227
|
-
|
|
228
|
-
const [data, totalCountQuery] = await Promise.all([
|
|
229
|
-
fetchAndPrepareSubstitutionsOrDeletions(filter, sequenceType).evaluate(lapis, signal),
|
|
230
|
-
getTotalNumberOfSequencesInDateRange(filter).evaluate(lapis, signal),
|
|
231
|
-
]);
|
|
232
|
-
|
|
233
|
-
return {
|
|
234
|
-
date,
|
|
235
|
-
mutations: data.content,
|
|
236
|
-
totalCount: totalCountQuery.content[0].count,
|
|
237
|
-
};
|
|
238
|
-
});
|
|
239
|
-
|
|
240
|
-
const data = await Promise.all(subQueries);
|
|
241
|
-
const overallMutationData = await overallMutationDataPromise;
|
|
242
|
-
|
|
243
|
-
return {
|
|
244
|
-
mutationOverTimeData: groupByMutation(data, overallMutationData),
|
|
245
|
-
overallMutationData,
|
|
246
|
-
};
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
async function queryMutationsOverTimeDataDirectEndpoint(
|
|
250
|
-
allDates: TemporalClass[],
|
|
251
|
-
overallMutationDataPromise: Promise<SubstitutionOrDeletionEntry[]>,
|
|
252
|
-
{ lapisFilter, sequenceType, lapis, lapisDateField, signal }: MutationOverTimeQuery,
|
|
253
|
-
): Promise<{
|
|
254
|
-
mutationOverTimeData: BaseMutationOverTimeDataMap;
|
|
255
|
-
overallMutationData: SubstitutionOrDeletionEntry[];
|
|
256
|
-
}> {
|
|
257
|
-
const overallMutationData = await overallMutationDataPromise;
|
|
258
174
|
overallMutationData.sort((a, b) => sortSubstitutionsAndDeletions(a.mutation, b.mutation));
|
|
259
|
-
const totalCounts = await Promise.all(
|
|
260
|
-
allDates.map(async (date) => {
|
|
261
|
-
const filter = {
|
|
262
|
-
...lapisFilter,
|
|
263
|
-
[`${lapisDateField}From`]: date.firstDay.toString(),
|
|
264
|
-
[`${lapisDateField}To`]: date.lastDay.toString(),
|
|
265
|
-
};
|
|
266
|
-
|
|
267
|
-
const totalCountQuery = await getTotalNumberOfSequencesInDateRange(filter).evaluate(lapis, signal);
|
|
268
|
-
|
|
269
|
-
return totalCountQuery.content[0].count;
|
|
270
|
-
}),
|
|
271
|
-
);
|
|
272
175
|
|
|
273
176
|
const includeMutations = overallMutationData.map((value) => value.mutation.code);
|
|
274
177
|
const apiResult = await fetchMutationsOverTime(
|
|
275
178
|
lapis,
|
|
276
179
|
{
|
|
277
180
|
filters: lapisFilter,
|
|
278
|
-
dateRanges:
|
|
181
|
+
dateRanges: requestedDateRanges.map((date) => ({
|
|
279
182
|
dateFrom: date.firstDay.toString(),
|
|
280
183
|
dateTo: date.lastDay.toString(),
|
|
281
184
|
})),
|
|
@@ -286,6 +189,7 @@ async function queryMutationsOverTimeDataDirectEndpoint(
|
|
|
286
189
|
signal,
|
|
287
190
|
);
|
|
288
191
|
|
|
192
|
+
const totalCounts = apiResult.data.totalCountsByDateRange;
|
|
289
193
|
const responseMutations = apiResult.data.mutations.map(parseMutationCode);
|
|
290
194
|
const mutationEntries: SubstitutionOrDeletionEntry[] = responseMutations.map((mutation, i) => {
|
|
291
195
|
const numbers = {
|
|
@@ -307,14 +211,14 @@ async function queryMutationsOverTimeDataDirectEndpoint(
|
|
|
307
211
|
}
|
|
308
212
|
});
|
|
309
213
|
|
|
310
|
-
const mutationOverTimeData: Map2DContents<Substitution | Deletion, Temporal,
|
|
214
|
+
const mutationOverTimeData: Map2DContents<Substitution | Deletion, Temporal, ProportionValue> = {
|
|
311
215
|
keysFirstAxis: new Map(responseMutations.map((mutation) => [mutation.code, mutation])),
|
|
312
|
-
keysSecondAxis: new Map(
|
|
216
|
+
keysSecondAxis: new Map(requestedDateRanges.map((date) => [date.dateString, date])),
|
|
313
217
|
data: new Map(
|
|
314
218
|
responseMutations.map((mutation, i) => [
|
|
315
219
|
mutation.code,
|
|
316
220
|
new Map(
|
|
317
|
-
|
|
221
|
+
requestedDateRanges.map((date, j): [string, ProportionValue] => {
|
|
318
222
|
if (totalCounts[j] === 0) {
|
|
319
223
|
return [date.dateString, null];
|
|
320
224
|
}
|
|
@@ -365,75 +269,6 @@ function parseMutationCode(code: string): SubstitutionClass | DeletionClass {
|
|
|
365
269
|
throw Error(`Given code is not valid: ${code}`);
|
|
366
270
|
}
|
|
367
271
|
|
|
368
|
-
/**
|
|
369
|
-
* Returns a list of date ranges as TemporalClass.
|
|
370
|
-
* Respects date range filters given in the lapisFilter as <lapisDateField>From and <lapisDateField>To.
|
|
371
|
-
* If either side (or both sides) of the range are not given, the min and max are determined from
|
|
372
|
-
* the available data.
|
|
373
|
-
*/
|
|
374
|
-
async function getDatesInDataset(
|
|
375
|
-
lapisFilter: LapisFilter,
|
|
376
|
-
lapis: string,
|
|
377
|
-
granularity: TemporalGranularity,
|
|
378
|
-
lapisDateField: string,
|
|
379
|
-
signal: AbortSignal | undefined,
|
|
380
|
-
) {
|
|
381
|
-
const { dateFrom, dateTo } = getDateRangeFromFilter(lapisFilter, lapisDateField, granularity);
|
|
382
|
-
if (dateFrom !== null && dateTo !== null) {
|
|
383
|
-
return generateAllInRange(dateFrom, dateTo);
|
|
384
|
-
}
|
|
385
|
-
|
|
386
|
-
const { content: availableDates } = await queryAvailableDates(
|
|
387
|
-
lapisFilter,
|
|
388
|
-
lapis,
|
|
389
|
-
granularity,
|
|
390
|
-
lapisDateField,
|
|
391
|
-
signal,
|
|
392
|
-
);
|
|
393
|
-
|
|
394
|
-
const { min, max } = getMinMaxTemporal(availableDates);
|
|
395
|
-
|
|
396
|
-
return generateAllInRange(dateFrom ?? min, dateTo ?? max);
|
|
397
|
-
}
|
|
398
|
-
|
|
399
|
-
function getDateRangeFromFilter(lapisFilter: LapisFilter, lapisDateField: string, granularity: TemporalGranularity) {
|
|
400
|
-
const valueFromFilter = lapisFilter[lapisDateField] as string | null;
|
|
401
|
-
|
|
402
|
-
if (valueFromFilter) {
|
|
403
|
-
return {
|
|
404
|
-
dateFrom: parseDateStringToTemporal(valueFromFilter, granularity),
|
|
405
|
-
dateTo: parseDateStringToTemporal(valueFromFilter, granularity),
|
|
406
|
-
};
|
|
407
|
-
}
|
|
408
|
-
|
|
409
|
-
const minFromFilter = lapisFilter[`${lapisDateField}From`] as string | null;
|
|
410
|
-
const maxFromFilter = lapisFilter[`${lapisDateField}To`] as string | null;
|
|
411
|
-
|
|
412
|
-
return {
|
|
413
|
-
dateFrom: minFromFilter ? parseDateStringToTemporal(minFromFilter, granularity) : null,
|
|
414
|
-
dateTo: maxFromFilter ? parseDateStringToTemporal(maxFromFilter, granularity) : null,
|
|
415
|
-
};
|
|
416
|
-
}
|
|
417
|
-
|
|
418
|
-
function queryAvailableDates(
|
|
419
|
-
lapisFilter: LapisFilter,
|
|
420
|
-
lapis: string,
|
|
421
|
-
granularity: TemporalGranularity,
|
|
422
|
-
lapisDateField: string,
|
|
423
|
-
signal?: AbortSignal,
|
|
424
|
-
) {
|
|
425
|
-
return fetchAndPrepareDates(lapisFilter, granularity, lapisDateField).evaluate(lapis, signal);
|
|
426
|
-
}
|
|
427
|
-
|
|
428
|
-
function fetchAndPrepareDates(filter: LapisFilter, granularity: TemporalGranularity, lapisDateField: string) {
|
|
429
|
-
const fetchData = new FetchAggregatedOperator<Record<string, string | null>>(filter, [lapisDateField]);
|
|
430
|
-
const dataWithFixedDateKey = new RenameFieldOperator(fetchData, lapisDateField, 'date');
|
|
431
|
-
const mapData = new MapOperator(dataWithFixedDateKey, (data) => mapDateToGranularityRange(data, granularity));
|
|
432
|
-
const groupByData = new GroupByAndSumOperator(mapData, 'dateRange', 'count');
|
|
433
|
-
const sortData = new SortOperator(groupByData, dateRangeCompare);
|
|
434
|
-
return new MapOperator(sortData, (data) => data.dateRange);
|
|
435
|
-
}
|
|
436
|
-
|
|
437
272
|
function fetchAndPrepareSubstitutionsOrDeletions(filter: LapisFilter, sequenceType: SequenceType) {
|
|
438
273
|
return new FetchSubstitutionsOrDeletionsOperator(filter, sequenceType, MUTATIONS_OVER_TIME_MIN_PROPORTION);
|
|
439
274
|
}
|
|
@@ -445,61 +280,3 @@ export function serializeSubstitutionOrDeletion(mutation: Substitution | Deletio
|
|
|
445
280
|
export function serializeTemporal(date: Temporal) {
|
|
446
281
|
return date.dateString;
|
|
447
282
|
}
|
|
448
|
-
|
|
449
|
-
export function groupByMutation(
|
|
450
|
-
data: MutationOverTimeData[],
|
|
451
|
-
overallMutationData: (SubstitutionEntry | DeletionEntry)[],
|
|
452
|
-
): BaseMutationOverTimeDataMap {
|
|
453
|
-
const dataArray = new BaseMutationOverTimeDataMap();
|
|
454
|
-
|
|
455
|
-
const allDates = data.map((mutationData) => mutationData.date);
|
|
456
|
-
|
|
457
|
-
const sortedOverallMutationData = overallMutationData
|
|
458
|
-
.sort((a, b) => sortSubstitutionsAndDeletions(a.mutation, b.mutation))
|
|
459
|
-
.map((entry) => {
|
|
460
|
-
return toSubstitutionOrDeletion(entry.mutation);
|
|
461
|
-
});
|
|
462
|
-
const sortedDates = allDates.sort((a, b) => compareTemporal(a, b)).map((date) => toTemporal(date));
|
|
463
|
-
|
|
464
|
-
sortedOverallMutationData.forEach((mutationData) => {
|
|
465
|
-
sortedDates.forEach((date) => {
|
|
466
|
-
dataArray.set(mutationData, date, null);
|
|
467
|
-
});
|
|
468
|
-
});
|
|
469
|
-
|
|
470
|
-
data.forEach((mutationData) => {
|
|
471
|
-
if (mutationData.totalCount == 0) {
|
|
472
|
-
return;
|
|
473
|
-
}
|
|
474
|
-
|
|
475
|
-
const date = toTemporal(mutationData.date);
|
|
476
|
-
|
|
477
|
-
mutationData.mutations.forEach((mutationEntry) => {
|
|
478
|
-
const mutation = toSubstitutionOrDeletion(mutationEntry.mutation);
|
|
479
|
-
|
|
480
|
-
if (dataArray.get(mutation, date) !== undefined) {
|
|
481
|
-
dataArray.set(mutation, date, {
|
|
482
|
-
type: 'value',
|
|
483
|
-
count: mutationEntry.count,
|
|
484
|
-
proportion: mutationEntry.proportion,
|
|
485
|
-
totalCount: mutationData.totalCount,
|
|
486
|
-
});
|
|
487
|
-
}
|
|
488
|
-
});
|
|
489
|
-
|
|
490
|
-
for (const firstAxisKey of dataArray.getFirstAxisKeys()) {
|
|
491
|
-
if (dataArray.get(firstAxisKey, date) === null) {
|
|
492
|
-
dataArray.set(firstAxisKey, date, {
|
|
493
|
-
type: 'belowThreshold',
|
|
494
|
-
totalCount: mutationData.totalCount,
|
|
495
|
-
});
|
|
496
|
-
}
|
|
497
|
-
}
|
|
498
|
-
});
|
|
499
|
-
|
|
500
|
-
return dataArray;
|
|
501
|
-
}
|
|
502
|
-
|
|
503
|
-
function getTotalNumberOfSequencesInDateRange(filter: LapisFilter) {
|
|
504
|
-
return new FetchAggregatedOperator<{ count: number }>(filter);
|
|
505
|
-
}
|