@genspectrum/dashboard-components 0.6.18 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (118) hide show
  1. package/README.md +5 -12
  2. package/custom-elements.json +22 -22
  3. package/dist/assets/mutationOverTimeWorker-BOCXtKzd.js.map +1 -0
  4. package/dist/dashboard-components.js +301 -302
  5. package/dist/dashboard-components.js.map +1 -1
  6. package/dist/genspectrum-components.d.ts +60 -10
  7. package/dist/style.css +3 -2
  8. package/package.json +13 -4
  9. package/src/index.ts +1 -0
  10. package/src/operator/FetchInsertionsOperator.ts +2 -2
  11. package/src/operator/FetchSubstitutionsOrDeletionsOperator.ts +3 -3
  12. package/src/preact/dateRangeSelector/computeInitialValues.spec.ts +53 -38
  13. package/src/preact/dateRangeSelector/computeInitialValues.ts +17 -23
  14. package/src/preact/dateRangeSelector/date-range-selector.stories.tsx +46 -32
  15. package/src/preact/dateRangeSelector/date-range-selector.tsx +24 -26
  16. package/src/preact/dateRangeSelector/dateRangeOption.ts +65 -0
  17. package/src/preact/dateRangeSelector/selectableOptions.ts +17 -66
  18. package/src/preact/mutationComparison/fetchMutationData.spec.ts +3 -3
  19. package/src/preact/mutationComparison/getMutationComparisonTableData.spec.ts +11 -11
  20. package/src/preact/mutationComparison/getMutationComparisonTableData.ts +4 -4
  21. package/src/preact/mutationComparison/mutation-comparison-table.tsx +2 -2
  22. package/src/preact/mutationFilter/mutation-filter.tsx +27 -18
  23. package/src/preact/mutationFilter/parseAndValidateMutation.ts +4 -4
  24. package/src/preact/mutationFilter/parseMutation.spec.ts +17 -17
  25. package/src/preact/mutations/getInsertionsTableData.spec.ts +3 -3
  26. package/src/preact/mutations/getMutationsGridData.spec.ts +9 -9
  27. package/src/preact/mutations/getMutationsTableData.spec.ts +7 -7
  28. package/src/preact/mutations/mutations-insertions-table.tsx +3 -3
  29. package/src/preact/mutations/mutations-table.tsx +3 -3
  30. package/src/preact/mutationsOverTime/MutationOverTimeData.ts +20 -0
  31. package/src/preact/mutationsOverTime/__mockData__/aminoAcidMutationsByDay.ts +45686 -0
  32. package/src/preact/mutationsOverTime/__mockData__/byWeek.ts +58989 -0
  33. package/src/preact/mutationsOverTime/__mockData__/defaultMockData.ts +103991 -0
  34. package/src/preact/mutationsOverTime/__mockData__/mockConversion.ts +54 -0
  35. package/src/preact/mutationsOverTime/__mockData__/showsMessageWhenTooManyMutations.ts +63690 -0
  36. package/src/preact/mutationsOverTime/getFilteredMutationsOverTime.spec.ts +177 -161
  37. package/src/preact/mutationsOverTime/getFilteredMutationsOverTimeData.ts +17 -59
  38. package/src/preact/mutationsOverTime/mutationOverTimeWorker.mock.ts +27 -0
  39. package/src/preact/mutationsOverTime/mutationOverTimeWorker.ts +29 -0
  40. package/src/preact/mutationsOverTime/mutations-over-time-grid.tsx +13 -14
  41. package/src/preact/mutationsOverTime/mutations-over-time.stories.tsx +9 -334
  42. package/src/preact/mutationsOverTime/mutations-over-time.tsx +59 -54
  43. package/src/preact/numberSequencesOverTime/getNumberOfSequencesOverTimeTableData.ts +3 -3
  44. package/src/preact/prevalenceOverTime/getPrevalenceOverTimeTableData.spec.ts +5 -5
  45. package/src/preact/prevalenceOverTime/prevalence-over-time-bubble-chart.tsx +1 -1
  46. package/src/preact/relativeGrowthAdvantage/relative-growth-advantage-chart.tsx +2 -2
  47. package/src/preact/shared/sort/sortInsertions.spec.ts +11 -11
  48. package/src/preact/shared/sort/sortInsertions.ts +2 -2
  49. package/src/preact/shared/sort/sortSubstitutionsAndDeletions.spec.ts +13 -13
  50. package/src/preact/shared/sort/sortSubstitutionsAndDeletions.ts +7 -4
  51. package/src/preact/webWorkers/useWebWorker.ts +51 -0
  52. package/src/preact/webWorkers/workerFunction.ts +14 -0
  53. package/src/query/queryAggregatedDataOverTime.ts +3 -3
  54. package/src/query/queryMutationsOverTime.spec.ts +272 -51
  55. package/src/query/queryMutationsOverTime.ts +114 -47
  56. package/src/query/queryPrevalenceOverTime.ts +2 -2
  57. package/src/query/queryRelativeGrowthAdvantage.ts +3 -3
  58. package/src/types.ts +25 -5
  59. package/src/utils/map2d.spec.ts +79 -12
  60. package/src/utils/map2d.ts +25 -5
  61. package/src/utils/mutations.spec.ts +20 -20
  62. package/src/utils/mutations.ts +80 -17
  63. package/src/utils/sort.ts +5 -2
  64. package/src/utils/temporal.spec.ts +27 -24
  65. package/src/utils/{temporal.ts → temporalClass.ts} +170 -72
  66. package/src/utils/temporalTestHelpers.ts +3 -3
  67. package/src/web-components/input/gs-date-range-selector.stories.ts +16 -28
  68. package/src/web-components/input/gs-date-range-selector.tsx +17 -32
  69. package/src/web-components/introduction.mdx +46 -0
  70. package/src/web-components/visualization/gs-mutations-over-time.stories.ts +6 -699
  71. package/src/web-components/visualization/gs-mutations-over-time.tsx +2 -2
  72. package/standalone-bundle/dashboard-components.js +12011 -12778
  73. package/standalone-bundle/dashboard-components.js.map +1 -1
  74. package/src/preact/mutationsOverTime/__mockData__/aggregated_2024_01.json +0 -13
  75. package/src/preact/mutationsOverTime/__mockData__/aggregated_2024_02.json +0 -13
  76. package/src/preact/mutationsOverTime/__mockData__/aggregated_2024_03.json +0 -13
  77. package/src/preact/mutationsOverTime/__mockData__/aggregated_2024_04.json +0 -13
  78. package/src/preact/mutationsOverTime/__mockData__/aggregated_2024_05.json +0 -13
  79. package/src/preact/mutationsOverTime/__mockData__/aggregated_2024_06.json +0 -13
  80. package/src/preact/mutationsOverTime/__mockData__/aggregated_2024_07.json +0 -13
  81. package/src/preact/mutationsOverTime/__mockData__/aggregated_20_01_2024.json +0 -13
  82. package/src/preact/mutationsOverTime/__mockData__/aggregated_21_01_2024.json +0 -13
  83. package/src/preact/mutationsOverTime/__mockData__/aggregated_22_01_2024.json +0 -13
  84. package/src/preact/mutationsOverTime/__mockData__/aggregated_23_01_2024.json +0 -13
  85. package/src/preact/mutationsOverTime/__mockData__/aggregated_24_01_2024.json +0 -13
  86. package/src/preact/mutationsOverTime/__mockData__/aggregated_25_01_2024.json +0 -13
  87. package/src/preact/mutationsOverTime/__mockData__/aggregated_26_01_2024.json +0 -13
  88. package/src/preact/mutationsOverTime/__mockData__/aggregated_byDay.json +0 -38
  89. package/src/preact/mutationsOverTime/__mockData__/aggregated_byWeek.json +0 -122
  90. package/src/preact/mutationsOverTime/__mockData__/aggregated_date.json +0 -642
  91. package/src/preact/mutationsOverTime/__mockData__/aggregated_tooManyMutations.json +0 -1470
  92. package/src/preact/mutationsOverTime/__mockData__/aggregated_tooManyMutations_total.json +0 -13
  93. package/src/preact/mutationsOverTime/__mockData__/aggregated_week3_2024.json +0 -13
  94. package/src/preact/mutationsOverTime/__mockData__/aggregated_week4_2024.json +0 -13
  95. package/src/preact/mutationsOverTime/__mockData__/aggregated_week5_2024.json +0 -13
  96. package/src/preact/mutationsOverTime/__mockData__/aggregated_week6_2024.json +0 -13
  97. package/src/preact/mutationsOverTime/__mockData__/aminoAcidMutations_20_01_2024.json +0 -6778
  98. package/src/preact/mutationsOverTime/__mockData__/aminoAcidMutations_21_01_2024.json +0 -7129
  99. package/src/preact/mutationsOverTime/__mockData__/aminoAcidMutations_22_01_2024.json +0 -4681
  100. package/src/preact/mutationsOverTime/__mockData__/aminoAcidMutations_23_01_2024.json +0 -10738
  101. package/src/preact/mutationsOverTime/__mockData__/aminoAcidMutations_24_01_2024.json +0 -11710
  102. package/src/preact/mutationsOverTime/__mockData__/aminoAcidMutations_25_01_2024.json +0 -11557
  103. package/src/preact/mutationsOverTime/__mockData__/aminoAcidMutations_26_01_2024.json +0 -8596
  104. package/src/preact/mutationsOverTime/__mockData__/aminoAcidMutations_byDayOverall.json +0 -4726
  105. package/src/preact/mutationsOverTime/__mockData__/nucleotideMutations_2024_01.json +0 -1747
  106. package/src/preact/mutationsOverTime/__mockData__/nucleotideMutations_2024_02.json +0 -1774
  107. package/src/preact/mutationsOverTime/__mockData__/nucleotideMutations_2024_03.json +0 -1819
  108. package/src/preact/mutationsOverTime/__mockData__/nucleotideMutations_2024_04.json +0 -1864
  109. package/src/preact/mutationsOverTime/__mockData__/nucleotideMutations_2024_05.json +0 -1927
  110. package/src/preact/mutationsOverTime/__mockData__/nucleotideMutations_2024_06.json +0 -1864
  111. package/src/preact/mutationsOverTime/__mockData__/nucleotideMutations_2024_07.json +0 -9
  112. package/src/preact/mutationsOverTime/__mockData__/nucleotideMutations_byMonthOverall.json +0 -11143
  113. package/src/preact/mutationsOverTime/__mockData__/nucleotideMutations_byWeekOverall.json +0 -9154
  114. package/src/preact/mutationsOverTime/__mockData__/nucleotideMutations_tooManyMutations.json +0 -16453
  115. package/src/preact/mutationsOverTime/__mockData__/nucleotideMutations_week3_2024.json +0 -8812
  116. package/src/preact/mutationsOverTime/__mockData__/nucleotideMutations_week4_2024.json +0 -9730
  117. package/src/preact/mutationsOverTime/__mockData__/nucleotideMutations_week5_2024.json +0 -9865
  118. 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,21 @@
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';
6
+ import { BaseMutationOverTimeDataMap, type MutationOverTimeDataMap } from './MutationOverTimeData';
4
7
  import { getFilteredMutationOverTimeData } from './getFilteredMutationsOverTimeData';
