@genspectrum/dashboard-components 0.6.4 → 0.6.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/custom-elements.json +1 -1
- package/dist/dashboard-components.js +44 -37
- package/dist/dashboard-components.js.map +1 -1
- package/dist/genspectrum-components.d.ts +13 -7
- package/dist/style.css +3 -0
- package/package.json +1 -1
- package/src/preact/mutationsOverTime/__mockData__/aggregated_tooManyMutations.json +1470 -0
- package/src/preact/mutationsOverTime/__mockData__/nucleotideMutations_tooManyMutations.json +16453 -0
- package/src/preact/mutationsOverTime/mutations-over-time-grid.tsx +41 -40
- package/src/preact/mutationsOverTime/mutations-over-time.stories.tsx +62 -8
- package/src/web-components/visualization/gs-mutations-over-time.tsx +11 -5
|
@@ -6,7 +6,6 @@ import {
|
|
|
6
6
|
} from '../../query/queryMutationsOverTime';
|
|
7
7
|
import { type Deletion, type Substitution } from '../../utils/mutations';
|
|
8
8
|
import { compareTemporal, type Temporal, YearMonthDay } from '../../utils/temporal';
|
|
9
|
-
import { UserFacingError } from '../components/error-display';
|
|
10
9
|
import Tooltip from '../components/tooltip';
|
|
11
10
|
import { singleGraphColorRGBByName } from '../shared/charts/colors';
|
|
12
11
|
import { formatProportion } from '../shared/table/formatProportion';
|
|
@@ -18,49 +17,51 @@ export interface MutationsOverTimeGridProps {
|
|
|
18
17
|
const MAX_NUMBER_OF_GRID_ROWS = 100;
|
|
19
18
|
|
|
20
19
|
const MutationsOverTimeGrid: FunctionComponent<MutationsOverTimeGridProps> = ({ data }) => {
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
throw new UserFacingError(
|
|
24
|
-
'Too many mutations',
|
|
25
|
-
`The dataset contains ${mutations.length} mutations. ` +
|
|
26
|
-
`Please adapt the filters to reduce the number to below ${MAX_NUMBER_OF_GRID_ROWS}.`,
|
|
27
|
-
);
|
|
28
|
-
}
|
|
20
|
+
const allMutations = data.getFirstAxisKeys();
|
|
21
|
+
const shownMutations = allMutations.slice(0, MAX_NUMBER_OF_GRID_ROWS);
|
|
29
22
|
|
|
30
23
|
const dates = data.getSecondAxisKeys().sort((a, b) => compareTemporal(a, b));
|
|
31
24
|
|
|
32
25
|
return (
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
{
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
26
|
+
<>
|
|
27
|
+
{allMutations.length > MAX_NUMBER_OF_GRID_ROWS && (
|
|
28
|
+
<div className='pl-2'>
|
|
29
|
+
Showing {MAX_NUMBER_OF_GRID_ROWS} of {allMutations.length} mutations. You can narrow the filter to
|
|
30
|
+
reduce the number of mutations.
|
|
31
|
+
</div>
|
|
32
|
+
)}
|
|
33
|
+
<div
|
|
34
|
+
style={{
|
|
35
|
+
display: 'grid',
|
|
36
|
+
gridTemplateRows: `repeat(${shownMutations.length}, 24px)`,
|
|
37
|
+
gridTemplateColumns: `8rem repeat(${dates.length}, minmax(1.5rem, 1fr))`,
|
|
38
|
+
}}
|
|
39
|
+
>
|
|
40
|
+
{shownMutations.map((mutation, i) => {
|
|
41
|
+
return (
|
|
42
|
+
<Fragment key={`fragment-${mutation.toString()}`}>
|
|
43
|
+
<div
|
|
44
|
+
key={`mutation-${mutation.toString()}`}
|
|
45
|
+
style={{ gridRowStart: i + 1, gridColumnStart: 1 }}
|
|
46
|
+
>
|
|
47
|
+
<MutationCell mutation={mutation} />
|
|
48
|
+
</div>
|
|
49
|
+
{dates.map((date, j) => {
|
|
50
|
+
const value = data.get(mutation, date) ?? { proportion: 0, count: 0 };
|
|
51
|
+
return (
|
|
52
|
+
<div
|
|
53
|
+
style={{ gridRowStart: i + 1, gridColumnStart: j + 2 }}
|
|
54
|
+
key={`${mutation.toString()}-${date.toString()}`}
|
|
55
|
+
>
|
|
56
|
+
<ProportionCell value={value} date={date} mutation={mutation} />
|
|
57
|
+
</div>
|
|
58
|
+
);
|
|
59
|
+
})}
|
|
60
|
+
</Fragment>
|
|
61
|
+
);
|
|
62
|
+
})}
|
|
63
|
+
</div>
|
|
64
|
+
</>
|
|
64
65
|
);
|
|
65
66
|
};
|
|
66
67
|
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { type Meta, type StoryObj } from '@storybook/preact';
|
|
2
|
+
import { expect, waitFor } from '@storybook/test';
|
|
2
3
|
|
|
3
4
|
import aggregated_date from './__mockData__/aggregated_date.json';
|
|
5
|
+
import aggregated_tooManyMutations from './__mockData__/aggregated_tooManyMutations.json';
|
|
4
6
|
import nucleotideMutation_01 from './__mockData__/nucleotideMutations_2024_01.json';
|
|
5
7
|
import nucleotideMutation_02 from './__mockData__/nucleotideMutations_2024_02.json';
|
|
6
8
|
import nucleotideMutation_03 from './__mockData__/nucleotideMutations_2024_03.json';
|
|
@@ -8,6 +10,7 @@ import nucleotideMutation_04 from './__mockData__/nucleotideMutations_2024_04.js
|
|
|
8
10
|
import nucleotideMutation_05 from './__mockData__/nucleotideMutations_2024_05.json';
|
|
9
11
|
import nucleotideMutation_06 from './__mockData__/nucleotideMutations_2024_06.json';
|
|
10
12
|
import nucleotideMutation_07 from './__mockData__/nucleotideMutations_2024_07.json';
|
|
13
|
+
import nucleotideMutation_tooManyMutations from './__mockData__/nucleotideMutations_tooManyMutations.json';
|
|
11
14
|
import { MutationsOverTime, type MutationsOverTimeProps } from './mutations-over-time';
|
|
12
15
|
import { AGGREGATED_ENDPOINT, LAPIS_URL, NUCLEOTIDE_MUTATIONS_ENDPOINT } from '../../constants';
|
|
13
16
|
import referenceGenome from '../../lapisApi/__mockData__/referenceGenome.json';
|
|
@@ -95,7 +98,7 @@ export const Default: StoryObj<MutationsOverTimeProps> = {
|
|
|
95
98
|
pangoLineage: 'JN.1*',
|
|
96
99
|
dateFrom: '2024-01-01',
|
|
97
100
|
dateTo: '2024-01-31',
|
|
98
|
-
minProportion: 0,
|
|
101
|
+
minProportion: 0.001,
|
|
99
102
|
},
|
|
100
103
|
},
|
|
101
104
|
response: {
|
|
@@ -111,7 +114,7 @@ export const Default: StoryObj<MutationsOverTimeProps> = {
|
|
|
111
114
|
pangoLineage: 'JN.1*',
|
|
112
115
|
dateFrom: '2024-02-01',
|
|
113
116
|
dateTo: '2024-02-29',
|
|
114
|
-
minProportion: 0,
|
|
117
|
+
minProportion: 0.001,
|
|
115
118
|
},
|
|
116
119
|
},
|
|
117
120
|
response: {
|
|
@@ -127,7 +130,7 @@ export const Default: StoryObj<MutationsOverTimeProps> = {
|
|
|
127
130
|
pangoLineage: 'JN.1*',
|
|
128
131
|
dateFrom: '2024-03-01',
|
|
129
132
|
dateTo: '2024-03-31',
|
|
130
|
-
minProportion: 0,
|
|
133
|
+
minProportion: 0.001,
|
|
131
134
|
},
|
|
132
135
|
response: {
|
|
133
136
|
status: 200,
|
|
@@ -143,7 +146,7 @@ export const Default: StoryObj<MutationsOverTimeProps> = {
|
|
|
143
146
|
pangoLineage: 'JN.1*',
|
|
144
147
|
dateFrom: '2024-04-01',
|
|
145
148
|
dateTo: '2024-04-30',
|
|
146
|
-
minProportion: 0,
|
|
149
|
+
minProportion: 0.001,
|
|
147
150
|
},
|
|
148
151
|
response: {
|
|
149
152
|
status: 200,
|
|
@@ -159,7 +162,7 @@ export const Default: StoryObj<MutationsOverTimeProps> = {
|
|
|
159
162
|
pangoLineage: 'JN.1*',
|
|
160
163
|
dateFrom: '2024-05-01',
|
|
161
164
|
dateTo: '2024-05-31',
|
|
162
|
-
minProportion: 0,
|
|
165
|
+
minProportion: 0.001,
|
|
163
166
|
},
|
|
164
167
|
response: {
|
|
165
168
|
status: 200,
|
|
@@ -175,7 +178,7 @@ export const Default: StoryObj<MutationsOverTimeProps> = {
|
|
|
175
178
|
pangoLineage: 'JN.1*',
|
|
176
179
|
dateFrom: '2024-06-01',
|
|
177
180
|
dateTo: '2024-06-30',
|
|
178
|
-
minProportion: 0,
|
|
181
|
+
minProportion: 0.001,
|
|
179
182
|
},
|
|
180
183
|
response: {
|
|
181
184
|
status: 200,
|
|
@@ -183,7 +186,6 @@ export const Default: StoryObj<MutationsOverTimeProps> = {
|
|
|
183
186
|
},
|
|
184
187
|
},
|
|
185
188
|
},
|
|
186
|
-
|
|
187
189
|
{
|
|
188
190
|
matcher: {
|
|
189
191
|
name: 'nucleotideMutations_07',
|
|
@@ -192,7 +194,7 @@ export const Default: StoryObj<MutationsOverTimeProps> = {
|
|
|
192
194
|
pangoLineage: 'JN.1*',
|
|
193
195
|
dateFrom: '2024-07-01',
|
|
194
196
|
dateTo: '2024-07-31',
|
|
195
|
-
minProportion: 0,
|
|
197
|
+
minProportion: 0.001,
|
|
196
198
|
},
|
|
197
199
|
response: {
|
|
198
200
|
status: 200,
|
|
@@ -204,3 +206,55 @@ export const Default: StoryObj<MutationsOverTimeProps> = {
|
|
|
204
206
|
},
|
|
205
207
|
},
|
|
206
208
|
};
|
|
209
|
+
|
|
210
|
+
export const ShowsMessageWhenTooManyMutations: StoryObj<MutationsOverTimeProps> = {
|
|
211
|
+
...Template,
|
|
212
|
+
args: {
|
|
213
|
+
lapisFilter: { dateFrom: '2023-01-01', dateTo: '2023-12-31' },
|
|
214
|
+
sequenceType: 'nucleotide',
|
|
215
|
+
views: ['grid'],
|
|
216
|
+
width: '100%',
|
|
217
|
+
height: '700px',
|
|
218
|
+
granularity: 'year',
|
|
219
|
+
lapisDateField: 'date',
|
|
220
|
+
},
|
|
221
|
+
parameters: {
|
|
222
|
+
fetchMock: {
|
|
223
|
+
mocks: [
|
|
224
|
+
{
|
|
225
|
+
matcher: {
|
|
226
|
+
name: 'aggregated',
|
|
227
|
+
url: AGGREGATED_ENDPOINT,
|
|
228
|
+
body: {
|
|
229
|
+
dateFrom: '2023-01-01',
|
|
230
|
+
dateTo: '2023-12-31',
|
|
231
|
+
fields: ['date'],
|
|
232
|
+
},
|
|
233
|
+
},
|
|
234
|
+
response: {
|
|
235
|
+
status: 200,
|
|
236
|
+
body: aggregated_tooManyMutations,
|
|
237
|
+
},
|
|
238
|
+
},
|
|
239
|
+
{
|
|
240
|
+
matcher: {
|
|
241
|
+
name: 'nucleotideMutations',
|
|
242
|
+
url: NUCLEOTIDE_MUTATIONS_ENDPOINT,
|
|
243
|
+
body: {
|
|
244
|
+
dateFrom: '2023-01-01',
|
|
245
|
+
dateTo: '2023-12-31',
|
|
246
|
+
minProportion: 0.001,
|
|
247
|
+
},
|
|
248
|
+
response: {
|
|
249
|
+
status: 200,
|
|
250
|
+
body: nucleotideMutation_tooManyMutations,
|
|
251
|
+
},
|
|
252
|
+
},
|
|
253
|
+
},
|
|
254
|
+
],
|
|
255
|
+
},
|
|
256
|
+
},
|
|
257
|
+
play: async ({ canvas }) => {
|
|
258
|
+
await waitFor(() => expect(canvas.getByText('Showing 100 of 137 mutations.', { exact: false })).toBeVisible());
|
|
259
|
+
},
|
|
260
|
+
};
|
|
@@ -17,11 +17,17 @@ import { PreactLitAdapterWithGridJsStyles } from '../PreactLitAdapterWithGridJsS
|
|
|
17
17
|
*
|
|
18
18
|
* The grid view shows the proportion for each mutation over date ranges.
|
|
19
19
|
*
|
|
20
|
-
* The grid
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
20
|
+
* The grid limits the number of rows columns for browser performance reasons.
|
|
21
|
+
* Too much data might make the browser unresponsive.
|
|
22
|
+
*
|
|
23
|
+
* The number of columns is limited to 200.
|
|
24
|
+
* If this number are exceeded, an error message will be shown.
|
|
25
|
+
* It is your responsibility to make sure that this does not happen.
|
|
26
|
+
* Depending on the selected date range in the `lapisFilter`, you can adapt the granularity accordingly
|
|
27
|
+
* (e.g. use months instead of days).
|
|
28
|
+
*
|
|
29
|
+
* The number of rows is limited to 100.
|
|
30
|
+
* If there are more, the component will only show 100 mutations and notify the user.
|
|
25
31
|
*/
|
|
26
32
|
@customElement('gs-mutations-over-time')
|
|
27
33
|
export class MutationsOverTimeComponent extends PreactLitAdapterWithGridJsStyles {
|