@genspectrum/dashboard-components 0.6.18 → 0.6.19

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.
Files changed (108) hide show
  1. package/README.md +5 -12
  2. package/custom-elements.json +4 -4
  3. package/dist/assets/mutationOverTimeWorker-BdzqDqvO.js.map +1 -0
  4. package/dist/dashboard-components.js +216 -214
  5. package/dist/dashboard-components.js.map +1 -1
  6. package/dist/genspectrum-components.d.ts +40 -40
  7. package/dist/style.css +3 -2
  8. package/package.json +13 -2
  9. package/src/operator/FetchInsertionsOperator.ts +2 -2
  10. package/src/operator/FetchSubstitutionsOrDeletionsOperator.ts +3 -3
  11. package/src/preact/mutationComparison/fetchMutationData.spec.ts +3 -3
  12. package/src/preact/mutationComparison/getMutationComparisonTableData.spec.ts +11 -11
  13. package/src/preact/mutationComparison/getMutationComparisonTableData.ts +4 -4
  14. package/src/preact/mutationComparison/mutation-comparison-table.tsx +2 -2
  15. package/src/preact/mutationFilter/mutation-filter.tsx +27 -18
  16. package/src/preact/mutationFilter/parseAndValidateMutation.ts +4 -4
  17. package/src/preact/mutationFilter/parseMutation.spec.ts +17 -17
  18. package/src/preact/mutations/getInsertionsTableData.spec.ts +3 -3
  19. package/src/preact/mutations/getMutationsGridData.spec.ts +9 -9
  20. package/src/preact/mutations/getMutationsTableData.spec.ts +7 -7
  21. package/src/preact/mutations/mutations-insertions-table.tsx +3 -3
  22. package/src/preact/mutations/mutations-table.tsx +3 -3
  23. package/src/preact/mutationsOverTime/__mockData__/aminoAcidMutationsByDay.ts +45686 -0
  24. package/src/preact/mutationsOverTime/__mockData__/byWeek.ts +58989 -0
  25. package/src/preact/mutationsOverTime/__mockData__/defaultMockData.ts +103991 -0
  26. package/src/preact/mutationsOverTime/__mockData__/mockConversion.ts +54 -0
  27. package/src/preact/mutationsOverTime/__mockData__/showsMessageWhenTooManyMutations.ts +63690 -0
  28. package/src/preact/mutationsOverTime/getFilteredMutationsOverTime.spec.ts +176 -159
  29. package/src/preact/mutationsOverTime/getFilteredMutationsOverTimeData.ts +17 -59
  30. package/src/preact/mutationsOverTime/mutationOverTimeWorker.mock.ts +27 -0
  31. package/src/preact/mutationsOverTime/mutationOverTimeWorker.ts +29 -0
  32. package/src/preact/mutationsOverTime/mutations-over-time-grid.tsx +13 -14
  33. package/src/preact/mutationsOverTime/mutations-over-time.stories.tsx +9 -334
  34. package/src/preact/mutationsOverTime/mutations-over-time.tsx +68 -52
  35. package/src/preact/numberSequencesOverTime/getNumberOfSequencesOverTimeTableData.ts +3 -3
  36. package/src/preact/prevalenceOverTime/getPrevalenceOverTimeTableData.spec.ts +5 -5
  37. package/src/preact/prevalenceOverTime/prevalence-over-time-bubble-chart.tsx +1 -1
  38. package/src/preact/relativeGrowthAdvantage/relative-growth-advantage-chart.tsx +2 -2
  39. package/src/preact/shared/sort/sortInsertions.spec.ts +11 -11
  40. package/src/preact/shared/sort/sortInsertions.ts +2 -2
  41. package/src/preact/shared/sort/sortSubstitutionsAndDeletions.spec.ts +13 -13
  42. package/src/preact/shared/sort/sortSubstitutionsAndDeletions.ts +7 -4
  43. package/src/preact/webWorkers/useWebWorker.ts +51 -0
  44. package/src/preact/webWorkers/workerFunction.ts +14 -0
  45. package/src/query/queryAggregatedDataOverTime.ts +3 -3
  46. package/src/query/queryMutationsOverTime.spec.ts +272 -51
  47. package/src/query/queryMutationsOverTime.ts +114 -45
  48. package/src/query/queryPrevalenceOverTime.ts +2 -2
  49. package/src/query/queryRelativeGrowthAdvantage.ts +3 -3
  50. package/src/types.ts +25 -5
  51. package/src/utils/map2d.spec.ts +29 -1
  52. package/src/utils/map2d.ts +22 -1
  53. package/src/utils/mutations.spec.ts +20 -20
  54. package/src/utils/mutations.ts +80 -17
  55. package/src/utils/sort.ts +5 -2
  56. package/src/utils/temporal.spec.ts +27 -24
  57. package/src/utils/{temporal.ts → temporalClass.ts} +170 -72
  58. package/src/utils/temporalTestHelpers.ts +3 -3
  59. package/src/web-components/introduction.mdx +46 -0
  60. package/src/web-components/visualization/gs-mutations-over-time.stories.ts +6 -699
  61. package/src/web-components/visualization/gs-mutations-over-time.tsx +2 -2
  62. package/standalone-bundle/dashboard-components.js +13763 -13754
  63. package/standalone-bundle/dashboard-components.js.map +1 -1
  64. package/src/preact/mutationsOverTime/__mockData__/aggregated_2024_01.json +0 -13
  65. package/src/preact/mutationsOverTime/__mockData__/aggregated_2024_02.json +0 -13
  66. package/src/preact/mutationsOverTime/__mockData__/aggregated_2024_03.json +0 -13
  67. package/src/preact/mutationsOverTime/__mockData__/aggregated_2024_04.json +0 -13
  68. package/src/preact/mutationsOverTime/__mockData__/aggregated_2024_05.json +0 -13
  69. package/src/preact/mutationsOverTime/__mockData__/aggregated_2024_06.json +0 -13
  70. package/src/preact/mutationsOverTime/__mockData__/aggregated_2024_07.json +0 -13
  71. package/src/preact/mutationsOverTime/__mockData__/aggregated_20_01_2024.json +0 -13
  72. package/src/preact/mutationsOverTime/__mockData__/aggregated_21_01_2024.json +0 -13
  73. package/src/preact/mutationsOverTime/__mockData__/aggregated_22_01_2024.json +0 -13
  74. package/src/preact/mutationsOverTime/__mockData__/aggregated_23_01_2024.json +0 -13
  75. package/src/preact/mutationsOverTime/__mockData__/aggregated_24_01_2024.json +0 -13
  76. package/src/preact/mutationsOverTime/__mockData__/aggregated_25_01_2024.json +0 -13
  77. package/src/preact/mutationsOverTime/__mockData__/aggregated_26_01_2024.json +0 -13
  78. package/src/preact/mutationsOverTime/__mockData__/aggregated_byDay.json +0 -38
  79. package/src/preact/mutationsOverTime/__mockData__/aggregated_byWeek.json +0 -122
  80. package/src/preact/mutationsOverTime/__mockData__/aggregated_date.json +0 -642
  81. package/src/preact/mutationsOverTime/__mockData__/aggregated_tooManyMutations.json +0 -1470
  82. package/src/preact/mutationsOverTime/__mockData__/aggregated_tooManyMutations_total.json +0 -13
  83. package/src/preact/mutationsOverTime/__mockData__/aggregated_week3_2024.json +0 -13
  84. package/src/preact/mutationsOverTime/__mockData__/aggregated_week4_2024.json +0 -13
  85. package/src/preact/mutationsOverTime/__mockData__/aggregated_week5_2024.json +0 -13
  86. package/src/preact/mutationsOverTime/__mockData__/aggregated_week6_2024.json +0 -13
  87. package/src/preact/mutationsOverTime/__mockData__/aminoAcidMutations_20_01_2024.json +0 -6778
  88. package/src/preact/mutationsOverTime/__mockData__/aminoAcidMutations_21_01_2024.json +0 -7129
  89. package/src/preact/mutationsOverTime/__mockData__/aminoAcidMutations_22_01_2024.json +0 -4681
  90. package/src/preact/mutationsOverTime/__mockData__/aminoAcidMutations_23_01_2024.json +0 -10738
  91. package/src/preact/mutationsOverTime/__mockData__/aminoAcidMutations_24_01_2024.json +0 -11710
  92. package/src/preact/mutationsOverTime/__mockData__/aminoAcidMutations_25_01_2024.json +0 -11557
  93. package/src/preact/mutationsOverTime/__mockData__/aminoAcidMutations_26_01_2024.json +0 -8596
  94. package/src/preact/mutationsOverTime/__mockData__/aminoAcidMutations_byDayOverall.json +0 -4726
  95. package/src/preact/mutationsOverTime/__mockData__/nucleotideMutations_2024_01.json +0 -1747
  96. package/src/preact/mutationsOverTime/__mockData__/nucleotideMutations_2024_02.json +0 -1774
  97. package/src/preact/mutationsOverTime/__mockData__/nucleotideMutations_2024_03.json +0 -1819
  98. package/src/preact/mutationsOverTime/__mockData__/nucleotideMutations_2024_04.json +0 -1864
  99. package/src/preact/mutationsOverTime/__mockData__/nucleotideMutations_2024_05.json +0 -1927
  100. package/src/preact/mutationsOverTime/__mockData__/nucleotideMutations_2024_06.json +0 -1864
  101. package/src/preact/mutationsOverTime/__mockData__/nucleotideMutations_2024_07.json +0 -9
  102. package/src/preact/mutationsOverTime/__mockData__/nucleotideMutations_byMonthOverall.json +0 -11143
  103. package/src/preact/mutationsOverTime/__mockData__/nucleotideMutations_byWeekOverall.json +0 -9154
  104. package/src/preact/mutationsOverTime/__mockData__/nucleotideMutations_tooManyMutations.json +0 -16453
  105. package/src/preact/mutationsOverTime/__mockData__/nucleotideMutations_week3_2024.json +0 -8812
  106. package/src/preact/mutationsOverTime/__mockData__/nucleotideMutations_week4_2024.json +0 -9730
  107. package/src/preact/mutationsOverTime/__mockData__/nucleotideMutations_week5_2024.json +0 -9865
  108. package/src/preact/mutationsOverTime/__mockData__/nucleotideMutations_week6_2024.json +0 -11314
