@genspectrum/dashboard-components 0.6.13 → 0.6.14
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 +29 -0
- package/custom-elements.json +11 -11
- package/dist/dashboard-components.js +8213 -37918
- package/dist/dashboard-components.js.map +1 -1
- package/dist/genspectrum-components.d.ts +7 -7
- package/dist/style.css +1 -1
- package/package.json +7 -6
- package/src/operator/FetchAggregatedOperator.ts +2 -7
- package/src/preact/components/info.tsx +1 -1
- package/src/preact/components/percent-intput.tsx +7 -2
- package/src/preact/components/proportion-selector.tsx +12 -2
- package/src/preact/dateRangeSelector/date-range-selector.tsx +4 -4
- package/src/preact/lineageFilter/lineage-filter.tsx +2 -2
- package/src/preact/locationFilter/location-filter.tsx +2 -2
- package/src/preact/mutationsOverTime/__mockData__/aggregated_2024_01.json +13 -0
- package/src/preact/mutationsOverTime/__mockData__/aggregated_2024_02.json +13 -0
- package/src/preact/mutationsOverTime/__mockData__/aggregated_2024_03.json +13 -0
- package/src/preact/mutationsOverTime/__mockData__/aggregated_2024_04.json +13 -0
- package/src/preact/mutationsOverTime/__mockData__/aggregated_2024_05.json +13 -0
- package/src/preact/mutationsOverTime/__mockData__/aggregated_2024_06.json +13 -0
- package/src/preact/mutationsOverTime/__mockData__/aggregated_2024_07.json +13 -0
- package/src/preact/mutationsOverTime/__mockData__/aggregated_20_01_2024.json +13 -0
- package/src/preact/mutationsOverTime/__mockData__/aggregated_21_01_2024.json +13 -0
- package/src/preact/mutationsOverTime/__mockData__/aggregated_22_01_2024.json +13 -0
- package/src/preact/mutationsOverTime/__mockData__/aggregated_23_01_2024.json +13 -0
- package/src/preact/mutationsOverTime/__mockData__/aggregated_24_01_2024.json +13 -0
- package/src/preact/mutationsOverTime/__mockData__/aggregated_25_01_2024.json +13 -0
- package/src/preact/mutationsOverTime/__mockData__/aggregated_26_01_2024.json +13 -0
- package/src/preact/mutationsOverTime/__mockData__/aggregated_tooManyMutations_total.json +13 -0
- package/src/preact/mutationsOverTime/__mockData__/aggregated_week3_2024.json +13 -0
- package/src/preact/mutationsOverTime/__mockData__/aggregated_week4_2024.json +13 -0
- package/src/preact/mutationsOverTime/__mockData__/aggregated_week5_2024.json +13 -0
- package/src/preact/mutationsOverTime/__mockData__/aggregated_week6_2024.json +13 -0
- package/src/preact/mutationsOverTime/getFilteredMutationsOverTime.spec.ts +56 -8
- package/src/preact/mutationsOverTime/mutations-over-time-grid.tsx +4 -2
- package/src/preact/mutationsOverTime/mutations-over-time.stories.tsx +135 -0
- package/src/preact/prevalenceOverTime/prevalence-over-time.tsx +2 -2
- package/src/preact/textInput/text-input.tsx +2 -2
- package/src/query/queryMutationsOverTime.spec.ts +210 -64
- package/src/query/queryMutationsOverTime.ts +10 -2
- package/src/web-components/input/gs-date-range-selector.tsx +24 -4
- package/src/web-components/input/gs-lineage-filter.tsx +15 -1
- package/src/web-components/input/gs-location-filter.tsx +13 -1
- package/src/web-components/input/gs-mutation-filter.tsx +1 -0
- package/src/web-components/input/gs-text-input.tsx +13 -1
- package/src/web-components/visualization/gs-aggregate.tsx +17 -1
- package/src/web-components/visualization/gs-mutation-comparison.tsx +9 -0
- package/src/web-components/visualization/gs-mutations-over-time.stories.ts +271 -0
- package/src/web-components/visualization/gs-mutations-over-time.tsx +7 -0
- package/src/web-components/visualization/gs-mutations.tsx +11 -5
- package/src/web-components/visualization/gs-number-sequences-over-time.tsx +15 -0
- package/src/web-components/visualization/gs-prevalence-over-time.stories.ts +8 -9
- package/src/web-components/visualization/gs-prevalence-over-time.tsx +26 -8
- package/src/web-components/visualization/gs-relative-growth-advantage.tsx +43 -5
- package/standalone-bundle/dashboard-components.js +30887 -0
- package/standalone-bundle/dashboard-components.js.map +1 -0
|
@@ -56,7 +56,7 @@ const MutationsOverTimeGrid: FunctionComponent<MutationsOverTimeGridProps> = ({
|
|
|
56
56
|
<MutationCell mutation={mutation} />
|
|
57
57
|
</div>
|
|
58
58
|
{dates.map((date, columnIndex) => {
|
|
59
|
-
const value = data.get(mutation, date) ?? { proportion: 0, count: 0 };
|
|
59
|
+
const value = data.get(mutation, date) ?? { proportion: 0, count: 0, totalCount: 0 };
|
|
60
60
|
const tooltipPosition = getTooltipPosition(
|
|
61
61
|
rowIndex,
|
|
62
62
|
shownMutations.length,
|
|
@@ -136,7 +136,9 @@ const ProportionCell: FunctionComponent<{
|
|
|
136
136
|
<p>({timeIntervalDisplay(date)})</p>
|
|
137
137
|
<p>{mutation.code}</p>
|
|
138
138
|
<p>Proportion: {formatProportion(value.proportion)}</p>
|
|
139
|
-
<p>
|
|
139
|
+
<p>
|
|
140
|
+
Count: {value.count} / {value.totalCount} total
|
|
141
|
+
</p>
|
|
140
142
|
</div>
|
|
141
143
|
);
|
|
142
144
|
|
|
@@ -1,8 +1,16 @@
|
|
|
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';
|
|
4
11
|
import aggregated_date from './__mockData__/aggregated_date.json';
|
|
5
12
|
import aggregated_tooManyMutations from './__mockData__/aggregated_tooManyMutations.json';
|
|
13
|
+
import aggregated_tooManyMutations_total from './__mockData__/aggregated_tooManyMutations_total.json';
|
|
6
14
|
import nucleotideMutation_01 from './__mockData__/nucleotideMutations_2024_01.json';
|
|
7
15
|
import nucleotideMutation_02 from './__mockData__/nucleotideMutations_2024_02.json';
|
|
8
16
|
import nucleotideMutation_03 from './__mockData__/nucleotideMutations_2024_03.json';
|
|
@@ -91,6 +99,118 @@ export const Default: StoryObj<MutationsOverTimeProps> = {
|
|
|
91
99
|
body: aggregated_date,
|
|
92
100
|
},
|
|
93
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
|
+
},
|
|
94
214
|
{
|
|
95
215
|
matcher: {
|
|
96
216
|
name: 'nucleotideMutations_overall',
|
|
@@ -253,6 +373,21 @@ export const ShowsMessageWhenTooManyMutations: StoryObj<MutationsOverTimeProps>
|
|
|
253
373
|
body: aggregated_tooManyMutations,
|
|
254
374
|
},
|
|
255
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
|
+
},
|
|
256
391
|
{
|
|
257
392
|
matcher: {
|
|
258
393
|
name: 'nucleotideMutations',
|
|
@@ -38,8 +38,8 @@ export interface PrevalenceOverTimeProps {
|
|
|
38
38
|
confidenceIntervalMethods: ConfidenceIntervalMethod[];
|
|
39
39
|
lapisDateField: string;
|
|
40
40
|
pageSize: boolean | number;
|
|
41
|
-
yAxisMaxLinear
|
|
42
|
-
yAxisMaxLogarithmic
|
|
41
|
+
yAxisMaxLinear: AxisMax;
|
|
42
|
+
yAxisMaxLogarithmic: AxisMax;
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
export const PrevalenceOverTime: FunctionComponent<PrevalenceOverTimeProps> = (componentProps) => {
|
|
@@ -12,8 +12,8 @@ import { useQuery } from '../useQuery';
|
|
|
12
12
|
|
|
13
13
|
export interface TextInputInnerProps {
|
|
14
14
|
lapisField: string;
|
|
15
|
-
placeholderText
|
|
16
|
-
initialValue
|
|
15
|
+
placeholderText: string;
|
|
16
|
+
initialValue: string;
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
export interface TextInputProps extends TextInputInnerProps {
|
|
@@ -8,15 +8,44 @@ describe('queryMutationsOverTime', () => {
|
|
|
8
8
|
const lapisFilter = { field1: 'value1', field2: 'value2' };
|
|
9
9
|
const dateField = 'dateField';
|
|
10
10
|
|
|
11
|
-
lapisRequestMocks.
|
|
12
|
-
{ ...lapisFilter, fields: [dateField] },
|
|
11
|
+
lapisRequestMocks.multipleAggregated([
|
|
13
12
|
{
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
13
|
+
body: { ...lapisFilter, fields: [dateField] },
|
|
14
|
+
response: {
|
|
15
|
+
data: [
|
|
16
|
+
{ count: 1, [dateField]: '2023-01-01' },
|
|
17
|
+
{ count: 2, [dateField]: '2023-01-03' },
|
|
18
|
+
],
|
|
19
|
+
},
|
|
18
20
|
},
|
|
19
|
-
|
|
21
|
+
{
|
|
22
|
+
body: {
|
|
23
|
+
...lapisFilter,
|
|
24
|
+
dateFieldFrom: '2023-01-01',
|
|
25
|
+
dateFieldTo: '2023-01-01',
|
|
26
|
+
fields: [],
|
|
27
|
+
},
|
|
28
|
+
response: { data: [{ count: 11 }] },
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
body: {
|
|
32
|
+
...lapisFilter,
|
|
33
|
+
dateFieldFrom: '2023-01-02',
|
|
34
|
+
dateFieldTo: '2023-01-02',
|
|
35
|
+
fields: [],
|
|
36
|
+
},
|
|
37
|
+
response: { data: [{ count: 12 }] },
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
body: {
|
|
41
|
+
...lapisFilter,
|
|
42
|
+
dateFieldFrom: '2023-01-03',
|
|
43
|
+
dateFieldTo: '2023-01-03',
|
|
44
|
+
fields: [],
|
|
45
|
+
},
|
|
46
|
+
response: { data: [{ count: 13 }] },
|
|
47
|
+
},
|
|
48
|
+
]);
|
|
20
49
|
|
|
21
50
|
lapisRequestMocks.multipleMutations(
|
|
22
51
|
[
|
|
@@ -53,16 +82,16 @@ describe('queryMutationsOverTime', () => {
|
|
|
53
82
|
|
|
54
83
|
const result = await queryMutationsOverTimeData(lapisFilter, 'nucleotide', DUMMY_LAPIS_URL, dateField, 'day');
|
|
55
84
|
|
|
56
|
-
expect(result.getAsArray({ count: 0, proportion: 0 })).to.deep.equal([
|
|
85
|
+
expect(result.getAsArray({ count: 0, proportion: 0, totalCount: 0 })).to.deep.equal([
|
|
57
86
|
[
|
|
58
|
-
{ proportion: 0.1, count: 1 },
|
|
59
|
-
{ proportion: 0.2, count: 2 },
|
|
60
|
-
{ proportion: 0.3, count: 3 },
|
|
87
|
+
{ proportion: 0.1, count: 1, totalCount: 11 },
|
|
88
|
+
{ proportion: 0.2, count: 2, totalCount: 12 },
|
|
89
|
+
{ proportion: 0.3, count: 3, totalCount: 13 },
|
|
61
90
|
],
|
|
62
91
|
[
|
|
63
|
-
{ proportion: 0.4, count: 4 },
|
|
64
|
-
{ proportion: 0, count: 0 },
|
|
65
|
-
{ proportion: 0, count: 0 },
|
|
92
|
+
{ proportion: 0.4, count: 4, totalCount: 11 },
|
|
93
|
+
{ proportion: 0, count: 0, totalCount: 0 },
|
|
94
|
+
{ proportion: 0, count: 0, totalCount: 0 },
|
|
66
95
|
],
|
|
67
96
|
]);
|
|
68
97
|
|
|
@@ -80,15 +109,44 @@ describe('queryMutationsOverTime', () => {
|
|
|
80
109
|
const lapisFilter = { field1: 'value1', field2: 'value2' };
|
|
81
110
|
const dateField = 'dateField';
|
|
82
111
|
|
|
83
|
-
lapisRequestMocks.
|
|
84
|
-
{
|
|
112
|
+
lapisRequestMocks.multipleAggregated([
|
|
113
|
+
{
|
|
114
|
+
body: { ...lapisFilter, fields: [dateField] },
|
|
115
|
+
response: {
|
|
116
|
+
data: [
|
|
117
|
+
{ count: 1, [dateField]: '2023-01-01' },
|
|
118
|
+
{ count: 2, [dateField]: '2023-01-03' },
|
|
119
|
+
],
|
|
120
|
+
},
|
|
121
|
+
},
|
|
85
122
|
{
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
123
|
+
body: {
|
|
124
|
+
...lapisFilter,
|
|
125
|
+
dateFieldFrom: '2023-01-01',
|
|
126
|
+
dateFieldTo: '2023-01-01',
|
|
127
|
+
fields: [],
|
|
128
|
+
},
|
|
129
|
+
response: { data: [{ count: 11 }] },
|
|
90
130
|
},
|
|
91
|
-
|
|
131
|
+
{
|
|
132
|
+
body: {
|
|
133
|
+
...lapisFilter,
|
|
134
|
+
dateFieldFrom: '2023-01-02',
|
|
135
|
+
dateFieldTo: '2023-01-02',
|
|
136
|
+
fields: [],
|
|
137
|
+
},
|
|
138
|
+
response: { data: [{ count: 12 }] },
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
body: {
|
|
142
|
+
...lapisFilter,
|
|
143
|
+
dateFieldFrom: '2023-01-03',
|
|
144
|
+
dateFieldTo: '2023-01-03',
|
|
145
|
+
fields: [],
|
|
146
|
+
},
|
|
147
|
+
response: { data: [{ count: 13 }] },
|
|
148
|
+
},
|
|
149
|
+
]);
|
|
92
150
|
|
|
93
151
|
lapisRequestMocks.multipleMutations(
|
|
94
152
|
[
|
|
@@ -125,16 +183,16 @@ describe('queryMutationsOverTime', () => {
|
|
|
125
183
|
|
|
126
184
|
const result = await queryMutationsOverTimeData(lapisFilter, 'nucleotide', DUMMY_LAPIS_URL, dateField, 'day');
|
|
127
185
|
|
|
128
|
-
expect(result.getAsArray({ count: 0, proportion: 0 })).to.deep.equal([
|
|
186
|
+
expect(result.getAsArray({ count: 0, proportion: 0, totalCount: 0 })).to.deep.equal([
|
|
129
187
|
[
|
|
130
|
-
{ proportion: 0.1, count: 1 },
|
|
131
|
-
{ proportion: 0.3, count: 3 },
|
|
132
|
-
{ proportion: 0, count: 0 },
|
|
188
|
+
{ proportion: 0.1, count: 1, totalCount: 11 },
|
|
189
|
+
{ proportion: 0.3, count: 3, totalCount: 13 },
|
|
190
|
+
{ proportion: 0, count: 0, totalCount: 0 },
|
|
133
191
|
],
|
|
134
192
|
[
|
|
135
|
-
{ proportion: 0.4, count: 4 },
|
|
136
|
-
{ proportion: 0, count: 0 },
|
|
137
|
-
{ proportion: 0, count: 0 },
|
|
193
|
+
{ proportion: 0.4, count: 4, totalCount: 11 },
|
|
194
|
+
{ proportion: 0, count: 0, totalCount: 0 },
|
|
195
|
+
{ proportion: 0, count: 0, totalCount: 0 },
|
|
138
196
|
],
|
|
139
197
|
]);
|
|
140
198
|
|
|
@@ -152,15 +210,44 @@ describe('queryMutationsOverTime', () => {
|
|
|
152
210
|
const lapisFilter = { field1: 'value1', field2: 'value2' };
|
|
153
211
|
const dateField = 'dateField';
|
|
154
212
|
|
|
155
|
-
lapisRequestMocks.
|
|
156
|
-
{
|
|
213
|
+
lapisRequestMocks.multipleAggregated([
|
|
214
|
+
{
|
|
215
|
+
body: { ...lapisFilter, fields: [dateField] },
|
|
216
|
+
response: {
|
|
217
|
+
data: [
|
|
218
|
+
{ count: 1, [dateField]: '2023-01-01' },
|
|
219
|
+
{ count: 2, [dateField]: '2023-01-03' },
|
|
220
|
+
],
|
|
221
|
+
},
|
|
222
|
+
},
|
|
157
223
|
{
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
224
|
+
body: {
|
|
225
|
+
...lapisFilter,
|
|
226
|
+
dateFieldFrom: '2023-01-01',
|
|
227
|
+
dateFieldTo: '2023-01-01',
|
|
228
|
+
fields: [],
|
|
229
|
+
},
|
|
230
|
+
response: { data: [{ count: 11 }] },
|
|
162
231
|
},
|
|
163
|
-
|
|
232
|
+
{
|
|
233
|
+
body: {
|
|
234
|
+
...lapisFilter,
|
|
235
|
+
dateFieldFrom: '2023-01-02',
|
|
236
|
+
dateFieldTo: '2023-01-02',
|
|
237
|
+
fields: [],
|
|
238
|
+
},
|
|
239
|
+
response: { data: [{ count: 12 }] },
|
|
240
|
+
},
|
|
241
|
+
{
|
|
242
|
+
body: {
|
|
243
|
+
...lapisFilter,
|
|
244
|
+
dateFieldFrom: '2023-01-03',
|
|
245
|
+
dateFieldTo: '2023-01-03',
|
|
246
|
+
fields: [],
|
|
247
|
+
},
|
|
248
|
+
response: { data: [{ count: 13 }] },
|
|
249
|
+
},
|
|
250
|
+
]);
|
|
164
251
|
|
|
165
252
|
lapisRequestMocks.multipleMutations(
|
|
166
253
|
[
|
|
@@ -197,7 +284,7 @@ describe('queryMutationsOverTime', () => {
|
|
|
197
284
|
|
|
198
285
|
const result = await queryMutationsOverTimeData(lapisFilter, 'nucleotide', DUMMY_LAPIS_URL, dateField, 'day');
|
|
199
286
|
|
|
200
|
-
expect(result.getAsArray({ count: 0, proportion: 0 })).to.deep.equal([]);
|
|
287
|
+
expect(result.getAsArray({ count: 0, proportion: 0, totalCount: 0 })).to.deep.equal([]);
|
|
201
288
|
expect(result.getFirstAxisKeys()).to.deep.equal([]);
|
|
202
289
|
expect(result.getSecondAxisKeys()).to.deep.equal([]);
|
|
203
290
|
});
|
|
@@ -206,15 +293,35 @@ describe('queryMutationsOverTime', () => {
|
|
|
206
293
|
const dateField = 'dateField';
|
|
207
294
|
const lapisFilter = { field1: 'value1', field2: 'value2', [`${dateField}From`]: '2023-01-02' };
|
|
208
295
|
|
|
209
|
-
lapisRequestMocks.
|
|
210
|
-
{
|
|
296
|
+
lapisRequestMocks.multipleAggregated([
|
|
297
|
+
{
|
|
298
|
+
body: { ...lapisFilter, fields: [dateField] },
|
|
299
|
+
response: {
|
|
300
|
+
data: [
|
|
301
|
+
{ count: 1, [dateField]: '2023-01-01' },
|
|
302
|
+
{ count: 2, [dateField]: '2023-01-03' },
|
|
303
|
+
],
|
|
304
|
+
},
|
|
305
|
+
},
|
|
211
306
|
{
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
307
|
+
body: {
|
|
308
|
+
...lapisFilter,
|
|
309
|
+
dateFieldFrom: '2023-01-02',
|
|
310
|
+
dateFieldTo: '2023-01-02',
|
|
311
|
+
fields: [],
|
|
312
|
+
},
|
|
313
|
+
response: { data: [{ count: 11 }] },
|
|
216
314
|
},
|
|
217
|
-
|
|
315
|
+
{
|
|
316
|
+
body: {
|
|
317
|
+
...lapisFilter,
|
|
318
|
+
dateFieldFrom: '2023-01-03',
|
|
319
|
+
dateFieldTo: '2023-01-03',
|
|
320
|
+
fields: [],
|
|
321
|
+
},
|
|
322
|
+
response: { data: [{ count: 12 }] },
|
|
323
|
+
},
|
|
324
|
+
]);
|
|
218
325
|
|
|
219
326
|
lapisRequestMocks.multipleMutations(
|
|
220
327
|
[
|
|
@@ -242,10 +349,10 @@ describe('queryMutationsOverTime', () => {
|
|
|
242
349
|
|
|
243
350
|
const result = await queryMutationsOverTimeData(lapisFilter, 'nucleotide', DUMMY_LAPIS_URL, dateField, 'day');
|
|
244
351
|
|
|
245
|
-
expect(result.getAsArray({ count: 0, proportion: 0 })).to.deep.equal([
|
|
352
|
+
expect(result.getAsArray({ count: 0, proportion: 0, totalCount: 0 })).to.deep.equal([
|
|
246
353
|
[
|
|
247
|
-
{ proportion: 0.2, count: 2 },
|
|
248
|
-
{ proportion: 0.3, count: 3 },
|
|
354
|
+
{ proportion: 0.2, count: 2, totalCount: 11 },
|
|
355
|
+
{ proportion: 0.3, count: 3, totalCount: 12 },
|
|
249
356
|
],
|
|
250
357
|
]);
|
|
251
358
|
|
|
@@ -261,15 +368,35 @@ describe('queryMutationsOverTime', () => {
|
|
|
261
368
|
const dateField = 'dateField';
|
|
262
369
|
const lapisFilter = { field1: 'value1', field2: 'value2', [`${dateField}To`]: '2023-01-02' };
|
|
263
370
|
|
|
264
|
-
lapisRequestMocks.
|
|
265
|
-
{ ...lapisFilter, fields: [dateField] },
|
|
371
|
+
lapisRequestMocks.multipleAggregated([
|
|
266
372
|
{
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
373
|
+
body: { ...lapisFilter, fields: [dateField] },
|
|
374
|
+
response: {
|
|
375
|
+
data: [
|
|
376
|
+
{ count: 1, [dateField]: '2023-01-01' },
|
|
377
|
+
{ count: 2, [dateField]: '2023-01-03' },
|
|
378
|
+
],
|
|
379
|
+
},
|
|
271
380
|
},
|
|
272
|
-
|
|
381
|
+
{
|
|
382
|
+
body: {
|
|
383
|
+
...lapisFilter,
|
|
384
|
+
dateFieldFrom: '2023-01-01',
|
|
385
|
+
dateFieldTo: '2023-01-01',
|
|
386
|
+
fields: [],
|
|
387
|
+
},
|
|
388
|
+
response: { data: [{ count: 11 }] },
|
|
389
|
+
},
|
|
390
|
+
{
|
|
391
|
+
body: {
|
|
392
|
+
...lapisFilter,
|
|
393
|
+
dateFieldFrom: '2023-01-02',
|
|
394
|
+
dateFieldTo: '2023-01-02',
|
|
395
|
+
fields: [],
|
|
396
|
+
},
|
|
397
|
+
response: { data: [{ count: 12 }] },
|
|
398
|
+
},
|
|
399
|
+
]);
|
|
273
400
|
|
|
274
401
|
lapisRequestMocks.multipleMutations(
|
|
275
402
|
[
|
|
@@ -297,10 +424,10 @@ describe('queryMutationsOverTime', () => {
|
|
|
297
424
|
|
|
298
425
|
const result = await queryMutationsOverTimeData(lapisFilter, 'nucleotide', DUMMY_LAPIS_URL, dateField, 'day');
|
|
299
426
|
|
|
300
|
-
expect(result.getAsArray({ count: 0, proportion: 0 })).to.deep.equal([
|
|
427
|
+
expect(result.getAsArray({ count: 0, proportion: 0, totalCount: 0 })).to.deep.equal([
|
|
301
428
|
[
|
|
302
|
-
{ proportion: 0.1, count: 1 },
|
|
303
|
-
{ proportion: 0.2, count: 2 },
|
|
429
|
+
{ proportion: 0.1, count: 1, totalCount: 11 },
|
|
430
|
+
{ proportion: 0.2, count: 2, totalCount: 12 },
|
|
304
431
|
],
|
|
305
432
|
]);
|
|
306
433
|
|
|
@@ -316,15 +443,26 @@ describe('queryMutationsOverTime', () => {
|
|
|
316
443
|
const dateField = 'dateField';
|
|
317
444
|
const lapisFilter = { field1: 'value1', field2: 'value2', [dateField]: '2023-01-02' };
|
|
318
445
|
|
|
319
|
-
lapisRequestMocks.
|
|
320
|
-
{ ...lapisFilter, fields: [dateField] },
|
|
446
|
+
lapisRequestMocks.multipleAggregated([
|
|
321
447
|
{
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
448
|
+
body: { ...lapisFilter, fields: [dateField] },
|
|
449
|
+
response: {
|
|
450
|
+
data: [
|
|
451
|
+
{ count: 1, [dateField]: '2023-01-01' },
|
|
452
|
+
{ count: 2, [dateField]: '2023-01-03' },
|
|
453
|
+
],
|
|
454
|
+
},
|
|
326
455
|
},
|
|
327
|
-
|
|
456
|
+
{
|
|
457
|
+
body: {
|
|
458
|
+
...lapisFilter,
|
|
459
|
+
dateFieldFrom: '2023-01-02',
|
|
460
|
+
dateFieldTo: '2023-01-02',
|
|
461
|
+
fields: [],
|
|
462
|
+
},
|
|
463
|
+
response: { data: [{ count: 11 }] },
|
|
464
|
+
},
|
|
465
|
+
]);
|
|
328
466
|
|
|
329
467
|
lapisRequestMocks.multipleMutations(
|
|
330
468
|
[
|
|
@@ -343,7 +481,15 @@ describe('queryMutationsOverTime', () => {
|
|
|
343
481
|
|
|
344
482
|
const result = await queryMutationsOverTimeData(lapisFilter, 'nucleotide', DUMMY_LAPIS_URL, dateField, 'day');
|
|
345
483
|
|
|
346
|
-
expect(result.getAsArray({ count: 0, proportion: 0 })).to.deep.equal([
|
|
484
|
+
expect(result.getAsArray({ count: 0, proportion: 0, totalCount: 0 })).to.deep.equal([
|
|
485
|
+
[
|
|
486
|
+
{
|
|
487
|
+
proportion: 0.2,
|
|
488
|
+
count: 2,
|
|
489
|
+
totalCount: 11,
|
|
490
|
+
},
|
|
491
|
+
],
|
|
492
|
+
]);
|
|
347
493
|
|
|
348
494
|
const sequences = result.getFirstAxisKeys();
|
|
349
495
|
expect(sequences[0].code).toBe('sequenceName:A123T');
|
|
@@ -25,9 +25,10 @@ import {
|
|
|
25
25
|
export type MutationOverTimeData = {
|
|
26
26
|
date: Temporal;
|
|
27
27
|
mutations: SubstitutionOrDeletionEntry[];
|
|
28
|
+
totalCount: number;
|
|
28
29
|
};
|
|
29
30
|
|
|
30
|
-
export type MutationOverTimeMutationValue = { proportion: number; count: number };
|
|
31
|
+
export type MutationOverTimeMutationValue = { proportion: number; count: number; totalCount: number };
|
|
31
32
|
export type MutationOverTimeDataGroupedByMutation = Map2d<
|
|
32
33
|
Substitution | Deletion,
|
|
33
34
|
Temporal,
|
|
@@ -75,9 +76,11 @@ export async function queryMutationsOverTimeData(
|
|
|
75
76
|
};
|
|
76
77
|
|
|
77
78
|
const data = await fetchAndPrepareSubstitutionsOrDeletions(filter, sequenceType).evaluate(lapis, signal);
|
|
79
|
+
const totalCountQuery = await getTotalNumberOfSequencesInDateRange(filter).evaluate(lapis, signal);
|
|
78
80
|
return {
|
|
79
81
|
date,
|
|
80
82
|
mutations: data.content,
|
|
83
|
+
totalCount: totalCountQuery.content[0].count,
|
|
81
84
|
};
|
|
82
85
|
});
|
|
83
86
|
|
|
@@ -164,6 +167,7 @@ export function groupByMutation(data: MutationOverTimeData[]) {
|
|
|
164
167
|
dataArray.set(mutationEntry.mutation, mutationData.date, {
|
|
165
168
|
count: mutationEntry.count,
|
|
166
169
|
proportion: mutationEntry.proportion,
|
|
170
|
+
totalCount: mutationData.totalCount,
|
|
167
171
|
});
|
|
168
172
|
});
|
|
169
173
|
});
|
|
@@ -181,8 +185,12 @@ function addZeroValuesForDatesWithNoMutationData(
|
|
|
181
185
|
const someMutation = dataArray.getFirstAxisKeys()[0];
|
|
182
186
|
data.forEach((mutationData) => {
|
|
183
187
|
if (mutationData.mutations.length === 0) {
|
|
184
|
-
dataArray.set(someMutation, mutationData.date, { count: 0, proportion: 0 });
|
|
188
|
+
dataArray.set(someMutation, mutationData.date, { count: 0, proportion: 0, totalCount: 0 });
|
|
185
189
|
}
|
|
186
190
|
});
|
|
187
191
|
}
|
|
188
192
|
}
|
|
193
|
+
|
|
194
|
+
function getTotalNumberOfSequencesInDateRange(filter: LapisFilter) {
|
|
195
|
+
return new FetchAggregatedOperator<{ count: number }>(filter);
|
|
196
|
+
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { customElement, property } from 'lit/decorators.js';
|
|
2
2
|
|
|
3
|
-
import { DateRangeSelector } from '../../preact/dateRangeSelector/date-range-selector';
|
|
4
|
-
import { type CustomSelectOption, type PresetOptionValues } from '../../preact/dateRangeSelector/selectableOptions';
|
|
3
|
+
import { DateRangeSelector, type DateRangeSelectorProps } from '../../preact/dateRangeSelector/date-range-selector';
|
|
5
4
|
import { type Equals, type Expect } from '../../utils/typeAssertions';
|
|
6
5
|
import { PreactLitAdapter } from '../PreactLitAdapter';
|
|
7
6
|
|
|
@@ -129,9 +128,30 @@ declare global {
|
|
|
129
128
|
|
|
130
129
|
/* eslint-disable @typescript-eslint/no-unused-vars, no-unused-vars */
|
|
131
130
|
type CustomSelectOptionsMatches = Expect<
|
|
132
|
-
Equals<
|
|
131
|
+
Equals<
|
|
132
|
+
typeof DateRangeSelectorComponent.prototype.customSelectOptions,
|
|
133
|
+
DateRangeSelectorProps<string>['customSelectOptions']
|
|
134
|
+
>
|
|
135
|
+
>;
|
|
136
|
+
type EarliestDateMatches = Expect<
|
|
137
|
+
Equals<typeof DateRangeSelectorComponent.prototype.earliestDate, DateRangeSelectorProps<string>['earliestDate']>
|
|
133
138
|
>;
|
|
134
139
|
type InitialValueMatches = Expect<
|
|
135
|
-
Equals<typeof DateRangeSelectorComponent.prototype.initialValue,
|
|
140
|
+
Equals<typeof DateRangeSelectorComponent.prototype.initialValue, DateRangeSelectorProps<string>['initialValue']>
|
|
141
|
+
>;
|
|
142
|
+
type InitialDateFromMatches = Expect<
|
|
143
|
+
Equals<
|
|
144
|
+
typeof DateRangeSelectorComponent.prototype.initialDateFrom,
|
|
145
|
+
DateRangeSelectorProps<string>['initialDateFrom']
|
|
146
|
+
>
|
|
147
|
+
>;
|
|
148
|
+
type InitialDateToMatches = Expect<
|
|
149
|
+
Equals<typeof DateRangeSelectorComponent.prototype.initialDateTo, DateRangeSelectorProps<string>['initialDateTo']>
|
|
150
|
+
>;
|
|
151
|
+
type WidthMatches = Expect<
|
|
152
|
+
Equals<typeof DateRangeSelectorComponent.prototype.width, DateRangeSelectorProps<string>['width']>
|
|
153
|
+
>;
|
|
154
|
+
type DateColumnMatches = Expect<
|
|
155
|
+
Equals<typeof DateRangeSelectorComponent.prototype.dateColumn, DateRangeSelectorProps<string>['dateColumn']>
|
|
136
156
|
>;
|
|
137
157
|
/* eslint-enable @typescript-eslint/no-unused-vars, no-unused-vars */
|