@genspectrum/dashboard-components 0.13.4 → 0.13.6
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 +20 -1
- package/dist/components.d.ts +27 -21
- package/dist/components.js +136 -63
- package/dist/components.js.map +1 -1
- package/dist/util.d.ts +21 -21
- package/package.json +1 -1
- package/src/preact/components/downshift-combobox.tsx +2 -2
- package/src/preact/components/mutation-info.tsx +36 -0
- package/src/preact/locationFilter/fetchAutocompletionList.spec.ts +13 -13
- package/src/preact/locationFilter/fetchAutocompletionList.ts +55 -19
- package/src/preact/locationFilter/location-filter.stories.tsx +1 -1
- package/src/preact/locationFilter/location-filter.tsx +18 -12
- package/src/preact/mutationComparison/mutation-comparison.tsx +26 -2
- package/src/preact/mutations/mutations.tsx +5 -23
- package/src/preact/mutationsOverTime/mutations-over-time-grid.tsx +11 -5
- package/src/preact/wastewater/mutationsOverTime/wastewater-mutations-over-time.tsx +7 -1
- package/src/query/queryWastewaterMutationsOverTime.spec.ts +29 -1
- package/src/query/queryWastewaterMutationsOverTime.ts +30 -16
- package/src/web-components/input/gs-location-filter.stories.ts +1 -1
- package/src/web-components/wastewaterVisualization/gs-wastewater-mutations-over-time.tsx +9 -0
- package/standalone-bundle/dashboard-components.js +4463 -4395
- package/standalone-bundle/dashboard-components.js.map +1 -1
package/custom-elements.json
CHANGED
|
@@ -805,7 +805,7 @@
|
|
|
805
805
|
"type": {
|
|
806
806
|
"text": "StoryObj<LocationFilterProps>"
|
|
807
807
|
},
|
|
808
|
-
"default": "{ ...Template, parameters: { fetchMock: { mocks: [ { matcher: aggregatedEndpointMatcher, response: { status: 200, body: data, }, }, ], }, }, play: async ({ canvasElement, step }) => { const canvas = await withinShadowRoot(canvasElement, 'gs-location-filter'); const inputField = () => canvas.getByRole('combobox'); const listenerMock = fn(); await step('Setup event listener mock', async () => { canvasElement.addEventListener('gs-location-changed', listenerMock); }); await step('wait until data is loaded', async () => { await waitFor(() => { return expect(inputField()).toBeEnabled(); }); }); await step('Input invalid location', async () => { await userEvent.type(inputField(), 'Not / A / Location'); await expect(listenerMock).not.toHaveBeenCalled(); }); await step('Empty input', async () => { await userEvent.type(inputField(), '{backspace>18/}'); await userEvent.click(canvas.getByLabelText('toggle menu')); await waitFor(() => { return expect(listenerMock.mock.calls.at(-1)![0].detail).toStrictEqual({ region: undefined, country: undefined, division: undefined, location: undefined, }); }); }); await step('Select Asia', async () => { await userEvent.type(inputField(), 'Asia'); await userEvent.click(canvas.getByRole('option', { name:
|
|
808
|
+
"default": "{ ...Template, parameters: { fetchMock: { mocks: [ { matcher: aggregatedEndpointMatcher, response: { status: 200, body: data, }, }, ], }, }, play: async ({ canvasElement, step }) => { const canvas = await withinShadowRoot(canvasElement, 'gs-location-filter'); const inputField = () => canvas.getByRole('combobox'); const listenerMock = fn(); await step('Setup event listener mock', async () => { canvasElement.addEventListener('gs-location-changed', listenerMock); }); await step('wait until data is loaded', async () => { await waitFor(() => { return expect(inputField()).toBeEnabled(); }); }); await step('Input invalid location', async () => { await userEvent.type(inputField(), 'Not / A / Location'); await expect(listenerMock).not.toHaveBeenCalled(); }); await step('Empty input', async () => { await userEvent.type(inputField(), '{backspace>18/}'); await userEvent.click(canvas.getByLabelText('toggle menu')); await waitFor(() => { return expect(listenerMock.mock.calls.at(-1)![0].detail).toStrictEqual({ region: undefined, country: undefined, division: undefined, location: undefined, }); }); }); await step('Select Asia', async () => { await userEvent.type(inputField(), 'Asia'); await userEvent.click(canvas.getByRole('option', { name: /^Asia.*Asia$/ })); await waitFor(() => { return expect(listenerMock.mock.calls.at(-1)![0].detail).toStrictEqual({ region: 'Asia', country: undefined, division: undefined, location: undefined, }); }); }); await step('Select Asia / Bangladesh / Rajshahi / Chapainawabgonj', async () => { await userEvent.type(inputField(), ' / Bangladesh / Rajshahi / Chapainawabgonj'); await userEvent.click(canvas.getByText('Asia / Bangladesh / Rajshahi / Chapainawabgonj')); await waitFor(() => { return expect(listenerMock.mock.calls.at(-1)![0].detail).toStrictEqual({ region: 'Asia', country: 'Bangladesh', division: 'Rajshahi', location: 'Chapainawabgonj', }); }); }); }, }"
|
|
809
809
|
}
|
|
810
810
|
],
|
|
811
811
|
"exports": [
|
|
@@ -4047,6 +4047,16 @@
|
|
|
4047
4047
|
"default": "'700px'",
|
|
4048
4048
|
"description": "The height of the component.\n\nVisit https://genspectrum.github.io/dashboard-components/?path=/docs/components-size-of-components--docs for more information.",
|
|
4049
4049
|
"attribute": "height"
|
|
4050
|
+
},
|
|
4051
|
+
{
|
|
4052
|
+
"kind": "field",
|
|
4053
|
+
"name": "maxNumberOfGridRows",
|
|
4054
|
+
"type": {
|
|
4055
|
+
"text": "number"
|
|
4056
|
+
},
|
|
4057
|
+
"default": "100",
|
|
4058
|
+
"description": "The maximum number of grid rows to display.\n\nVisit https://genspectrum.github.io/dashboard-components/?path=/docs/components-size-of-components--docs for more information.",
|
|
4059
|
+
"attribute": "maxNumberOfGridRows"
|
|
4050
4060
|
}
|
|
4051
4061
|
],
|
|
4052
4062
|
"attributes": [
|
|
@@ -4085,6 +4095,15 @@
|
|
|
4085
4095
|
"default": "'700px'",
|
|
4086
4096
|
"description": "The height of the component.\n\nVisit https://genspectrum.github.io/dashboard-components/?path=/docs/components-size-of-components--docs for more information.",
|
|
4087
4097
|
"fieldName": "height"
|
|
4098
|
+
},
|
|
4099
|
+
{
|
|
4100
|
+
"name": "maxNumberOfGridRows",
|
|
4101
|
+
"type": {
|
|
4102
|
+
"text": "number"
|
|
4103
|
+
},
|
|
4104
|
+
"default": "100",
|
|
4105
|
+
"description": "The maximum number of grid rows to display.\n\nVisit https://genspectrum.github.io/dashboard-components/?path=/docs/components-size-of-components--docs for more information.",
|
|
4106
|
+
"fieldName": "maxNumberOfGridRows"
|
|
4088
4107
|
}
|
|
4089
4108
|
],
|
|
4090
4109
|
"superclass": {
|
package/dist/components.d.ts
CHANGED
|
@@ -1317,6 +1317,12 @@ export declare class WastewaterMutationsOverTimeComponent extends PreactLitAdapt
|
|
|
1317
1317
|
* Visit https://genspectrum.github.io/dashboard-components/?path=/docs/components-size-of-components--docs for more information.
|
|
1318
1318
|
*/
|
|
1319
1319
|
height: string;
|
|
1320
|
+
/**
|
|
1321
|
+
* The maximum number of grid rows to display.
|
|
1322
|
+
*
|
|
1323
|
+
* Visit https://genspectrum.github.io/dashboard-components/?path=/docs/components-size-of-components--docs for more information.
|
|
1324
|
+
*/
|
|
1325
|
+
maxNumberOfGridRows: number;
|
|
1320
1326
|
render(): JSX_2.Element;
|
|
1321
1327
|
}
|
|
1322
1328
|
|
|
@@ -1380,7 +1386,7 @@ declare global {
|
|
|
1380
1386
|
|
|
1381
1387
|
declare global {
|
|
1382
1388
|
interface HTMLElementTagNameMap {
|
|
1383
|
-
'gs-
|
|
1389
|
+
'gs-prevalence-over-time': PrevalenceOverTimeComponent;
|
|
1384
1390
|
}
|
|
1385
1391
|
}
|
|
1386
1392
|
|
|
@@ -1388,7 +1394,7 @@ declare global {
|
|
|
1388
1394
|
declare global {
|
|
1389
1395
|
namespace JSX {
|
|
1390
1396
|
interface IntrinsicElements {
|
|
1391
|
-
'gs-
|
|
1397
|
+
'gs-prevalence-over-time': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
1392
1398
|
}
|
|
1393
1399
|
}
|
|
1394
1400
|
}
|
|
@@ -1396,7 +1402,7 @@ declare global {
|
|
|
1396
1402
|
|
|
1397
1403
|
declare global {
|
|
1398
1404
|
interface HTMLElementTagNameMap {
|
|
1399
|
-
'gs-
|
|
1405
|
+
'gs-relative-growth-advantage': RelativeGrowthAdvantageComponent;
|
|
1400
1406
|
}
|
|
1401
1407
|
}
|
|
1402
1408
|
|
|
@@ -1404,7 +1410,7 @@ declare global {
|
|
|
1404
1410
|
declare global {
|
|
1405
1411
|
namespace JSX {
|
|
1406
1412
|
interface IntrinsicElements {
|
|
1407
|
-
'gs-
|
|
1413
|
+
'gs-relative-growth-advantage': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
1408
1414
|
}
|
|
1409
1415
|
}
|
|
1410
1416
|
}
|
|
@@ -1412,7 +1418,7 @@ declare global {
|
|
|
1412
1418
|
|
|
1413
1419
|
declare global {
|
|
1414
1420
|
interface HTMLElementTagNameMap {
|
|
1415
|
-
'gs-
|
|
1421
|
+
'gs-aggregate': AggregateComponent;
|
|
1416
1422
|
}
|
|
1417
1423
|
}
|
|
1418
1424
|
|
|
@@ -1420,7 +1426,7 @@ declare global {
|
|
|
1420
1426
|
declare global {
|
|
1421
1427
|
namespace JSX {
|
|
1422
1428
|
interface IntrinsicElements {
|
|
1423
|
-
'gs-
|
|
1429
|
+
'gs-aggregate': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
1424
1430
|
}
|
|
1425
1431
|
}
|
|
1426
1432
|
}
|
|
@@ -1428,7 +1434,7 @@ declare global {
|
|
|
1428
1434
|
|
|
1429
1435
|
declare global {
|
|
1430
1436
|
interface HTMLElementTagNameMap {
|
|
1431
|
-
'gs-
|
|
1437
|
+
'gs-mutations-over-time': MutationsOverTimeComponent;
|
|
1432
1438
|
}
|
|
1433
1439
|
}
|
|
1434
1440
|
|
|
@@ -1436,7 +1442,7 @@ declare global {
|
|
|
1436
1442
|
declare global {
|
|
1437
1443
|
namespace JSX {
|
|
1438
1444
|
interface IntrinsicElements {
|
|
1439
|
-
'gs-
|
|
1445
|
+
'gs-mutations-over-time': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
1440
1446
|
}
|
|
1441
1447
|
}
|
|
1442
1448
|
}
|
|
@@ -1444,7 +1450,7 @@ declare global {
|
|
|
1444
1450
|
|
|
1445
1451
|
declare global {
|
|
1446
1452
|
interface HTMLElementTagNameMap {
|
|
1447
|
-
'gs-
|
|
1453
|
+
'gs-sequences-by-location': SequencesByLocationComponent;
|
|
1448
1454
|
}
|
|
1449
1455
|
}
|
|
1450
1456
|
|
|
@@ -1452,7 +1458,7 @@ declare global {
|
|
|
1452
1458
|
declare global {
|
|
1453
1459
|
namespace JSX {
|
|
1454
1460
|
interface IntrinsicElements {
|
|
1455
|
-
'gs-
|
|
1461
|
+
'gs-sequences-by-location': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
1456
1462
|
}
|
|
1457
1463
|
}
|
|
1458
1464
|
}
|
|
@@ -1460,7 +1466,7 @@ declare global {
|
|
|
1460
1466
|
|
|
1461
1467
|
declare global {
|
|
1462
1468
|
interface HTMLElementTagNameMap {
|
|
1463
|
-
'gs-sequences-
|
|
1469
|
+
'gs-number-sequences-over-time': NumberSequencesOverTimeComponent;
|
|
1464
1470
|
}
|
|
1465
1471
|
}
|
|
1466
1472
|
|
|
@@ -1468,7 +1474,7 @@ declare global {
|
|
|
1468
1474
|
declare global {
|
|
1469
1475
|
namespace JSX {
|
|
1470
1476
|
interface IntrinsicElements {
|
|
1471
|
-
'gs-sequences-
|
|
1477
|
+
'gs-number-sequences-over-time': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
1472
1478
|
}
|
|
1473
1479
|
}
|
|
1474
1480
|
}
|
|
@@ -1528,10 +1534,10 @@ declare global {
|
|
|
1528
1534
|
|
|
1529
1535
|
declare global {
|
|
1530
1536
|
interface HTMLElementTagNameMap {
|
|
1531
|
-
'gs-
|
|
1537
|
+
'gs-location-filter': LocationFilterComponent;
|
|
1532
1538
|
}
|
|
1533
1539
|
interface HTMLElementEventMap {
|
|
1534
|
-
'gs-
|
|
1540
|
+
'gs-location-changed': LocationChangedEvent;
|
|
1535
1541
|
}
|
|
1536
1542
|
}
|
|
1537
1543
|
|
|
@@ -1539,7 +1545,7 @@ declare global {
|
|
|
1539
1545
|
declare global {
|
|
1540
1546
|
namespace JSX {
|
|
1541
1547
|
interface IntrinsicElements {
|
|
1542
|
-
'gs-
|
|
1548
|
+
'gs-location-filter': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
1543
1549
|
}
|
|
1544
1550
|
}
|
|
1545
1551
|
}
|
|
@@ -1547,10 +1553,10 @@ declare global {
|
|
|
1547
1553
|
|
|
1548
1554
|
declare global {
|
|
1549
1555
|
interface HTMLElementTagNameMap {
|
|
1550
|
-
'gs-
|
|
1556
|
+
'gs-text-input': TextInputComponent;
|
|
1551
1557
|
}
|
|
1552
1558
|
interface HTMLElementEventMap {
|
|
1553
|
-
'gs-
|
|
1559
|
+
'gs-text-input-changed': TextInputChangedEvent;
|
|
1554
1560
|
}
|
|
1555
1561
|
}
|
|
1556
1562
|
|
|
@@ -1558,7 +1564,7 @@ declare global {
|
|
|
1558
1564
|
declare global {
|
|
1559
1565
|
namespace JSX {
|
|
1560
1566
|
interface IntrinsicElements {
|
|
1561
|
-
'gs-
|
|
1567
|
+
'gs-text-input': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
1562
1568
|
}
|
|
1563
1569
|
}
|
|
1564
1570
|
}
|
|
@@ -1585,10 +1591,10 @@ declare global {
|
|
|
1585
1591
|
|
|
1586
1592
|
declare global {
|
|
1587
1593
|
interface HTMLElementTagNameMap {
|
|
1588
|
-
'gs-
|
|
1594
|
+
'gs-mutation-filter': MutationFilterComponent;
|
|
1589
1595
|
}
|
|
1590
1596
|
interface HTMLElementEventMap {
|
|
1591
|
-
'gs-
|
|
1597
|
+
'gs-mutation-filter-changed': CustomEvent<MutationsFilter>;
|
|
1592
1598
|
}
|
|
1593
1599
|
}
|
|
1594
1600
|
|
|
@@ -1596,7 +1602,7 @@ declare global {
|
|
|
1596
1602
|
declare global {
|
|
1597
1603
|
namespace JSX {
|
|
1598
1604
|
interface IntrinsicElements {
|
|
1599
|
-
'gs-
|
|
1605
|
+
'gs-mutation-filter': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
1600
1606
|
}
|
|
1601
1607
|
}
|
|
1602
1608
|
}
|
package/dist/components.js
CHANGED
|
@@ -1628,6 +1628,25 @@ const LoadingDisplay = () => {
|
|
|
1628
1628
|
}
|
|
1629
1629
|
);
|
|
1630
1630
|
};
|
|
1631
|
+
const SubstitutionsLink = () => /* @__PURE__ */ u$1(InfoLink, { href: "https://www.genome.gov/genetics-glossary/Substitution", children: "substitutions" });
|
|
1632
|
+
const InsertionsLink = () => /* @__PURE__ */ u$1(InfoLink, { href: "https://www.genome.gov/genetics-glossary/Insertion", children: "insertions" });
|
|
1633
|
+
const DeletionsLink = () => /* @__PURE__ */ u$1(InfoLink, { href: "https://www.genome.gov/genetics-glossary/Deletion", children: "deletions" });
|
|
1634
|
+
const ProportionExplanation = () => /* @__PURE__ */ u$1(Fragment, { children: [
|
|
1635
|
+
/* @__PURE__ */ u$1(InfoHeadline2, { children: "Proportion calculation" }),
|
|
1636
|
+
/* @__PURE__ */ u$1(InfoParagraph, { children: "The proportion of a mutation is calculated by dividing the number of sequences with the mutation by the total number of sequences with a non-ambiguous symbol at the position." }),
|
|
1637
|
+
/* @__PURE__ */ u$1(InfoParagraph, { children: [
|
|
1638
|
+
/* @__PURE__ */ u$1("b", { children: "Example:" }),
|
|
1639
|
+
" Assume we look at nucleotide mutations at position 5 where the reference has a T and assume there are 10 sequences in total:",
|
|
1640
|
+
/* @__PURE__ */ u$1("ul", { className: "list-disc list-inside ml-2", children: [
|
|
1641
|
+
/* @__PURE__ */ u$1("li", { children: "3 sequences have a C," }),
|
|
1642
|
+
/* @__PURE__ */ u$1("li", { children: "2 sequences have a T," }),
|
|
1643
|
+
/* @__PURE__ */ u$1("li", { children: "1 sequence has a G," }),
|
|
1644
|
+
/* @__PURE__ */ u$1("li", { children: "3 sequences have an N," }),
|
|
1645
|
+
/* @__PURE__ */ u$1("li", { children: "1 sequence has a Y (which means T or C)," })
|
|
1646
|
+
] }),
|
|
1647
|
+
"then the proportion of the T5C mutation is 50%. The 4 sequences that have an N or Y are excluded from the calculation."
|
|
1648
|
+
] })
|
|
1649
|
+
] });
|
|
1631
1650
|
function useFloatingUi(referenceRef, floatingRef, middleware, placement) {
|
|
1632
1651
|
const cleanupRef = A$1(null);
|
|
1633
1652
|
y(() => {
|
|
@@ -2212,7 +2231,22 @@ const MutationComparisonInfo = ({ originalComponentProps }) => {
|
|
|
2212
2231
|
const lapis = x$1(LapisUrlContext);
|
|
2213
2232
|
return /* @__PURE__ */ u$1(Info, { children: [
|
|
2214
2233
|
/* @__PURE__ */ u$1(InfoHeadline1, { children: "Info for mutation comparison" }),
|
|
2215
|
-
/* @__PURE__ */ u$1(InfoParagraph, { children:
|
|
2234
|
+
/* @__PURE__ */ u$1(InfoParagraph, { children: [
|
|
2235
|
+
"This displays ",
|
|
2236
|
+
/* @__PURE__ */ u$1(SubstitutionsLink, {}),
|
|
2237
|
+
" and ",
|
|
2238
|
+
/* @__PURE__ */ u$1(DeletionsLink, {}),
|
|
2239
|
+
" of several variants. It shows mutations where the proportion for any given variant falls within the range you can select in the component's toolbar."
|
|
2240
|
+
] }),
|
|
2241
|
+
/* @__PURE__ */ u$1(ProportionExplanation, {}),
|
|
2242
|
+
originalComponentProps.views.includes(views.table) && /* @__PURE__ */ u$1(Fragment, { children: [
|
|
2243
|
+
/* @__PURE__ */ u$1(InfoHeadline2, { children: "Table View" }),
|
|
2244
|
+
/* @__PURE__ */ u$1(InfoParagraph, { children: "The table view displays the proportion of mutations that appear in any of the variants." })
|
|
2245
|
+
] }),
|
|
2246
|
+
originalComponentProps.views.includes(views.venn) && /* @__PURE__ */ u$1(Fragment, { children: [
|
|
2247
|
+
/* @__PURE__ */ u$1(InfoHeadline2, { children: "Venn Diagram View" }),
|
|
2248
|
+
/* @__PURE__ */ u$1(InfoParagraph, { children: "The Venn diagram view illustrates which mutations overlap between the variants and which are exclusive to specific variants. Mutations overlap if their proportion falls within the selected range for two variants. If the proportion of a mutation is within the selected range for one variant but not for the other, the mutation is considered exclusive to that variant." })
|
|
2249
|
+
] }),
|
|
2216
2250
|
/* @__PURE__ */ u$1(InfoComponentCode, { componentName: "mutation-comparison", params: originalComponentProps, lapisUrl: lapis })
|
|
2217
2251
|
] });
|
|
2218
2252
|
};
|
|
@@ -6075,31 +6109,16 @@ const MutationsInfo = ({ originalComponentProps }) => {
|
|
|
6075
6109
|
return /* @__PURE__ */ u$1(Info, { children: [
|
|
6076
6110
|
/* @__PURE__ */ u$1(InfoHeadline1, { children: "Mutations" }),
|
|
6077
6111
|
/* @__PURE__ */ u$1(InfoParagraph, { children: [
|
|
6078
|
-
"This shows mutations of a variant. There are three types of mutations:",
|
|
6079
|
-
|
|
6080
|
-
/* @__PURE__ */ u$1(InfoLink, { href: "https://www.genome.gov/genetics-glossary/Substitution", children: "substitutions" }),
|
|
6112
|
+
"This shows mutations of a variant. There are three types of mutations: ",
|
|
6113
|
+
/* @__PURE__ */ u$1(SubstitutionsLink, {}),
|
|
6081
6114
|
",",
|
|
6082
6115
|
" ",
|
|
6083
|
-
/* @__PURE__ */ u$1(
|
|
6084
|
-
" and",
|
|
6085
|
-
|
|
6086
|
-
/* @__PURE__ */ u$1(InfoLink, { href: "https://www.genome.gov/genetics-glossary/Insertion", children: "insertions" }),
|
|
6116
|
+
/* @__PURE__ */ u$1(DeletionsLink, {}),
|
|
6117
|
+
" and ",
|
|
6118
|
+
/* @__PURE__ */ u$1(InsertionsLink, {}),
|
|
6087
6119
|
"."
|
|
6088
6120
|
] }),
|
|
6089
|
-
/* @__PURE__ */ u$1(
|
|
6090
|
-
/* @__PURE__ */ u$1(InfoParagraph, { children: "The proportion of a mutation is calculated by dividing the number of sequences with the mutation by the total number of sequences with a non-ambiguous symbol at the position." }),
|
|
6091
|
-
/* @__PURE__ */ u$1(InfoParagraph, { children: [
|
|
6092
|
-
/* @__PURE__ */ u$1("b", { children: "Example:" }),
|
|
6093
|
-
" Assume we look at nucleotide mutations at position 5 where the reference has a T and assume there are 10 sequences in total:",
|
|
6094
|
-
/* @__PURE__ */ u$1("ul", { className: "list-disc list-inside ml-2", children: [
|
|
6095
|
-
/* @__PURE__ */ u$1("li", { children: "3 sequences have a C," }),
|
|
6096
|
-
/* @__PURE__ */ u$1("li", { children: "2 sequences have a T," }),
|
|
6097
|
-
/* @__PURE__ */ u$1("li", { children: "1 sequence has a G," }),
|
|
6098
|
-
/* @__PURE__ */ u$1("li", { children: "3 sequences have an N," }),
|
|
6099
|
-
/* @__PURE__ */ u$1("li", { children: "1 sequence has a Y (which means T or C)," })
|
|
6100
|
-
] }),
|
|
6101
|
-
"then the proportion of the T5C mutation is 50%. The 4 sequences that have an N or Y are excluded from the calculation."
|
|
6102
|
-
] }),
|
|
6121
|
+
/* @__PURE__ */ u$1(ProportionExplanation, {}),
|
|
6103
6122
|
/* @__PURE__ */ u$1(InfoComponentCode, { componentName: "mutations", params: originalComponentProps, lapisUrl: lapis })
|
|
6104
6123
|
] });
|
|
6105
6124
|
};
|
|
@@ -9472,15 +9491,20 @@ const Tooltip = ({ children, content, position = "bottom" }) => {
|
|
|
9472
9491
|
};
|
|
9473
9492
|
const MAX_NUMBER_OF_GRID_ROWS = 100;
|
|
9474
9493
|
const MUTATION_CELL_WIDTH_REM = 8;
|
|
9475
|
-
const MutationsOverTimeGrid = ({
|
|
9494
|
+
const MutationsOverTimeGrid = ({
|
|
9495
|
+
data,
|
|
9496
|
+
colorScale,
|
|
9497
|
+
maxNumberOfGridRows
|
|
9498
|
+
}) => {
|
|
9499
|
+
const currentMaxNumberOfGridRows = maxNumberOfGridRows ?? MAX_NUMBER_OF_GRID_ROWS;
|
|
9476
9500
|
const allMutations = data.getFirstAxisKeys();
|
|
9477
|
-
const shownMutations = allMutations.slice(0,
|
|
9501
|
+
const shownMutations = allMutations.slice(0, currentMaxNumberOfGridRows);
|
|
9478
9502
|
const dates = data.getSecondAxisKeys();
|
|
9479
9503
|
const gridRef = A$1(null);
|
|
9480
9504
|
return /* @__PURE__ */ u$1(Fragment, { children: [
|
|
9481
|
-
allMutations.length >
|
|
9505
|
+
allMutations.length > currentMaxNumberOfGridRows && /* @__PURE__ */ u$1("div", { className: "pl-2", children: [
|
|
9482
9506
|
"Showing ",
|
|
9483
|
-
|
|
9507
|
+
currentMaxNumberOfGridRows,
|
|
9484
9508
|
" of ",
|
|
9485
9509
|
allMutations.length,
|
|
9486
9510
|
" mutations. You can narrow the filter to reduce the number of mutations."
|
|
@@ -11135,12 +11159,20 @@ async function queryWastewaterMutationsOverTime(lapis, lapisFilter, signal) {
|
|
|
11135
11159
|
"aminoAcidMutationFrequency"
|
|
11136
11160
|
]);
|
|
11137
11161
|
const data = (await fetchData.evaluate(lapis, signal)).content;
|
|
11138
|
-
return data.map((row) =>
|
|
11139
|
-
|
|
11140
|
-
|
|
11141
|
-
|
|
11142
|
-
|
|
11143
|
-
|
|
11162
|
+
return data.map((row) => {
|
|
11163
|
+
try {
|
|
11164
|
+
return {
|
|
11165
|
+
location: row.location,
|
|
11166
|
+
date: toTemporalClass(parseDateStringToTemporal(row.date, "day")),
|
|
11167
|
+
nucleotideMutationFrequency: row.nucleotideMutationFrequency !== null ? transformMutations(JSON.parse(row.nucleotideMutationFrequency)) : [],
|
|
11168
|
+
aminoAcidMutationFrequency: row.aminoAcidMutationFrequency !== null ? transformMutations(JSON.parse(row.aminoAcidMutationFrequency)) : []
|
|
11169
|
+
};
|
|
11170
|
+
} catch (e2) {
|
|
11171
|
+
throw new Error(
|
|
11172
|
+
`Failed to parse row of wastewater data: ${JSON.stringify(row)}: ${(e2 == null ? void 0 : e2.message) ?? "Unknown error"}`
|
|
11173
|
+
);
|
|
11174
|
+
}
|
|
11175
|
+
});
|
|
11144
11176
|
}
|
|
11145
11177
|
const mutationFrequencySchema = z$2.record(z$2.number().nullable());
|
|
11146
11178
|
function transformMutations(input) {
|
|
@@ -11148,10 +11180,16 @@ function transformMutations(input) {
|
|
|
11148
11180
|
if (!mutationFrequency.success) {
|
|
11149
11181
|
throw new Error(`Failed to parse mutation frequency: ${mutationFrequency.error.message}`);
|
|
11150
11182
|
}
|
|
11151
|
-
return Object.entries(mutationFrequency.data).map(([key, value]) =>
|
|
11152
|
-
mutation
|
|
11153
|
-
|
|
11154
|
-
|
|
11183
|
+
return Object.entries(mutationFrequency.data).map(([key, value]) => {
|
|
11184
|
+
const mutation = SubstitutionClass.parse(key);
|
|
11185
|
+
if (mutation === null) {
|
|
11186
|
+
throw new Error(`Failed to parse mutation: "${key}"`);
|
|
11187
|
+
}
|
|
11188
|
+
return {
|
|
11189
|
+
mutation,
|
|
11190
|
+
proportion: value
|
|
11191
|
+
};
|
|
11192
|
+
});
|
|
11155
11193
|
}
|
|
11156
11194
|
async function computeWastewaterMutationsOverTimeDataPerLocation(lapis, lapisFilter, sequenceType, signal) {
|
|
11157
11195
|
const data = await queryWastewaterMutationsOverTime(lapis, lapisFilter, signal);
|
|
@@ -11186,7 +11224,8 @@ const wastewaterMutationOverTimeSchema = z$2.object({
|
|
|
11186
11224
|
lapisFilter: lapisFilterSchema,
|
|
11187
11225
|
sequenceType: sequenceTypeSchema,
|
|
11188
11226
|
width: z$2.string(),
|
|
11189
|
-
height: z$2.string()
|
|
11227
|
+
height: z$2.string(),
|
|
11228
|
+
maxNumberOfGridRows: z$2.number().optional()
|
|
11190
11229
|
});
|
|
11191
11230
|
const WastewaterMutationsOverTime = (componentProps) => {
|
|
11192
11231
|
const { width, height } = componentProps;
|
|
@@ -11220,18 +11259,20 @@ const WastewaterMutationsOverTimeInner = (componentProps) => {
|
|
|
11220
11259
|
MutationsOverTimeTabs,
|
|
11221
11260
|
{
|
|
11222
11261
|
mutationOverTimeDataPerLocation,
|
|
11223
|
-
originalComponentProps: componentProps
|
|
11262
|
+
originalComponentProps: componentProps,
|
|
11263
|
+
maxNumberOfGridRows: componentProps.maxNumberOfGridRows
|
|
11224
11264
|
}
|
|
11225
11265
|
);
|
|
11226
11266
|
};
|
|
11227
11267
|
const MutationsOverTimeTabs = ({
|
|
11228
11268
|
mutationOverTimeDataPerLocation,
|
|
11229
|
-
originalComponentProps
|
|
11269
|
+
originalComponentProps,
|
|
11270
|
+
maxNumberOfGridRows
|
|
11230
11271
|
}) => {
|
|
11231
11272
|
const [colorScale, setColorScale] = h({ min: 0, max: 1, color: "indigo" });
|
|
11232
11273
|
const tabs = mutationOverTimeDataPerLocation.map(({ location, data }) => ({
|
|
11233
11274
|
title: location,
|
|
11234
|
-
content: /* @__PURE__ */ u$1(MutationsOverTimeGrid, { data, colorScale })
|
|
11275
|
+
content: /* @__PURE__ */ u$1(MutationsOverTimeGrid, { data, colorScale, maxNumberOfGridRows })
|
|
11235
11276
|
}));
|
|
11236
11277
|
const toolbar = /* @__PURE__ */ u$1(
|
|
11237
11278
|
Toolbar,
|
|
@@ -11285,6 +11326,7 @@ let WastewaterMutationsOverTimeComponent = class extends PreactLitAdapterWithGri
|
|
|
11285
11326
|
this.sequenceType = "nucleotide";
|
|
11286
11327
|
this.width = "100%";
|
|
11287
11328
|
this.height = "700px";
|
|
11329
|
+
this.maxNumberOfGridRows = 100;
|
|
11288
11330
|
}
|
|
11289
11331
|
render() {
|
|
11290
11332
|
return /* @__PURE__ */ u$1(
|
|
@@ -11293,7 +11335,8 @@ let WastewaterMutationsOverTimeComponent = class extends PreactLitAdapterWithGri
|
|
|
11293
11335
|
lapisFilter: this.lapisFilter,
|
|
11294
11336
|
sequenceType: this.sequenceType,
|
|
11295
11337
|
width: this.width,
|
|
11296
|
-
height: this.height
|
|
11338
|
+
height: this.height,
|
|
11339
|
+
maxNumberOfGridRows: this.maxNumberOfGridRows
|
|
11297
11340
|
}
|
|
11298
11341
|
);
|
|
11299
11342
|
}
|
|
@@ -11310,6 +11353,9 @@ __decorateClass$5([
|
|
|
11310
11353
|
__decorateClass$5([
|
|
11311
11354
|
n$1({ type: String })
|
|
11312
11355
|
], WastewaterMutationsOverTimeComponent.prototype, "height", 2);
|
|
11356
|
+
__decorateClass$5([
|
|
11357
|
+
n$1({ type: Number })
|
|
11358
|
+
], WastewaterMutationsOverTimeComponent.prototype, "maxNumberOfGridRows", 2);
|
|
11313
11359
|
WastewaterMutationsOverTimeComponent = __decorateClass$5([
|
|
11314
11360
|
t$3("gs-wastewater-mutations-over-time")
|
|
11315
11361
|
], WastewaterMutationsOverTimeComponent);
|
|
@@ -11627,26 +11673,46 @@ async function fetchAutocompletionList({
|
|
|
11627
11673
|
signal,
|
|
11628
11674
|
lapisFilter
|
|
11629
11675
|
}) {
|
|
11630
|
-
const
|
|
11676
|
+
const helpersThatOverwriteAValueToItsAncestor = fields.map(
|
|
11677
|
+
(_2, i2) => fields.slice(i2 + 1).reduce((acc, field) => ({ ...acc, [field]: null }), {})
|
|
11678
|
+
);
|
|
11631
11679
|
const fetchAggregatedOperator = new FetchAggregatedOperator(
|
|
11632
11680
|
lapisFilter ?? {},
|
|
11633
11681
|
fields
|
|
11634
11682
|
);
|
|
11635
11683
|
const data = (await fetchAggregatedOperator.evaluate(lapis, signal)).content;
|
|
11636
|
-
const locationValues = data.map((entry) =>
|
|
11637
|
-
|
|
11638
|
-
|
|
11639
|
-
|
|
11640
|
-
|
|
11641
|
-
|
|
11642
|
-
|
|
11643
|
-
|
|
11684
|
+
const locationValues = data.map((entry) => ({
|
|
11685
|
+
value: fields.reduce((acc, field) => ({ ...acc, [field]: entry[field] }), {}),
|
|
11686
|
+
count: entry.count
|
|
11687
|
+
})).reduce((mapOfAllHierarchiesAndCounts, entry) => {
|
|
11688
|
+
return addValueAndAllAncestorsToMap(
|
|
11689
|
+
entry,
|
|
11690
|
+
helpersThatOverwriteAValueToItsAncestor,
|
|
11691
|
+
mapOfAllHierarchiesAndCounts
|
|
11692
|
+
);
|
|
11693
|
+
}, /* @__PURE__ */ new Map());
|
|
11694
|
+
return [...locationValues].map(([json, count]) => ({
|
|
11695
|
+
value: JSON.parse(json),
|
|
11696
|
+
count
|
|
11697
|
+
})).sort(compareLocationEntries(fields)).map(({ value, count }) => ({
|
|
11698
|
+
value: fields.reduce((acc, field) => ({ ...acc, [field]: value[field] ?? void 0 }), {}),
|
|
11699
|
+
count
|
|
11700
|
+
}));
|
|
11701
|
+
}
|
|
11702
|
+
function addValueAndAllAncestorsToMap({ value, count }, helpersThatOverwriteAValueToItsAncestor, mapOfAllHierarchiesAndCounts) {
|
|
11703
|
+
const keysOfAllHierarchyLevels = new Set(
|
|
11704
|
+
helpersThatOverwriteAValueToItsAncestor.map((overwriteValues) => ({ ...value, ...overwriteValues })).map((value2) => JSON.stringify(value2))
|
|
11705
|
+
);
|
|
11706
|
+
for (const key of keysOfAllHierarchyLevels) {
|
|
11707
|
+
mapOfAllHierarchiesAndCounts.set(key, (mapOfAllHierarchiesAndCounts.get(key) ?? 0) + count);
|
|
11708
|
+
}
|
|
11709
|
+
return mapOfAllHierarchiesAndCounts;
|
|
11644
11710
|
}
|
|
11645
11711
|
function compareLocationEntries(fields) {
|
|
11646
11712
|
return (a2, b3) => {
|
|
11647
11713
|
for (const field of fields) {
|
|
11648
|
-
const valueA = a2[field];
|
|
11649
|
-
const valueB = b3[field];
|
|
11714
|
+
const valueA = a2.value[field];
|
|
11715
|
+
const valueB = b3.value[field];
|
|
11650
11716
|
if (valueA === valueB) {
|
|
11651
11717
|
continue;
|
|
11652
11718
|
}
|
|
@@ -14702,12 +14768,12 @@ function DownshiftCombobox({
|
|
|
14702
14768
|
children: items.length > 0 ? items.map((item, index) => /* @__PURE__ */ u$1(
|
|
14703
14769
|
"li",
|
|
14704
14770
|
{
|
|
14705
|
-
className: `${highlightedIndex === index ? "bg-blue-300" : ""} ${selectedItem !== null && itemToString2(selectedItem) === itemToString2(item) ? "font-bold" : ""} py-2 px-3 shadow-sm
|
|
14771
|
+
className: `${highlightedIndex === index ? "bg-blue-300" : ""} ${selectedItem !== null && itemToString2(selectedItem) === itemToString2(item) ? "font-bold" : ""} py-2 px-3 shadow-sm`,
|
|
14706
14772
|
...getItemProps({ item, index }),
|
|
14707
14773
|
children: formatItemInList(item)
|
|
14708
14774
|
},
|
|
14709
14775
|
itemToString2(item)
|
|
14710
|
-
)) : /* @__PURE__ */ u$1("li", { className: "py-2 px-3 shadow-sm
|
|
14776
|
+
)) : /* @__PURE__ */ u$1("li", { className: "py-2 px-3 shadow-sm", children: "No elements to select." })
|
|
14711
14777
|
}
|
|
14712
14778
|
)
|
|
14713
14779
|
] });
|
|
@@ -14750,8 +14816,8 @@ const LocationSelector = ({
|
|
|
14750
14816
|
return locationData.map((location) => toSelectItem(location, fields)).filter((item) => item !== void 0);
|
|
14751
14817
|
}, [fields, locationData]);
|
|
14752
14818
|
const selectedItem = T$1(() => {
|
|
14753
|
-
return value !== void 0 ?
|
|
14754
|
-
}, [fields, value]);
|
|
14819
|
+
return value !== void 0 ? allItems.find((item) => item.description == concatenateLocation(value, fields)) : void 0;
|
|
14820
|
+
}, [fields, value, allItems]);
|
|
14755
14821
|
return /* @__PURE__ */ u$1(
|
|
14756
14822
|
DownshiftCombobox,
|
|
14757
14823
|
{
|
|
@@ -14761,12 +14827,17 @@ const LocationSelector = ({
|
|
|
14761
14827
|
createEvent: (item) => new LocationChangedEvent((item == null ? void 0 : item.lapisFilter) ?? emptyLocationFilter(fields)),
|
|
14762
14828
|
itemToString: (item) => (item == null ? void 0 : item.label) ?? "",
|
|
14763
14829
|
placeholderText,
|
|
14764
|
-
formatItemInList: (item) => {
|
|
14765
|
-
|
|
14830
|
+
formatItemInList: (item) => /* @__PURE__ */ u$1(Fragment, { children: [
|
|
14831
|
+
/* @__PURE__ */ u$1("p", { children: [
|
|
14766
14832
|
/* @__PURE__ */ u$1("span", { children: item.label }),
|
|
14767
|
-
/* @__PURE__ */ u$1("span", { className: "
|
|
14768
|
-
|
|
14769
|
-
|
|
14833
|
+
/* @__PURE__ */ u$1("span", { className: "ml-2 text-gray-500", children: [
|
|
14834
|
+
"(",
|
|
14835
|
+
item.count,
|
|
14836
|
+
")"
|
|
14837
|
+
] })
|
|
14838
|
+
] }),
|
|
14839
|
+
/* @__PURE__ */ u$1("span", { className: "text-sm text-gray-500", children: item.description })
|
|
14840
|
+
] })
|
|
14770
14841
|
}
|
|
14771
14842
|
);
|
|
14772
14843
|
};
|
|
@@ -14777,7 +14848,8 @@ function filterByInputValue$2(item, inputValue) {
|
|
|
14777
14848
|
}
|
|
14778
14849
|
return ((_a = item == null ? void 0 : item.label) == null ? void 0 : _a.toLowerCase().includes(inputValue.toLowerCase())) || (item == null ? void 0 : item.description.toLowerCase().includes(inputValue.toLowerCase()));
|
|
14779
14850
|
}
|
|
14780
|
-
function toSelectItem(
|
|
14851
|
+
function toSelectItem(locationEntry, fields) {
|
|
14852
|
+
const locationFilter = locationEntry.value;
|
|
14781
14853
|
const concatenatedLocation = concatenateLocation(locationFilter, fields);
|
|
14782
14854
|
const lastNonUndefinedField = [...fields].reverse().find((field) => locationFilter[field] !== void 0 && locationFilter[field] !== null);
|
|
14783
14855
|
if (lastNonUndefinedField === void 0) {
|
|
@@ -14786,7 +14858,8 @@ function toSelectItem(locationFilter, fields) {
|
|
|
14786
14858
|
return {
|
|
14787
14859
|
lapisFilter: locationFilter,
|
|
14788
14860
|
label: locationFilter[lastNonUndefinedField],
|
|
14789
|
-
description: concatenatedLocation
|
|
14861
|
+
description: concatenatedLocation,
|
|
14862
|
+
count: locationEntry.count
|
|
14790
14863
|
};
|
|
14791
14864
|
}
|
|
14792
14865
|
function concatenateLocation(locationFilter, fields) {
|