@@ -1,28 +1,9 @@
1
1
  import { type Meta, type StoryObj } from '@storybook/preact';
2
2
  import { expect, waitFor } from '@storybook/test';
3
3
 
4
- import aggregated_01 from './__mockData__/aggregated_2024_01.json';
5
- import aggregated_02 from './__mockData__/aggregated_2024_02.json';
6
- import aggregated_03 from './__mockData__/aggregated_2024_03.json';
7
- import aggregated_04 from './__mockData__/aggregated_2024_04.json';
8
- import aggregated_05 from './__mockData__/aggregated_2024_05.json';
9
- import aggregated_06 from './__mockData__/aggregated_2024_06.json';
10
- import aggregated_07 from './__mockData__/aggregated_2024_07.json';
11
- import aggregated_date from './__mockData__/aggregated_date.json';
12
- import aggregated_tooManyMutations from './__mockData__/aggregated_tooManyMutations.json';
13
- import aggregated_tooManyMutations_total from './__mockData__/aggregated_tooManyMutations_total.json';
14
- import nucleotideMutation_01 from './__mockData__/nucleotideMutations_2024_01.json';
15
- import nucleotideMutation_02 from './__mockData__/nucleotideMutations_2024_02.json';
16
- import nucleotideMutation_03 from './__mockData__/nucleotideMutations_2024_03.json';
17
- import nucleotideMutation_04 from './__mockData__/nucleotideMutations_2024_04.json';
18
- import nucleotideMutation_05 from './__mockData__/nucleotideMutations_2024_05.json';
19
- import nucleotideMutation_06 from './__mockData__/nucleotideMutations_2024_06.json';
20
- import nucleotideMutation_07 from './__mockData__/nucleotideMutations_2024_07.json';
21
- import nucleotideMutation_tooManyMutations from './__mockData__/nucleotideMutations_tooManyMutations.json';
22
4
  import { MutationsOverTime, type MutationsOverTimeProps } from './mutations-over-time';