8
+ import { type MutationOverTimeWorkerResponse } from './mutationOverTimeWorker';
5
9
  import MutationsOverTimeGrid from './mutations-over-time-grid';
6
- import { type Dataset } from '../../operator/Dataset';
10
+ import { type MutationOverTimeQuery } from '../../query/queryMutationsOverTime';
7
11
  import {
8
- type MutationOverTimeDataGroupedByMutation,
9
- queryMutationsOverTimeData,
10
- queryOverallMutationData,
11
- } from '../../query/queryMutationsOverTime';
12
- import {
13
- type DeletionEntry,
14
12
  type LapisFilter,
15
13
  type SequenceType,
16
- type SubstitutionEntry,
14
+ type SubstitutionOrDeletionEntry,
17
15
  type TemporalGranularity,
18
16
  } from '../../types';
19
- import { compareTemporal } from '../../utils/temporal';
17
+ import { type Deletion, type Substitution } from '../../utils/mutations';
18
+ import { toTemporalClass } from '../../utils/temporalClass';
20
19
  import { LapisUrlContext } from '../LapisUrlContext';
21
20
  import { type ColorScale } from '../components/color-scale-selector';
22
21
  import { ColorScaleSelectorDropdown } from '../components/color-scale-selector-dropdown';
@@ -33,8 +32,7 @@ import { ProportionSelectorDropdown } from '../components/proportion-selector-dr
33
32
  import { ResizeContainer } from '../components/resize-container';
