@genspectrum/dashboard-components 0.15.0 → 0.16.1
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 +255 -57
- package/dist/components.d.ts +49 -32
- package/dist/components.js +361 -212
- package/dist/components.js.map +1 -1
- package/dist/style.css +9 -0
- package/dist/util.d.ts +43 -43
- package/package.json +1 -1
- package/src/preact/ReferenceGenomeContext.ts +16 -1
- package/src/preact/aggregatedData/aggregate-bar-chart.tsx +26 -5
- package/src/preact/aggregatedData/aggregate.stories.tsx +0 -1
- package/src/preact/aggregatedData/aggregate.tsx +5 -1
- package/src/preact/components/ReferenceGenomesAwaiter.tsx +1 -6
- package/src/preact/components/info.tsx +1 -0
- package/src/preact/components/resize-container.tsx +1 -1
- package/src/preact/mutationComparison/mutation-comparison-venn.tsx +4 -2
- package/src/preact/mutationComparison/mutation-comparison.stories.tsx +0 -1
- package/src/preact/mutationComparison/mutation-comparison.tsx +5 -1
- package/src/preact/mutationFilter/mutation-filter.stories.tsx +17 -1
- package/src/preact/mutationFilter/mutation-filter.tsx +8 -0
- package/src/preact/mutations/mutations.stories.tsx +0 -1
- package/src/preact/mutations/mutations.tsx +1 -1
- package/src/preact/mutationsOverTime/getFilteredMutationsOverTime.spec.ts +70 -14
- package/src/preact/mutationsOverTime/getFilteredMutationsOverTimeData.ts +30 -7
- package/src/preact/mutationsOverTime/mutations-over-time-grid.tsx +56 -55
- package/src/preact/mutationsOverTime/mutations-over-time.stories.tsx +26 -39
- package/src/preact/mutationsOverTime/mutations-over-time.tsx +22 -7
- package/src/preact/numberSequencesOverTime/number-sequences-over-time-bar-chart.tsx +8 -3
- package/src/preact/numberSequencesOverTime/number-sequences-over-time-line-chart.tsx +8 -3
- package/src/preact/numberSequencesOverTime/number-sequences-over-time.stories.tsx +3 -1
- package/src/preact/numberSequencesOverTime/number-sequences-over-time.tsx +18 -3
- package/src/preact/prevalenceOverTime/prevalence-over-time-bar-chart.tsx +48 -35
- package/src/preact/prevalenceOverTime/prevalence-over-time-bubble-chart.tsx +83 -70
- package/src/preact/prevalenceOverTime/prevalence-over-time-line-chart.tsx +48 -37
- package/src/preact/prevalenceOverTime/prevalence-over-time.stories.tsx +0 -3
- package/src/preact/prevalenceOverTime/prevalence-over-time.tsx +6 -1
- package/src/preact/relativeGrowthAdvantage/relative-growth-advantage-chart.tsx +31 -23
- package/src/preact/relativeGrowthAdvantage/relative-growth-advantage.stories.tsx +0 -1
- package/src/preact/relativeGrowthAdvantage/relative-growth-advantage.tsx +5 -1
- package/src/preact/sequencesByLocation/__mockData__/worldAtlas.json +1 -0
- package/src/preact/{map → sequencesByLocation}/sequences-by-location-map.tsx +6 -3
- package/src/preact/{map → sequencesByLocation}/sequences-by-location-table.tsx +1 -1
- package/src/preact/{map → sequencesByLocation}/sequences-by-location.stories.tsx +58 -1
- package/src/preact/{map → sequencesByLocation}/sequences-by-location.tsx +10 -1
- package/src/preact/shared/aspectRatio/AspectRatio.tsx +13 -0
- package/src/preact/shared/charts/getMaintainAspectRatio.ts +3 -0
- package/src/preact/statistic/statistics.stories.tsx +0 -1
- package/src/preact/statistic/statistics.tsx +4 -4
- package/src/preact/wastewater/mutationsOverTime/wastewater-mutations-over-time.stories.tsx +0 -1
- package/src/preact/wastewater/mutationsOverTime/wastewater-mutations-over-time.tsx +1 -1
- package/src/query/computeMapLocationData.spec.ts +1 -1
- package/src/query/computeMapLocationData.ts +1 -1
- package/src/query/querySequencesByLocationData.ts +1 -1
- package/src/utilEntrypoint.ts +1 -1
- package/src/web-components/PreactLitAdapter.tsx +2 -5
- package/src/web-components/ResizeContainer.mdx +4 -1
- package/src/web-components/gs-app.ts +2 -4
- package/src/web-components/visualization/gs-aggregate.stories.ts +13 -6
- package/src/web-components/visualization/gs-aggregate.tsx +1 -1
- package/src/web-components/visualization/gs-mutation-comparison.stories.ts +8 -1
- package/src/web-components/visualization/gs-mutation-comparison.tsx +1 -1
- package/src/web-components/visualization/gs-mutations-over-time.stories.ts +24 -1
- package/src/web-components/visualization/gs-mutations-over-time.tsx +30 -1
- package/src/web-components/visualization/gs-mutations.stories.ts +8 -1
- package/src/web-components/visualization/gs-mutations.tsx +1 -1
- package/src/web-components/visualization/gs-number-sequences-over-time.stories.ts +11 -1
- package/src/web-components/visualization/gs-number-sequences-over-time.tsx +1 -1
- package/src/web-components/visualization/gs-prevalence-over-time.stories.ts +8 -2
- package/src/web-components/visualization/gs-prevalence-over-time.tsx +1 -1
- package/src/web-components/visualization/gs-relative-growth-advantage.stories.ts +8 -1
- package/src/web-components/visualization/gs-relative-growth-advantage.tsx +1 -1
- package/src/web-components/visualization/gs-sequences-by-location.stories.ts +13 -7
- package/src/web-components/visualization/gs-sequences-by-location.tsx +6 -3
- package/src/web-components/visualization/gs-statistics.stories.ts +0 -1
- package/src/web-components/visualization/gs-statistics.tsx +1 -1
- package/src/web-components/wastewaterVisualization/gs-wastewater-mutations-over-time.stories.ts +9 -1
- package/src/web-components/wastewaterVisualization/gs-wastewater-mutations-over-time.tsx +1 -1
- package/standalone-bundle/dashboard-components.js +5817 -5706
- package/standalone-bundle/dashboard-components.js.map +1 -1
- package/standalone-bundle/style.css +1 -1
- package/src/preact/map/__mockData__/worldAtlas.json +0 -497127
- /package/src/preact/{map → sequencesByLocation}/__mockData__/aggregatedGermany.json +0 -0
- /package/src/preact/{map → sequencesByLocation}/__mockData__/aggregatedWorld.json +0 -0
- /package/src/preact/{map → sequencesByLocation}/__mockData__/germanyMap.json +0 -0
- /package/src/preact/{map → sequencesByLocation}/__mockData__/howToGenerateWorldMap.md +0 -0
- /package/src/preact/{map → sequencesByLocation}/leafletStyleModifications.css +0 -0
- /package/src/preact/{map → sequencesByLocation}/loadMapSource.tsx +0 -0
|
@@ -6,6 +6,7 @@ import { useEffect, useRef } from 'preact/hooks';
|
|
|
6
6
|
import type { EnhancedGeoJsonFeatureProperties } from '../../query/computeMapLocationData';
|
|
7
7
|
import { InfoHeadline1, InfoParagraph } from '../components/info';
|
|
8
8
|
import { Modal, useModalRef } from '../components/modal';
|
|
9
|
+
import { AspectRatio } from '../shared/aspectRatio/AspectRatio';
|
|
9
10
|
import { formatProportion } from '../shared/table/formatProportion';
|
|
10
11
|
|
|
11
12
|
type SequencesByLocationMapProps = {
|
|
@@ -20,6 +21,7 @@ type SequencesByLocationMapProps = {
|
|
|
20
21
|
offsetX: number;
|
|
21
22
|
offsetY: number;
|
|
22
23
|
hasTableView: boolean;
|
|
24
|
+
maintainAspectRatio: boolean;
|
|
23
25
|
};
|
|
24
26
|
|
|
25
27
|
export const SequencesByLocationMap: FunctionComponent<SequencesByLocationMapProps> = ({
|
|
@@ -34,6 +36,7 @@ export const SequencesByLocationMap: FunctionComponent<SequencesByLocationMapPro
|
|
|
34
36
|
offsetX,
|
|
35
37
|
offsetY,
|
|
36
38
|
hasTableView,
|
|
39
|
+
maintainAspectRatio,
|
|
37
40
|
}) => {
|
|
38
41
|
const ref = useRef<HTMLDivElement>(null);
|
|
39
42
|
|
|
@@ -69,8 +72,8 @@ export const SequencesByLocationMap: FunctionComponent<SequencesByLocationMapPro
|
|
|
69
72
|
}, [ref, locations, enableMapNavigation, lapisLocationField, zoom, offsetX, offsetY]);
|
|
70
73
|
|
|
71
74
|
return (
|
|
72
|
-
<
|
|
73
|
-
<div
|
|
75
|
+
<AspectRatio aspectRatio={maintainAspectRatio ? 50 : undefined}>
|
|
76
|
+
<div className='h-full' ref={ref} />
|
|
74
77
|
<div className='relative'>
|
|
75
78
|
<DataMatchInformation
|
|
76
79
|
totalCount={totalCount}
|
|
@@ -80,7 +83,7 @@ export const SequencesByLocationMap: FunctionComponent<SequencesByLocationMapPro
|
|
|
80
83
|
hasTableView={hasTableView}
|
|
81
84
|
/>
|
|
82
85
|
</div>
|
|
83
|
-
</
|
|
86
|
+
</AspectRatio>
|
|
84
87
|
);
|
|
85
88
|
};
|
|
86
89
|
|
|
@@ -32,7 +32,7 @@ export const SequencesByLocationTable: FunctionComponent<SequencesByLocationTabl
|
|
|
32
32
|
sort: true,
|
|
33
33
|
formatter: (cell: number) => formatProportion(cell),
|
|
34
34
|
},
|
|
35
|
-
...('isShownOnMap' in tableData[0]
|
|
35
|
+
...(tableData.length > 0 && 'isShownOnMap' in tableData[0]
|
|
36
36
|
? [{ id: 'isShownOnMap', name: 'shown on map', sort: true, width: '20%' }]
|
|
37
37
|
: []),
|
|
38
38
|
];
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type Meta, type StoryObj } from '@storybook/preact';
|
|
2
|
+
import { expect, waitFor, within } from '@storybook/test';
|
|
2
3
|
|
|
3
4
|
import worldAtlas from './__mockData__/worldAtlas.json';
|
|
4
5
|
import { AGGREGATED_ENDPOINT, LAPIS_URL } from '../../constants';
|
|
@@ -13,6 +14,21 @@ import './leafletStyleModifications.css';
|
|
|
13
14
|
const meta: Meta<SequencesByLocationProps> = {
|
|
14
15
|
title: 'Visualization/SequencesByLocation',
|
|
15
16
|
component: SequencesByLocation,
|
|
17
|
+
argTypes: {
|
|
18
|
+
lapisFilter: { control: 'object' },
|
|
19
|
+
lapisLocationField: { control: { type: 'text' } },
|
|
20
|
+
enableMapNavigation: { control: { type: 'boolean' } },
|
|
21
|
+
width: { control: { type: 'text' } },
|
|
22
|
+
height: { control: { type: 'text' } },
|
|
23
|
+
views: {
|
|
24
|
+
options: ['map', 'table'],
|
|
25
|
+
control: { type: 'check' },
|
|
26
|
+
},
|
|
27
|
+
zoom: { control: { type: 'number' } },
|
|
28
|
+
offsetX: { control: { type: 'number' } },
|
|
29
|
+
offsetY: { control: { type: 'number' } },
|
|
30
|
+
pageSize: { control: 'object' },
|
|
31
|
+
},
|
|
16
32
|
};
|
|
17
33
|
|
|
18
34
|
export default meta;
|
|
@@ -51,7 +67,6 @@ export const Default: StoryObj<SequencesByLocationProps> = {
|
|
|
51
67
|
},
|
|
52
68
|
enableMapNavigation: false,
|
|
53
69
|
width: '1100px',
|
|
54
|
-
height: '800px',
|
|
55
70
|
views: ['map', 'table'],
|
|
56
71
|
zoom: 2,
|
|
57
72
|
offsetX: 0,
|
|
@@ -77,6 +92,48 @@ export const Default: StoryObj<SequencesByLocationProps> = {
|
|
|
77
92
|
},
|
|
78
93
|
};
|
|
79
94
|
|
|
95
|
+
export const NoData: StoryObj<SequencesByLocationProps> = {
|
|
96
|
+
...Default,
|
|
97
|
+
parameters: {
|
|
98
|
+
fetchMock: {
|
|
99
|
+
mocks: [
|
|
100
|
+
{
|
|
101
|
+
matcher: {
|
|
102
|
+
name: 'worldMap',
|
|
103
|
+
url: worldMapUrl,
|
|
104
|
+
},
|
|
105
|
+
response: {
|
|
106
|
+
status: 200,
|
|
107
|
+
body: worldAtlas,
|
|
108
|
+
},
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
matcher: {
|
|
112
|
+
name: 'aggregatedData',
|
|
113
|
+
url: AGGREGATED_ENDPOINT,
|
|
114
|
+
body: {
|
|
115
|
+
fields: ['country'],
|
|
116
|
+
dateFrom: '2022-01-01',
|
|
117
|
+
dateTo: '2022-04-01',
|
|
118
|
+
},
|
|
119
|
+
},
|
|
120
|
+
response: {
|
|
121
|
+
status: 200,
|
|
122
|
+
body: { data: [] },
|
|
123
|
+
},
|
|
124
|
+
},
|
|
125
|
+
],
|
|
126
|
+
},
|
|
127
|
+
},
|
|
128
|
+
play: async ({ canvasElement }) => {
|
|
129
|
+
const canvas = within(canvasElement);
|
|
130
|
+
|
|
131
|
+
await waitFor(async () => {
|
|
132
|
+
await expect(canvas.getByText('No data available.')).toBeVisible();
|
|
133
|
+
});
|
|
134
|
+
},
|
|
135
|
+
};
|
|
136
|
+
|
|
80
137
|
export const InvalidTopoJsonTopology: StoryObj<SequencesByLocationProps> = {
|
|
81
138
|
...Default,
|
|
82
139
|
parameters: {
|
|
@@ -20,7 +20,9 @@ import { ResizeContainer } from '../components/resize-container';
|
|
|
20
20
|
import { useQuery } from '../useQuery';
|
|
21
21
|
import { mapSourceSchema } from './loadMapSource';
|
|
22
22
|
import { lapisFilterSchema, views } from '../../types';
|
|
23
|
+
import { NoDataDisplay } from '../components/no-data-display';
|
|
23
24
|
import Tabs from '../components/tabs';
|
|
25
|
+
import { getMaintainAspectRatio } from '../shared/charts/getMaintainAspectRatio';
|
|
24
26
|
|
|
25
27
|
export const sequencesByLocationViewSchema = z.union([z.literal(views.map), z.literal(views.table)]);
|
|
26
28
|
export type SequencesByLocationMapView = z.infer<typeof sequencesByLocationViewSchema>;
|
|
@@ -31,7 +33,7 @@ const sequencesByLocationPropsSchema = z.object({
|
|
|
31
33
|
mapSource: mapSourceSchema.optional(),
|
|
32
34
|
enableMapNavigation: z.boolean(),
|
|
33
35
|
width: z.string(),
|
|
34
|
-
height: z.string(),
|
|
36
|
+
height: z.string().optional(),
|
|
35
37
|
views: z.array(sequencesByLocationViewSchema),
|
|
36
38
|
zoom: z.number(),
|
|
37
39
|
offsetX: z.number(),
|
|
@@ -75,6 +77,10 @@ const SequencesByLocationMapInner: FunctionComponent<SequencesByLocationProps> =
|
|
|
75
77
|
throw error;
|
|
76
78
|
}
|
|
77
79
|
|
|
80
|
+
if (data.tableData.length === 0) {
|
|
81
|
+
return <NoDataDisplay />;
|
|
82
|
+
}
|
|
83
|
+
|
|
78
84
|
return <SequencesByLocationMapTabs data={data} originalComponentProps={props} />;
|
|
79
85
|
};
|
|
80
86
|
|
|
@@ -87,6 +93,8 @@ const SequencesByLocationMapTabs: FunctionComponent<SequencesByLocationMapTabsPr
|
|
|
87
93
|
originalComponentProps,
|
|
88
94
|
data,
|
|
89
95
|
}) => {
|
|
96
|
+
const maintainAspectRatio = getMaintainAspectRatio(originalComponentProps.height);
|
|
97
|
+
|
|
90
98
|
const getTab = (view: SequencesByLocationMapView) => {
|
|
91
99
|
switch (view) {
|
|
92
100
|
case views.map: {
|
|
@@ -105,6 +113,7 @@ const SequencesByLocationMapTabs: FunctionComponent<SequencesByLocationMapTabsPr
|
|
|
105
113
|
offsetX={originalComponentProps.offsetX}
|
|
106
114
|
offsetY={originalComponentProps.offsetY}
|
|
107
115
|
hasTableView={originalComponentProps.views.includes(views.table)}
|
|
116
|
+
maintainAspectRatio={maintainAspectRatio}
|
|
108
117
|
/>
|
|
109
118
|
),
|
|
110
119
|
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type PropsWithChildren } from 'react';
|
|
2
|
+
|
|
3
|
+
export function AspectRatio({ children, aspectRatio }: PropsWithChildren<{ aspectRatio?: number }>) {
|
|
4
|
+
if (aspectRatio === undefined) {
|
|
5
|
+
return children;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
return (
|
|
9
|
+
<div class={`w-full relative`} style={{ paddingTop: `${aspectRatio}%` }}>
|
|
10
|
+
<div className='absolute inset-0'>{children}</div>
|
|
11
|
+
</div>
|
|
12
|
+
);
|
|
13
|
+
}
|
|
@@ -13,7 +13,7 @@ import { useQuery } from '../useQuery';
|
|
|
13
13
|
|
|
14
14
|
const statisticsPropsSchema = z.object({
|
|
15
15
|
width: z.string(),
|
|
16
|
-
height: z.string(),
|
|
16
|
+
height: z.string().optional(),
|
|
17
17
|
numeratorFilter: lapisFilterSchema,
|
|
18
18
|
denominatorFilter: lapisFilterSchema,
|
|
19
19
|
});
|
|
@@ -62,17 +62,17 @@ type MetricDataTabsProps = {
|
|
|
62
62
|
const MetricDataTabs: FunctionComponent<MetricDataTabsProps> = ({ data }) => {
|
|
63
63
|
const { count, proportion } = data;
|
|
64
64
|
return (
|
|
65
|
-
<div className='flex flex-col sm:flex-row rounded-md border-2 border-gray-100'>
|
|
65
|
+
<div className='flex flex-col sm:flex-row rounded-md border-2 border-gray-100 min-w-[180px]'>
|
|
66
66
|
<div className='stat'>
|
|
67
67
|
<div className='stat-title'>Sequences</div>
|
|
68
68
|
<div className='stat-value text-2xl sm:text-4xl'>{count.toLocaleString('en-us')}</div>
|
|
69
|
-
<div className='stat-desc'>The total number of sequenced samples</div>
|
|
69
|
+
<div className='stat-desc text-wrap'>The total number of sequenced samples</div>
|
|
70
70
|
</div>
|
|
71
71
|
|
|
72
72
|
<div className='stat'>
|
|
73
73
|
<div className='stat-title'>Overall proportion</div>
|
|
74
74
|
<div className='stat-value text-2xl sm:text-4xl'>{formatProportion(proportion)}</div>
|
|
75
|
-
<div className='stat-desc'>The proportion among all sequenced samples</div>
|
|
75
|
+
<div className='stat-desc text-wrap'>The proportion among all sequenced samples</div>
|
|
76
76
|
</div>
|
|
77
77
|
</div>
|
|
78
78
|
);
|
|
@@ -2,7 +2,7 @@ import type { FeatureCollection, GeometryObject } from 'geojson';
|
|
|
2
2
|
import { describe, expect, test } from 'vitest';
|
|
3
3
|
|
|
4
4
|
import { computeMapLocationData } from './computeMapLocationData';
|
|
5
|
-
import type { GeoJsonFeatureProperties } from '../preact/
|
|
5
|
+
import type { GeoJsonFeatureProperties } from '../preact/sequencesByLocation/loadMapSource';
|
|
6
6
|
|
|
7
7
|
const lapisLocationField = 'locationField';
|
|
8
8
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Feature, FeatureCollection, GeometryObject } from 'geojson';
|
|
2
2
|
|
|
3
3
|
import type { AggregateData } from './queryAggregateData';
|
|
4
|
-
import type { GeoJsonFeatureProperties } from '../preact/
|
|
4
|
+
import type { GeoJsonFeatureProperties } from '../preact/sequencesByLocation/loadMapSource';
|
|
5
5
|
|
|
6
6
|
export type FeatureData = { proportion: number; count: number };
|
|
7
7
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { computeMapLocationData } from './computeMapLocationData';
|
|
2
2
|
import { queryAggregateData } from './queryAggregateData';
|
|
3
|
-
import { loadMapSource, type MapSource } from '../preact/
|
|
3
|
+
import { loadMapSource, type MapSource } from '../preact/sequencesByLocation/loadMapSource';
|
|
4
4
|
import type { LapisFilter } from '../types';
|
|
5
5
|
|
|
6
6
|
export async function querySequencesByLocationData(
|
package/src/utilEntrypoint.ts
CHANGED
|
@@ -27,7 +27,7 @@ export type {
|
|
|
27
27
|
RelativeGrowthAdvantageProps,
|
|
28
28
|
} from './preact/relativeGrowthAdvantage/relative-growth-advantage';
|
|
29
29
|
export type { StatisticsProps } from './preact/statistic/statistics';
|
|
30
|
-
export type { MapSource } from './preact/
|
|
30
|
+
export type { MapSource } from './preact/sequencesByLocation/loadMapSource';
|
|
31
31
|
|
|
32
32
|
export type { ConfidenceIntervalMethod } from './preact/shared/charts/confideceInterval';
|
|
33
33
|
|
|
@@ -8,7 +8,7 @@ import { lapisContext } from './lapis-context';
|
|
|
8
8
|
import { referenceGenomeContext } from './reference-genome-context';
|
|
9
9
|
import { type ReferenceGenome } from '../lapisApi/ReferenceGenome';
|
|
10
10
|
import { LapisUrlContextProvider } from '../preact/LapisUrlContext';
|
|
11
|
-
import { ReferenceGenomeContext } from '../preact/ReferenceGenomeContext';
|
|
11
|
+
import { INITIAL_REFERENCE_GENOMES, ReferenceGenomeContext } from '../preact/ReferenceGenomeContext';
|
|
12
12
|
import minMaxPercentSliderCss from '../preact/components/min-max-percent-slider.css?inline';
|
|
13
13
|
import tailwindStyle from '../styles/tailwind.css?inline';
|
|
14
14
|
|
|
@@ -40,10 +40,7 @@ export abstract class PreactLitAdapter extends ReactiveElement {
|
|
|
40
40
|
* This value will automatically be injected by the parent `gs-app` component.
|
|
41
41
|
*/
|
|
42
42
|
@consume({ context: referenceGenomeContext, subscribe: true })
|
|
43
|
-
referenceGenome: ReferenceGenome =
|
|
44
|
-
nucleotideSequences: [],
|
|
45
|
-
genes: [],
|
|
46
|
-
};
|
|
43
|
+
referenceGenome: ReferenceGenome = INITIAL_REFERENCE_GENOMES;
|
|
47
44
|
|
|
48
45
|
override update(changedProperties: PropertyValues) {
|
|
49
46
|
const vdom = (
|
|
@@ -5,7 +5,10 @@ import { Meta } from '@storybook/blocks';
|
|
|
5
5
|
# Size of components
|
|
6
6
|
|
|
7
7
|
All visualization and input components can be provided with a width prop (or height, when applicable) to control the size of the component.
|
|
8
|
-
If not provided, the default
|
|
8
|
+
If the width is not provided, the default is used. In most cases, the default is a width of '100%' of its parent container.
|
|
9
|
+
If the height is not set, the component takes up as much space as needed in the vertical direction.
|
|
10
|
+
For table views, this includes showing the complete table.
|
|
11
|
+
For diagrams, a fixed aspect ratio of 2:1 (width/height) is used.
|
|
9
12
|
|
|
10
13
|
Both width and height can be set using the css units (e.g. 'px', 'em', 'rem', '%', 'vh', 'vw', etc.).
|
|
11
14
|
By using '%', the size of the component can be controlled by the parent component.
|
|
@@ -9,6 +9,7 @@ import { lapisContext } from './lapis-context';
|
|
|
9
9
|
import { referenceGenomeContext } from './reference-genome-context';
|
|
10
10
|
import { type ReferenceGenome } from '../lapisApi/ReferenceGenome';
|
|
11
11
|
import { fetchReferenceGenome } from '../lapisApi/lapisApi';
|
|
12
|
+
import { INITIAL_REFERENCE_GENOMES } from '../preact/ReferenceGenomeContext';
|
|
12
13
|
|
|
13
14
|
const lapisUrlSchema = z.string().url();
|
|
14
15
|
|
|
@@ -43,10 +44,7 @@ export class AppComponent extends LitElement {
|
|
|
43
44
|
* @internal
|
|
44
45
|
*/
|
|
45
46
|
@provide({ context: referenceGenomeContext })
|
|
46
|
-
referenceGenome: ReferenceGenome =
|
|
47
|
-
nucleotideSequences: [],
|
|
48
|
-
genes: [],
|
|
49
|
-
};
|
|
47
|
+
referenceGenome: ReferenceGenome = INITIAL_REFERENCE_GENOMES;
|
|
50
48
|
|
|
51
49
|
/**
|
|
52
50
|
* @internal
|
|
@@ -54,7 +54,7 @@ const meta: Meta<Required<AggregateProps>> = {
|
|
|
54
54
|
|
|
55
55
|
export default meta;
|
|
56
56
|
|
|
57
|
-
export const
|
|
57
|
+
export const Default: StoryObj<Required<AggregateProps>> = {
|
|
58
58
|
render: (args) => html`
|
|
59
59
|
<gs-app lapis="${LAPIS_URL}">
|
|
60
60
|
<gs-aggregate
|
|
@@ -97,7 +97,6 @@ export const Table: StoryObj<Required<AggregateProps>> = {
|
|
|
97
97
|
country: 'USA',
|
|
98
98
|
},
|
|
99
99
|
width: '100%',
|
|
100
|
-
height: '700px',
|
|
101
100
|
initialSortField: 'count',
|
|
102
101
|
initialSortDirection: 'descending',
|
|
103
102
|
pageSize: 10,
|
|
@@ -105,10 +104,18 @@ export const Table: StoryObj<Required<AggregateProps>> = {
|
|
|
105
104
|
},
|
|
106
105
|
};
|
|
107
106
|
|
|
107
|
+
export const WithFixedHeight: StoryObj<Required<AggregateProps>> = {
|
|
108
|
+
...Default,
|
|
109
|
+
args: {
|
|
110
|
+
...Default.args,
|
|
111
|
+
height: '700px',
|
|
112
|
+
},
|
|
113
|
+
};
|
|
114
|
+
|
|
108
115
|
export const BarChartWithOneField: StoryObj<Required<AggregateProps>> = {
|
|
109
|
-
...
|
|
116
|
+
...Default,
|
|
110
117
|
args: {
|
|
111
|
-
...
|
|
118
|
+
...Default.args,
|
|
112
119
|
fields: ['division'],
|
|
113
120
|
views: ['bar', 'table'],
|
|
114
121
|
},
|
|
@@ -135,9 +142,9 @@ export const BarChartWithOneField: StoryObj<Required<AggregateProps>> = {
|
|
|
135
142
|
};
|
|
136
143
|
|
|
137
144
|
export const BarChartWithTwoFields: StoryObj<Required<AggregateProps>> = {
|
|
138
|
-
...
|
|
145
|
+
...Default,
|
|
139
146
|
args: {
|
|
140
|
-
...
|
|
147
|
+
...Default.args,
|
|
141
148
|
fields: ['division', 'nextstrainClade'],
|
|
142
149
|
lapisFilter: {
|
|
143
150
|
country: 'Germany',
|
|
@@ -75,7 +75,7 @@ export class AggregateComponent extends PreactLitAdapterWithGridJsStyles {
|
|
|
75
75
|
* Visit https://genspectrum.github.io/dashboard-components/?path=/docs/components-size-of-components--docs for more information.
|
|
76
76
|
*/
|
|
77
77
|
@property({ type: String })
|
|
78
|
-
height: string =
|
|
78
|
+
height: string | undefined = undefined;
|
|
79
79
|
|
|
80
80
|
/**
|
|
81
81
|
* The field by which the table is initially sorted.
|
|
@@ -89,7 +89,6 @@ export const Default: StoryObj<Required<MutationComparisonProps>> = {
|
|
|
89
89
|
sequenceType: 'nucleotide',
|
|
90
90
|
views: ['table', 'venn'],
|
|
91
91
|
width: '100%',
|
|
92
|
-
height: '700px',
|
|
93
92
|
pageSize: 10,
|
|
94
93
|
},
|
|
95
94
|
parameters: {
|
|
@@ -162,3 +161,11 @@ export const VennDiagram: StoryObj<Required<MutationComparisonProps>> = {
|
|
|
162
161
|
});
|
|
163
162
|
},
|
|
164
163
|
};
|
|
164
|
+
|
|
165
|
+
export const WithFixedHeight: StoryObj<Required<MutationComparisonProps>> = {
|
|
166
|
+
...Default,
|
|
167
|
+
args: {
|
|
168
|
+
...Default.args,
|
|
169
|
+
height: '700px',
|
|
170
|
+
},
|
|
171
|
+
};
|
|
@@ -79,7 +79,7 @@ export class MutationComparisonComponent extends PreactLitAdapterWithGridJsStyle
|
|
|
79
79
|
* Visit https://genspectrum.github.io/dashboard-components/?path=/docs/components-size-of-components--docs for more information.
|
|
80
80
|
*/
|
|
81
81
|
@property({ type: String })
|
|
82
|
-
height: string =
|
|
82
|
+
height: string | undefined = undefined;
|
|
83
83
|
|
|
84
84
|
/**
|
|
85
85
|
* The maximum number of rows to display in the table view.
|
|
@@ -16,6 +16,7 @@ const codeExample = String.raw`
|
|
|
16
16
|
height='700px'
|
|
17
17
|
granularity="month"
|
|
18
18
|
lapisDateField="date"
|
|
19
|
+
displayMutations='["A23403G","C241T"]'
|
|
19
20
|
></gs-mutations-over-time>`;
|
|
20
21
|
|
|
21
22
|
const meta: Meta<Required<MutationsOverTimeProps>> = {
|
|
@@ -38,15 +39,17 @@ const meta: Meta<Required<MutationsOverTimeProps>> = {
|
|
|
38
39
|
control: { type: 'radio' },
|
|
39
40
|
},
|
|
40
41
|
lapisDateField: { control: 'text' },
|
|
42
|
+
displayMutations: { control: 'object' },
|
|
43
|
+
initialMeanProportionInterval: { control: 'object' },
|
|
41
44
|
},
|
|
42
45
|
args: {
|
|
43
46
|
lapisFilter: { pangoLineage: 'JN.1*', dateFrom: '2024-01-15', dateTo: '2024-07-10' },
|
|
44
47
|
sequenceType: 'nucleotide',
|
|
45
48
|
views: ['grid'],
|
|
46
49
|
width: '100%',
|
|
47
|
-
height: '700px',
|
|
48
50
|
granularity: 'month',
|
|
49
51
|
lapisDateField: 'date',
|
|
52
|
+
initialMeanProportionInterval: { min: 0.05, max: 0.9 },
|
|
50
53
|
},
|
|
51
54
|
parameters: withComponentDocs({
|
|
52
55
|
componentDocs: {
|
|
@@ -72,6 +75,8 @@ const Template: StoryObj<Required<MutationsOverTimeProps>> = {
|
|
|
72
75
|
.height=${args.height}
|
|
73
76
|
.granularity=${args.granularity}
|
|
74
77
|
.lapisDateField=${args.lapisDateField}
|
|
78
|
+
.displayMutations=${args.displayMutations}
|
|
79
|
+
.initialMeanProportionInterval=${args.initialMeanProportionInterval}
|
|
75
80
|
></gs-mutations-over-time>
|
|
76
81
|
</gs-app>
|
|
77
82
|
`,
|
|
@@ -82,6 +87,15 @@ export const ByMonth: StoryObj<Required<MutationsOverTimeProps>> = {
|
|
|
82
87
|
...Template,
|
|
83
88
|
};
|
|
84
89
|
|
|
90
|
+
// This test uses mock data: defaultMockData.ts (through mutationOverTimeWorker.mock.ts)
|
|
91
|
+
export const ByMonthWithFilterOnDisplayedMutations: StoryObj<Required<MutationsOverTimeProps>> = {
|
|
92
|
+
...Template,
|
|
93
|
+
args: {
|
|
94
|
+
...Template.args,
|
|
95
|
+
displayMutations: ['A19722G', 'G21641T', 'T21653-'],
|
|
96
|
+
},
|
|
97
|
+
};
|
|
98
|
+
|
|
85
99
|
// This test uses mock data: byWeek.ts (through mutationOverTimeWorker.mock.ts)
|
|
86
100
|
export const ByWeek: StoryObj<Required<MutationsOverTimeProps>> = {
|
|
87
101
|
...Template,
|
|
@@ -111,3 +125,12 @@ export const HideProportionOnSmallScreen: StoryObj<Required<MutationsOverTimePro
|
|
|
111
125
|
width: '300px',
|
|
112
126
|
},
|
|
113
127
|
};
|
|
128
|
+
|
|
129
|
+
// This test uses mock data: defaultMockData.ts (through mutationOverTimeWorker.mock.ts)
|
|
130
|
+
export const WithFixedHeight: StoryObj<Required<MutationsOverTimeProps>> = {
|
|
131
|
+
...Template,
|
|
132
|
+
args: {
|
|
133
|
+
...Template,
|
|
134
|
+
height: '700px',
|
|
135
|
+
},
|
|
136
|
+
};
|
|
@@ -29,6 +29,10 @@ import { PreactLitAdapterWithGridJsStyles } from '../PreactLitAdapterWithGridJsS
|
|
|
29
29
|
*
|
|
30
30
|
* The number of rows is limited to 100.
|
|
31
31
|
* If there are more, the component will only show 100 mutations and notify the user.
|
|
32
|
+
*
|
|
33
|
+
* Users can filter the displayed rows by mean proportion via a slider in the toolbar.
|
|
34
|
+
* The mean proportion of each row is calculated by LAPIS over the whole data range that the component displays.
|
|
35
|
+
* The initial mean proportion can be set via `initialMeanProportionInterval`.
|
|
32
36
|
*/
|
|
33
37
|
@customElement('gs-mutations-over-time')
|
|
34
38
|
export class MutationsOverTimeComponent extends PreactLitAdapterWithGridJsStyles {
|
|
@@ -69,7 +73,7 @@ export class MutationsOverTimeComponent extends PreactLitAdapterWithGridJsStyles
|
|
|
69
73
|
* Visit https://genspectrum.github.io/dashboard-components/?path=/docs/components-size-of-components--docs for more information.
|
|
70
74
|
*/
|
|
71
75
|
@property({ type: String })
|
|
72
|
-
height: string =
|
|
76
|
+
height: string | undefined = undefined;
|
|
73
77
|
|
|
74
78
|
/**
|
|
75
79
|
* The granularity of the time axis.
|
|
@@ -87,6 +91,20 @@ export class MutationsOverTimeComponent extends PreactLitAdapterWithGridJsStyles
|
|
|
87
91
|
@property({ type: String })
|
|
88
92
|
lapisDateField: string = 'date';
|
|
89
93
|
|
|
94
|
+
/**
|
|
95
|
+
* If provided, only the given mutations will be displayed.
|
|
96
|
+
* The mutations must be provided in the exact format as they would be displayed by the component.
|
|
97
|
+
*/
|
|
98
|
+
@property({ type: Array })
|
|
99
|
+
displayMutations: string[] | undefined = undefined;
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* The initial proportion interval for the grid view.
|
|
103
|
+
* The values must be between 0 and 1, inclusive.
|
|
104
|
+
*/
|
|
105
|
+
@property({ type: Object })
|
|
106
|
+
initialMeanProportionInterval: { min: number; max: number } = { min: 0.05, max: 0.9 };
|
|
107
|
+
|
|
90
108
|
override render() {
|
|
91
109
|
return (
|
|
92
110
|
<MutationsOverTime
|
|
@@ -97,6 +115,8 @@ export class MutationsOverTimeComponent extends PreactLitAdapterWithGridJsStyles
|
|
|
97
115
|
height={this.height}
|
|
98
116
|
granularity={this.granularity}
|
|
99
117
|
lapisDateField={this.lapisDateField}
|
|
118
|
+
displayMutations={this.displayMutations}
|
|
119
|
+
initialMeanProportionInterval={this.initialMeanProportionInterval}
|
|
100
120
|
/>
|
|
101
121
|
);
|
|
102
122
|
}
|
|
@@ -135,4 +155,13 @@ type GranularityMatches = Expect<
|
|
|
135
155
|
type LapisDateFieldMatches = Expect<
|
|
136
156
|
Equals<typeof MutationsOverTimeComponent.prototype.lapisDateField, MutationsOverTimeProps['lapisDateField']>
|
|
137
157
|
>;
|
|
158
|
+
type DisplayMutationsMatches = Expect<
|
|
159
|
+
Equals<typeof MutationsOverTimeComponent.prototype.displayMutations, MutationsOverTimeProps['displayMutations']>
|
|
160
|
+
>;
|
|
161
|
+
type InitialMeanProportionIntervalMatches = Expect<
|
|
162
|
+
Equals<
|
|
163
|
+
typeof MutationsOverTimeComponent.prototype.initialMeanProportionInterval,
|
|
164
|
+
MutationsOverTimeProps['initialMeanProportionInterval']
|
|
165
|
+
>
|
|
166
|
+
>;
|
|
138
167
|
/* eslint-enable @typescript-eslint/no-unused-vars, no-unused-vars */
|
|
@@ -54,7 +54,6 @@ const meta: Meta<Required<MutationsProps>> = {
|
|
|
54
54
|
sequenceType: 'nucleotide',
|
|
55
55
|
views: ['grid', 'table', 'insertions'],
|
|
56
56
|
width: '100%',
|
|
57
|
-
height: '700px',
|
|
58
57
|
pageSize: 10,
|
|
59
58
|
},
|
|
60
59
|
parameters: withComponentDocs({
|
|
@@ -189,3 +188,11 @@ export const OnInsertionsTab: StoryObj<Required<MutationsProps>> = {
|
|
|
189
188
|
await fireEvent.click(canvas.getByRole('button', { name: 'Insertions' }));
|
|
190
189
|
},
|
|
191
190
|
};
|
|
191
|
+
|
|
192
|
+
export const WithFixedHeight: StoryObj<Required<MutationsProps>> = {
|
|
193
|
+
...Default,
|
|
194
|
+
args: {
|
|
195
|
+
...Default.args,
|
|
196
|
+
height: '700px',
|
|
197
|
+
},
|
|
198
|
+
};
|
|
@@ -111,7 +111,7 @@ export class MutationsComponent extends PreactLitAdapterWithGridJsStyles {
|
|
|
111
111
|
* Visit https://genspectrum.github.io/dashboard-components/?path=/docs/components-size-of-components--docs for more information.
|
|
112
112
|
*/
|
|
113
113
|
@property({ type: String })
|
|
114
|
-
height: string =
|
|
114
|
+
height: string | undefined = undefined;
|
|
115
115
|
|
|
116
116
|
/**
|
|
117
117
|
* The maximum number of rows to display in the table view.
|
|
@@ -38,6 +38,9 @@ const meta: Meta<NumberSequencesOverTimeProps> = {
|
|
|
38
38
|
control: { type: 'check' },
|
|
39
39
|
},
|
|
40
40
|
pageSize: { control: 'object' },
|
|
41
|
+
height: {
|
|
42
|
+
control: 'text',
|
|
43
|
+
},
|
|
41
44
|
},
|
|
42
45
|
parameters: withComponentDocs({
|
|
43
46
|
componentDocs: {
|
|
@@ -73,7 +76,6 @@ const Template: StoryObj<NumberSequencesOverTimeProps> = {
|
|
|
73
76
|
],
|
|
74
77
|
lapisDateField: 'date',
|
|
75
78
|
width: '100%',
|
|
76
|
-
height: '700px',
|
|
77
79
|
smoothingWindow: 0,
|
|
78
80
|
granularity: 'month',
|
|
79
81
|
pageSize: 10,
|
|
@@ -239,3 +241,11 @@ export const TwoDatasetsWithNonOverlappingDates: StoryObj<NumberSequencesOverTim
|
|
|
239
241
|
},
|
|
240
242
|
},
|
|
241
243
|
};
|
|
244
|
+
|
|
245
|
+
export const WithFixedHeight: StoryObj<NumberSequencesOverTimeProps> = {
|
|
246
|
+
...Template,
|
|
247
|
+
args: {
|
|
248
|
+
...Template.args,
|
|
249
|
+
height: '700px',
|
|
250
|
+
},
|
|
251
|
+
};
|
|
@@ -72,7 +72,7 @@ export class NumberSequencesOverTimeComponent extends PreactLitAdapterWithGridJs
|
|
|
72
72
|
* Visit https://genspectrum.github.io/dashboard-components/?path=/docs/components-size-of-components--docs for more information.
|
|
73
73
|
*/
|
|
74
74
|
@property({ type: String })
|
|
75
|
-
height: string =
|
|
75
|
+
height: string | undefined = undefined;
|
|
76
76
|
|
|
77
77
|
/**
|
|
78
78
|
* The granularity of the time axis.
|