23
- import { AGGREGATED_ENDPOINT, LAPIS_URL, NUCLEOTIDE_MUTATIONS_ENDPOINT } from '../../constants';
5
+ import { LAPIS_URL } from '../../constants';
24
6
  import referenceGenome from '../../lapisApi/__mockData__/referenceGenome.json';
25
- import nucleotideMutations_byMonthOverall from '../../preact/mutationsOverTime/__mockData__/nucleotideMutations_byMonthOverall.json';
26
7
  import { LapisUrlContext } from '../LapisUrlContext';
27
8
  import { ReferenceGenomeContext } from '../ReferenceGenomeContext';
28
9
 
@@ -47,6 +28,9 @@ const meta: Meta<MutationsOverTimeProps> = {
47
28
  },
48
29
  lapisDateField: { control: 'text' },
49
30
  },
31
+ parameters: {
32
+ fetchMock: {},
33
+ },
50
34
  };
51
35
 
52
36
  export default meta;
@@ -69,6 +53,7 @@ const Template = {
69
53
  ),
70
54
  };
71
55
 
56
+ // This test uses mock data: defaultMockData.ts (through mutationOverTimeWorker.mock.ts)
72
57
  export const Default: StoryObj<MutationsOverTimeProps> = {
73
58
  ...Template,
74
59
  args: {
@@ -80,270 +65,9 @@ export const Default: StoryObj<MutationsOverTimeProps> = {
80
65
  granularity: 'month',
81
66
  lapisDateField: 'date',
82
67
  },
83
- parameters: {
84
- fetchMock: {
85
- mocks: [
86
- {
87
- matcher: {
88
- name: 'aggregated_dates',
89
- url: AGGREGATED_ENDPOINT,
90
- body: {
91
- dateFrom: '2024-01-15',
92
- dateTo: '2024-07-10',
93
- fields: ['date'],
94
- pangoLineage: 'JN.1*',
95
- },
96
- },
97
- response: {
98
- status: 200,
99
- body: aggregated_date,
100
- },
101
- },
102
- {
103
- matcher: {
104
- name: 'aggregated_01',
105
- url: AGGREGATED_ENDPOINT,
106
- body: {
107
- dateFrom: '2024-01-01',
108
- dateTo: '2024-01-31',
109
- fields: [],
110
- pangoLineage: 'JN.1*',
111
- },
112
- },
113
- response: {
114
- status: 200,
115
- body: aggregated_01,
116
- },
117
- },
118
- {
119
- matcher: {
120
- name: 'aggregated_02',
121
- url: AGGREGATED_ENDPOINT,
122
- body: {
123
- dateFrom: '2024-02-01',
124
- dateTo: '2024-02-29',
125
- fields: [],
126
- pangoLineage: 'JN.1*',
127
- },
128
- },
129
- response: {
130
- status: 200,
131
- body: aggregated_02,
132
- },
133
- },
134
- {
135
- matcher: {
136
- name: 'aggregated_03',
137
- url: AGGREGATED_ENDPOINT,
138
- body: {
139
- dateFrom: '2024-03-01',
140
- dateTo: '2024-03-31',
141
- fields: [],
142
- pangoLineage: 'JN.1*',
143
- },
144
- },
145
- response: {
146
- status: 200,
147
- body: aggregated_03,
148
- },
149
- },
150
- {
151
- matcher: {
152
- name: 'aggregated_04',
153
- url: AGGREGATED_ENDPOINT,
154
- body: {
155
- dateFrom: '2024-04-01',
156
- dateTo: '2024-04-30',
157
- fields: [],
158
- pangoLineage: 'JN.1*',
159
- },
160
- },
161
- response: {
162
- status: 200,
163
- body: aggregated_04,
164
- },
165
- },
166
- {
167
- matcher: {
168
- name: 'aggregated_05',
169
- url: AGGREGATED_ENDPOINT,
170
- body: {
171
- dateFrom: '2024-05-01',
172
- dateTo: '2024-05-31',
173
- fields: [],
174
- pangoLineage: 'JN.1*',
175
- },
176
- },
177
- response: {
178
- status: 200,
179
- body: aggregated_05,
180
- },
181
- },
182
- {
183
- matcher: {
184
- name: 'aggregated_06',
185
- url: AGGREGATED_ENDPOINT,
186
- body: {
187
- dateFrom: '2024-06-01',
188
- dateTo: '2024-06-30',
189
- fields: [],
190
- pangoLineage: 'JN.1*',
191
- },
192
- },
193
- response: {
194
- status: 200,
195
- body: aggregated_06,
196
- },
197
- },
198
- {
199
- matcher: {
200
- name: 'aggregated_07',
201
- url: AGGREGATED_ENDPOINT,
202
- body: {
203
- dateFrom: '2024-07-01',
204
- dateTo: '2024-07-31',
205
- fields: [],
206
- pangoLineage: 'JN.1*',
207
- },
208
- },
209
- response: {
210
- status: 200,
211
- body: aggregated_07,
212
- },
213
- },
214
- {
215
- matcher: {
216
- name: 'nucleotideMutations_overall',
217
- url: NUCLEOTIDE_MUTATIONS_ENDPOINT,
218
- body: {
219
- pangoLineage: 'JN.1*',
220
- dateFrom: '2024-01-15',
221
- dateTo: '2024-07-10',
222
- minProportion: 0.001,
223
- },
224
- },
225
- response: {
226
- status: 200,
227
- body: nucleotideMutations_byMonthOverall,
228
- },
229
- },
230
- {
231
- matcher: {
232
- name: 'nucleotideMutations_01',
233
- url: NUCLEOTIDE_MUTATIONS_ENDPOINT,
234
- body: {
235
- pangoLineage: 'JN.1*',
236
- dateFrom: '2024-01-01',
237
- dateTo: '2024-01-31',
238
- minProportion: 0.001,
239
- },
240
- },
241
- response: {
242
- status: 200,
243
- body: nucleotideMutation_01,
244
- },
245
- },
246
- {
247
- matcher: {
248
- name: 'nucleotideMutations_02',
249
- url: NUCLEOTIDE_MUTATIONS_ENDPOINT,
250
- body: {
251
- pangoLineage: 'JN.1*',
252
- dateFrom: '2024-02-01',
253
- dateTo: '2024-02-29',
254
- minProportion: 0.001,
255
- },
256
- },
257
- response: {
258
- status: 200,
259
- body: nucleotideMutation_02,
260
- },
261
- },
262
- {
263
- matcher: {
264
- name: 'nucleotideMutations_03',
265
- url: NUCLEOTIDE_MUTATIONS_ENDPOINT,
266
- body: {
267
- pangoLineage: 'JN.1*',
268
- dateFrom: '2024-03-01',
269
- dateTo: '2024-03-31',
270
- minProportion: 0.001,
271
- },
272
- response: {
273
- status: 200,
274
- body: nucleotideMutation_03,
275
- },
276
- },
277
- },
278
- {
279
- matcher: {
280
- name: 'nucleotideMutations_04',
281
- url: NUCLEOTIDE_MUTATIONS_ENDPOINT,
282
- body: {
283
- pangoLineage: 'JN.1*',
284
- dateFrom: '2024-04-01',
285
- dateTo: '2024-04-30',
286
- minProportion: 0.001,
287
- },
288
- response: {
289
- status: 200,
290
- body: nucleotideMutation_04,
291
- },
292
- },
293
- },
294
- {
295
- matcher: {
296
- name: 'nucleotideMutations_05',
297
- url: NUCLEOTIDE_MUTATIONS_ENDPOINT,
298
- body: {
299
- pangoLineage: 'JN.1*',
300
- dateFrom: '2024-05-01',
301
- dateTo: '2024-05-31',
302
- minProportion: 0.001,
303
- },
304
- response: {
305
- status: 200,
306
- body: nucleotideMutation_05,
307
- },
308
- },
309
- },
310
- {
311
- matcher: {
312
- name: 'nucleotideMutations_06',
313
- url: NUCLEOTIDE_MUTATIONS_ENDPOINT,
314
- body: {
315
- pangoLineage: 'JN.1*',
316
- dateFrom: '2024-06-01',
317
- dateTo: '2024-06-30',
318
- minProportion: 0.001,
319
- },
320
- response: {
321
- status: 200,
322
- body: nucleotideMutation_06,
323
- },
324
- },
325
- },
326
- {
327
- matcher: {
328
- name: 'nucleotideMutations_07',
329
- url: NUCLEOTIDE_MUTATIONS_ENDPOINT,
330
- body: {
331
- pangoLineage: 'JN.1*',
332
- dateFrom: '2024-07-01',
333
- dateTo: '2024-07-31',
334
- minProportion: 0.001,
335
- },
336
- response: {
337
- status: 200,
338
- body: nucleotideMutation_07,
339
- },
340
- },
341
- },
342
- ],
343
- },
344
- },
345
68
  };
346
69
 
70
+ // This test uses mock data: showMessagWhenTooManyMutations.ts (through mutationOverTimeWorker.mock.ts)
347
71
  export const ShowsMessageWhenTooManyMutations: StoryObj<MutationsOverTimeProps> = {
348
72
  ...Template,
349
73
  args: {
@@ -355,58 +79,9 @@ export const ShowsMessageWhenTooManyMutations: StoryObj<MutationsOverTimeProps>
355
79
  granularity: 'year',
356
80
  lapisDateField: 'date',
357
81
  },
358
- parameters: {
359
- fetchMock: {
360
- mocks: [
361
- {
362
- matcher: {
363
- name: 'aggregated',
364
- url: AGGREGATED_ENDPOINT,
365
- body: {
366
- dateFrom: '2023-01-01',
367
- dateTo: '2023-12-31',
368
- fields: ['date'],
369
- },
370
- },
371
- response: {
372
- status: 200,
373
- body: aggregated_tooManyMutations,
374
- },
375
- },
376
- {
377
- matcher: {
378
- name: 'aggregated_total',
379
- url: AGGREGATED_ENDPOINT,
380
- body: {
381
- dateFrom: '2023-01-01',
382
- dateTo: '2023-12-31',
383
- fields: [],
384
- },
385
- },
386
- response: {
387
- status: 200,
388
- body: aggregated_tooManyMutations_total,
389
- },
390
- },
391
- {
392
- matcher: {
393
- name: 'nucleotideMutations',
394
- url: NUCLEOTIDE_MUTATIONS_ENDPOINT,
395
- body: {
396
- dateFrom: '2023-01-01',
397
- dateTo: '2023-12-31',
398
- minProportion: 0.001,
399
- },
400
- response: {
401
- status: 200,
402
- body: nucleotideMutation_tooManyMutations,
403
- },
404
- },
405
- },
406
- ],
407
- },
408
- },
409
82
  play: async ({ canvas }) => {
410
- await waitFor(() => expect(canvas.getByText('Showing 100 of 137 mutations.', { exact: false })).toBeVisible());
83
+ await waitFor(() => expect(canvas.getByText('Showing 100 of 137 mutations.', { exact: false })).toBeVisible(), {
84
+ timeout: 10000,
85
+ });
411
86
  },
412
87
  };
@@ -1,22 +1,26 @@
1
1
  import { type FunctionComponent } from 'preact';
2
2
  import { type Dispatch, type StateUpdater, useContext, useMemo, useState } from 'preact/hooks';
3
3
 
4
+ // @ts-expect-error -- uses subpath imports and vite worker import
5
+ import MutationOverTimeWorker from '#mutationOverTime?worker&inline';
4
6
  import { getFilteredMutationOverTimeData } from './getFilteredMutationsOverTimeData';
7
+ import { type MutationOverTimeWorkerResponse } from './mutationOverTimeWorker';
5
8
  import MutationsOverTimeGrid from './mutations-over-time-grid';
6
- import { type Dataset } from '../../operator/Dataset';
7
9
  import {
8
- type MutationOverTimeDataGroupedByMutation,
9
- queryMutationsOverTimeData,
10
- queryOverallMutationData,
10
+ type MutationOverTimeMutationValue,
11
+ type MutationOverTimeQuery,
12
+ serializeSubstitutionOrDeletion,
13
+ serializeTemporal,
11
14
  } from '../../query/queryMutationsOverTime';
12
15
  import {
13
- type DeletionEntry,
14
16
  type LapisFilter,
15
17
  type SequenceType,
16
- type SubstitutionEntry,
18
+ type SubstitutionOrDeletionEntry,
17
19
  type TemporalGranularity,
18
20
  } from '../../types';
19
- import { compareTemporal } from '../../utils/temporal';
21
+ import { type Map2d, Map2dBase } from '../../utils/map2d';
22
+ import { type Deletion, type Substitution } from '../../utils/mutations';
23
+ import { type Temporal, toTemporalClass } from '../../utils/temporalClass';
20
24
  import { LapisUrlContext } from '../LapisUrlContext';
21
25
  import { type ColorScale } from '../components/color-scale-selector';
22
26
  import { ColorScaleSelectorDropdown } from '../components/color-scale-selector-dropdown';
@@ -33,8 +37,7 @@ import { ProportionSelectorDropdown } from '../components/proportion-selector-dr
33
37
  import { ResizeContainer } from '../components/resize-container';
34
38
  import { type DisplayedSegment, SegmentSelector, useDisplayedSegments } from '../components/segment-selector';
35
39
  import Tabs from '../components/tabs';
36
- import { sortSubstitutionsAndDeletions } from '../shared/sort/sortSubstitutionsAndDeletions';
37
- import { useQuery } from '../useQuery';
40
+ import { useWebWorker } from '../webWorkers/useWebWorker';
38
41
 
39
42
  export type View = 'grid';
40
43
 
@@ -71,41 +74,53 @@ export const MutationsOverTimeInner: FunctionComponent<MutationsOverTimeInnerPro
71
74
  lapisDateField,
72
75
  }) => {
73
76
  const lapis = useContext(LapisUrlContext);
74
- const { data, error, isLoading } = useQuery(async () => {
75
- const [mutationOverTimeData, overallMutationData] = await Promise.all([
76
- queryMutationsOverTimeData(lapisFilter, sequenceType, lapis, lapisDateField, granularity),
77
- queryOverallMutationData(lapisFilter, sequenceType, lapis),
78
- ]);
79
- return { mutationOverTimeData, overallMutationData };
80
- }, [lapisFilter, sequenceType, lapis, granularity, lapisDateField]);
77
+
78
+ const { data, error, isLoading } = useWebWorker<MutationOverTimeQuery, MutationOverTimeWorkerResponse>(
79
+ {
80
+ lapisFilter,
81
+ sequenceType,
82
+ granularity,
83
+ lapisDateField,
84
+ lapis,
85
+ },
86
+ new MutationOverTimeWorker() as Worker,
87
+ );
81
88
 
82
89
  if (isLoading) {
83
90
  return <LoadingDisplay />;
84
91
  }
85
92
 
86
- if (error !== null) {
93
+ if (error !== undefined) {
87
94
  return <ErrorDisplay error={error} />;
88
95
  }
89
96
 
90
- if (data === null) {
97
+ if (data === null || data === undefined) {
91
98
  return <NoDataDisplay />;
92
99
  }
93
100
 
101
+ const { overallMutationData, mutationOverTimeSerialized } = data;
102
+ const mutationOverTimeData = new Map2dBase(
103
+ serializeSubstitutionOrDeletion,
104
+ serializeTemporal,
105
+ mutationOverTimeSerialized,
106
+ );
94
107
  return (
95
108
  <MutationsOverTimeTabs
96
- overallMutationData={data.overallMutationData}
97
- mutationOverTimeData={data.mutationOverTimeData}
109
+ overallMutationData={overallMutationData}
110
+ mutationOverTimeData={mutationOverTimeData}
98
111
  sequenceType={sequenceType}
99
112
  views={views}
100
113
  />
101
114
  );
102
115
  };
103
116
 
117
+ export type MutationOverTimeData = Map2d<Substitution | Deletion, Temporal, MutationOverTimeMutationValue>;
118
+
104
119
  type MutationOverTimeTabsProps = {
105
- mutationOverTimeData: MutationOverTimeDataGroupedByMutation;
120
+ mutationOverTimeData: MutationOverTimeData;
106
121
  sequenceType: SequenceType;
107
122
  views: View[];
108
- overallMutationData: Dataset<SubstitutionEntry | DeletionEntry>;
123
+ overallMutationData: SubstitutionOrDeletionEntry<Substitution, Deletion>[];
109
124
  };
110
125
 
111
126
  const MutationsOverTimeTabs: FunctionComponent<MutationOverTimeTabsProps> = ({
@@ -123,19 +138,23 @@ const MutationsOverTimeTabs: FunctionComponent<MutationOverTimeTabsProps> = ({
123
138
  { label: 'Deletions', checked: true, type: 'deletion' },
124
139
  ]);
125
140
 
126
- const filteredData = useMemo(
127
- () =>
128
- getFilteredMutationOverTimeData(
129
- mutationOverTimeData,
130
- overallMutationData,
131
- displayedSegments,
132
- displayedMutationTypes,
133
- proportionInterval,
134
- ),
135
- [mutationOverTimeData, overallMutationData, displayedSegments, displayedMutationTypes, proportionInterval],
136
- );
141
+ const filteredData = useMemo(() => {
142
+ return getFilteredMutationOverTimeData(
143
+ mutationOverTimeData,
144
+ overallMutationData,
145
+ displayedSegments,
146
+ displayedMutationTypes,
147
+ proportionInterval,
148
+ );
149
+ }, [mutationOverTimeData, overallMutationData, displayedSegments, displayedMutationTypes, proportionInterval]);
137
150
 
138
151
  const getTab = (view: View) => {
152
+ if (filteredData === undefined) {
153
+ return {
154
+ title: 'Calculating',
155
+ content: <LoadingDisplay />,
156
+ };
157
+ }
139
158
  switch (view) {
140
159
  case 'grid':
141
160
  return {
@@ -173,7 +192,7 @@ type ToolbarProps = {
173
192
  setDisplayedMutationTypes: (types: DisplayedMutationType[]) => void;
174
193
  proportionInterval: ProportionInterval;
175
194
  setProportionInterval: Dispatch<StateUpdater<ProportionInterval>>;
176
- filteredData: MutationOverTimeDataGroupedByMutation;
195
+ filteredData: MutationOverTimeData;
177
196
  colorScale: ColorScale;
178
197
  setColorScale: Dispatch<StateUpdater<ColorScale>>;
179
198
  };
@@ -217,22 +236,19 @@ const Toolbar: FunctionComponent<ToolbarProps> = ({
217
236
  );
218
237
  };
219
238
 
220
- function getDownloadData(filteredData: MutationOverTimeDataGroupedByMutation) {
221
- const dates = filteredData.getSecondAxisKeys().sort((a, b) => compareTemporal(a, b));
222
-
223
- return filteredData
224
- .getFirstAxisKeys()
225
- .sort(sortSubstitutionsAndDeletions)
226
- .map((mutation) => {
227
- return dates.reduce(
228
- (accumulated, date) => {
229
- const proportion = filteredData.get(mutation, date)?.proportion ?? 0;
230
- return {
231
- ...accumulated,
232
- [date.toString()]: proportion,
233
- };
234
- },
235
- { mutation: mutation.toString() },
236
- );
237
- });
239
+ function getDownloadData(filteredData: MutationOverTimeData) {
240
+ const dates = filteredData.getSecondAxisKeys().map((date) => toTemporalClass(date));
241
+
242
+ return filteredData.getFirstAxisKeys().map((mutation) => {
243
+ return dates.reduce(
244
+ (accumulated, date) => {
245
+ const proportion = filteredData.get(mutation, date)?.proportion ?? 0;
246
+ return {
247
+ ...accumulated,
248
+ [date.dateString]: proportion,
249
+ };
250
+ },
251
+ { mutation: mutation.code },
252
+ );
253
+ });
238
254
  }
@@ -1,5 +1,5 @@
1
1
  import type { NumberOfSequencesDatasets } from '../../query/queryNumberOfSequencesOverTime';
2
- import { generateAllInRange, getMinMaxTemporal, type Temporal } from '../../utils/temporal';
2
+ import { generateAllInRange, getMinMaxTemporal, type TemporalClass } from '../../utils/temporalClass';
3
3
 
4
4
  type TableRow<DateRangeKey extends string> = { [K in DateRangeKey]: string } & { [key: string]: number };
5
5
 
@@ -14,14 +14,14 @@ export const getNumberOfSequencesOverTimeTableData = <DateRangeKey extends strin
14
14
 
15
15
  const allDateRangesThatOccurInData = datasetsWithCountByDate
16
16
  .map(({ content }) => [...content.values()].map((datum) => datum.dateRange))
17
- .reduce((acc, keys) => new Set([...acc, ...keys]), new Set<Temporal | null>());
17
+ .reduce((acc, keys) => new Set([...acc, ...keys]), new Set<TemporalClass | null>());
18
18
 
19
19
  const minMax = getMinMaxTemporal(allDateRangesThatOccurInData);
20
20
  if (minMax === null) {
21
21
  return [];
22
22
  }
23
23
 
24
- const allDateRanges: (Temporal | null)[] = generateAllInRange(minMax.min, minMax.max);
24
+ const allDateRanges: (TemporalClass | null)[] = generateAllInRange(minMax.min, minMax.max);
25
25
 
26
26
  if (allDateRangesThatOccurInData.has(null)) {
27
27
  allDateRanges.unshift(null);
@@ -3,7 +3,7 @@ import { describe, expect, it } from 'vitest';
3
3
  import { getPrevalenceOverTimeTableData } from './getPrevalenceOverTimeTableData';
4
4
  import { type PrevalenceOverTimeData } from '../../query/queryPrevalenceOverTime';
5
5
  import { type TemporalGranularity } from '../../types';
6
- import { TemporalCache, YearMonthDay } from '../../utils/temporal';
6
+ import { TemporalCache, YearMonthDayClass } from '../../utils/temporalClass';
7
7
 
8
8
  describe('getPrevalenceOverTimeTableData', () => {
9
9
  it('should flatten the data to CSV format', () => {
@@ -12,13 +12,13 @@ describe('getPrevalenceOverTimeTableData', () => {
12
12
  displayName: 'Test 1',
13
13
  content: [
14
14
  {
15
- dateRange: new YearMonthDay(2021, 1, 1, TemporalCache.getInstance()),
15
+ dateRange: new YearMonthDayClass(2021, 1, 1, TemporalCache.getInstance()),
16
16
  prevalence: 0.5,
17
17
  count: 100,
18
18
  total: -5,
19
19
  },
20
20
  {
21
- dateRange: new YearMonthDay(2021, 1, 2, TemporalCache.getInstance()),
21
+ dateRange: new YearMonthDayClass(2021, 1, 2, TemporalCache.getInstance()),
22
22
  prevalence: 0.6,
23
23
  count: 200,
24
24
  total: -5,
@@ -29,13 +29,13 @@ describe('getPrevalenceOverTimeTableData', () => {
29
29
  displayName: 'Test 2',
30
30
  content: [
31
31
  {
32
- dateRange: new YearMonthDay(2021, 1, 1, TemporalCache.getInstance()),
32
+ dateRange: new YearMonthDayClass(2021, 1, 1, TemporalCache.getInstance()),
33
33
  prevalence: 0.7,
34
34
  count: 300,
35
35
  total: -5,
36
36
  },
37
37
  {
38
- dateRange: new YearMonthDay(2021, 1, 2, TemporalCache.getInstance()),
38
+ dateRange: new YearMonthDayClass(2021, 1, 2, TemporalCache.getInstance()),
39
39
  prevalence: 0.8,
40
40
  count: 400,
41
41
  total: -5,
@@ -2,7 +2,7 @@ import { Chart, type ChartConfiguration, registerables } from 'chart.js';
2
2
 
3
3
  import { maxInData } from './prevalence-over-time';
4
4
  import { type PrevalenceOverTimeData } from '../../query/queryPrevalenceOverTime';
5
- import { addUnit, minusTemporal } from '../../utils/temporal';
5
+ import { addUnit, minusTemporal } from '../../utils/temporalClass';
6
6
  import { getMinMaxNumber } from '../../utils/utils';
7
7
  import GsChart from '../components/chart';
8
8
  import { LogitScale } from '../shared/charts/LogitScale';
@@ -1,6 +1,6 @@
1
1
  import { Chart, type ChartConfiguration, registerables, type TooltipItem } from 'chart.js';
2
2
 
3
- import { type YearMonthDay } from '../../utils/temporal';
3
+ import { type YearMonthDayClass } from '../../utils/temporalClass';
4
4
  import GsChart from '../components/chart';
5
5
  import { LogitScale } from '../shared/charts/LogitScale';
6
6
  import { singleGraphColorRGBByName } from '../shared/charts/colors';
@@ -10,7 +10,7 @@ import { getYAxisScale, type ScaleType } from '../shared/charts/getYAxisScale';
10
10
  import { formatProportion } from '../shared/table/formatProportion';
11
11
 
12
12
  interface RelativeGrowthAdvantageChartData {
13
- t: YearMonthDay[];
13
+ t: YearMonthDayClass[];
14
14
  proportion: number[];
15
15
  ciLower: number[];
16
16
  ciUpper: number[];