34
33
  import { type DisplayedSegment, SegmentSelector, useDisplayedSegments } from '../components/segment-selector';
35
34
  import Tabs from '../components/tabs';
36
- import { sortSubstitutionsAndDeletions } from '../shared/sort/sortSubstitutionsAndDeletions';
37
- import { useQuery } from '../useQuery';
35
+ import { useWebWorker } from '../webWorkers/useWebWorker';
38
36
 
39
37
  export type View = 'grid';
40
38
 
@@ -71,30 +69,36 @@ export const MutationsOverTimeInner: FunctionComponent<MutationsOverTimeInnerPro
71
69
  lapisDateField,
72
70
  }) => {
73
71
  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]);
72
+
73
+ const { data, error, isLoading } = useWebWorker<MutationOverTimeQuery, MutationOverTimeWorkerResponse>(
74
+ {
75
+ lapisFilter,
76
+ sequenceType,
77
+ granularity,
78
+ lapisDateField,
79
+ lapis,
80
+ },
81
+ new MutationOverTimeWorker() as Worker,
82
+ );
81
83
 
82
84
  if (isLoading) {
83
85
  return <LoadingDisplay />;
84
86
  }
85
87
 
86
- if (error !== null) {
88
+ if (error !== undefined) {
87
89
  return <ErrorDisplay error={error} />;
88
90
  }
89
91
 
90
- if (data === null) {
92
+ if (data === null || data === undefined) {
91
93
  return <NoDataDisplay />;
92
94
  }
93
95
 
96
+ const { overallMutationData, mutationOverTimeSerialized } = data;
97
+ const mutationOverTimeData = new BaseMutationOverTimeDataMap(mutationOverTimeSerialized);
94
98
  return (
95
99
  <MutationsOverTimeTabs
96
- overallMutationData={data.overallMutationData}
97
- mutationOverTimeData={data.mutationOverTimeData}
100
+ overallMutationData={overallMutationData}
101
+ mutationOverTimeData={mutationOverTimeData}
98
102
  sequenceType={sequenceType}
99
103
  views={views}
100
104
  />
@@ -102,10 +106,10 @@ export const MutationsOverTimeInner: FunctionComponent<MutationsOverTimeInnerPro
102
106
  };
103
107
 
104
108
  type MutationOverTimeTabsProps = {
105
- mutationOverTimeData: MutationOverTimeDataGroupedByMutation;
109
+ mutationOverTimeData: BaseMutationOverTimeDataMap;
106
110
  sequenceType: SequenceType;
107
111
  views: View[];
108
- overallMutationData: Dataset<SubstitutionEntry | DeletionEntry>;
112
+ overallMutationData: SubstitutionOrDeletionEntry<Substitution, Deletion>[];
109
113
  };
110
114
 
111
115
  const MutationsOverTimeTabs: FunctionComponent<MutationOverTimeTabsProps> = ({
@@ -123,19 +127,23 @@ const MutationsOverTimeTabs: FunctionComponent<MutationOverTimeTabsProps> = ({
123
127
  { label: 'Deletions', checked: true, type: 'deletion' },
124
128
  ]);
125
129
 
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
- );
130
+ const filteredData = useMemo(() => {
131
+ return getFilteredMutationOverTimeData(
132
+ mutationOverTimeData,
133
+ overallMutationData,
134
+ displayedSegments,
135
+ displayedMutationTypes,
136
+ proportionInterval,
137
+ );
138
+ }, [mutationOverTimeData, overallMutationData, displayedSegments, displayedMutationTypes, proportionInterval]);
137
139
 
138
140
  const getTab = (view: View) => {
141
+ if (filteredData === undefined) {
142
+ return {
143
+ title: 'Calculating',
144
+ content: <LoadingDisplay />,
145
+ };
146
+ }
139
147
  switch (view) {
140
148
  case 'grid':
141
149
  return {
@@ -173,7 +181,7 @@ type ToolbarProps = {
173
181
  setDisplayedMutationTypes: (types: DisplayedMutationType[]) => void;
174
182
  proportionInterval: ProportionInterval;
175
183
  setProportionInterval: Dispatch<StateUpdater<ProportionInterval>>;
176
- filteredData: MutationOverTimeDataGroupedByMutation;
184
+ filteredData: MutationOverTimeDataMap;
177
185
  colorScale: ColorScale;
178
186
  setColorScale: Dispatch<StateUpdater<ColorScale>>;
179
187
  };
@@ -217,22 +225,19 @@ const Toolbar: FunctionComponent<ToolbarProps> = ({
217
225
  );
218
226
  };
219
227
 
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
- });
228
+ function getDownloadData(filteredData: MutationOverTimeDataMap) {
229
+ const dates = filteredData.getSecondAxisKeys().map((date) => toTemporalClass(date));
230
+
231
+ return filteredData.getFirstAxisKeys().map((mutation) => {
232
+ return dates.reduce(
233
+ (accumulated, date) => {
234
+ const proportion = filteredData.get(mutation, date)?.proportion ?? 0;
235
+ return {
236
+ ...accumulated,
237
+ [date.dateString]: proportion,
238
+ };
239
+ },
240
+ { mutation: mutation.code },
241
+ );
242
+ });
238
243
  }
@@ -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[];