@genspectrum/dashboard-components 0.1.4 → 0.1.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 +213 -78
- package/dist/dashboard-components.js +303 -53
- package/dist/dashboard-components.js.map +1 -1
- package/dist/genspectrum-components.d.ts +288 -69
- package/dist/style.css +142 -15
- package/package.json +3 -3
- package/src/preact/aggregatedData/aggregate.stories.tsx +2 -0
- package/src/preact/aggregatedData/aggregate.tsx +9 -4
- package/src/preact/components/headline.stories.tsx +19 -1
- package/src/preact/components/headline.tsx +9 -1
- package/src/preact/components/info.stories.tsx +24 -3
- package/src/preact/components/info.tsx +49 -5
- package/src/preact/dateRangeSelector/date-range-selector.tsx +10 -10
- package/src/preact/mutationComparison/mutation-comparison.stories.tsx +3 -0
- package/src/preact/mutationComparison/mutation-comparison.tsx +3 -3
- package/src/preact/mutationFilter/mutation-filter.tsx +1 -1
- package/src/preact/mutations/mutations.stories.tsx +3 -0
- package/src/preact/mutations/mutations.tsx +9 -3
- package/src/preact/prevalenceOverTime/prevalence-over-time.stories.tsx +4 -0
- package/src/preact/prevalenceOverTime/prevalence-over-time.tsx +14 -4
- package/src/preact/relativeGrowthAdvantage/relative-growth-advantage.stories.tsx +3 -0
- package/src/preact/relativeGrowthAdvantage/relative-growth-advantage.tsx +49 -4
- package/src/web-components/display/aggregate-component.stories.ts +3 -0
- package/src/web-components/display/aggregate-component.tsx +15 -1
- package/src/web-components/display/mutation-comparison-component.stories.ts +3 -0
- package/src/web-components/display/mutation-comparison-component.tsx +7 -0
- package/src/web-components/display/mutations-component.stories.ts +27 -7
- package/src/web-components/display/mutations-component.tsx +58 -4
- package/src/web-components/display/prevalence-over-time-component.stories.ts +24 -0
- package/src/web-components/display/prevalence-over-time-component.tsx +93 -5
- package/src/web-components/display/relative-growth-advantage-component.stories.ts +21 -0
- package/src/web-components/display/relative-growth-advantage-component.tsx +54 -3
- package/src/web-components/input/date-range-selector-component.stories.ts +17 -2
- package/src/web-components/input/date-range-selector-component.tsx +57 -5
- package/src/web-components/input/mutation-filter-component.stories.ts +13 -3
- package/src/web-components/input/mutation-filter-component.tsx +50 -2
- package/src/web-components/input/text-input-component.stories.ts +14 -3
- package/src/web-components/input/text-input-component.tsx +23 -1
|
@@ -23,6 +23,7 @@ const meta: Meta<MutationsProps> = {
|
|
|
23
23
|
control: { type: 'check' },
|
|
24
24
|
},
|
|
25
25
|
size: [{ control: 'object' }],
|
|
26
|
+
headline: { control: 'text' },
|
|
26
27
|
},
|
|
27
28
|
};
|
|
28
29
|
|
|
@@ -37,6 +38,7 @@ const Template = {
|
|
|
37
38
|
sequenceType={args.sequenceType}
|
|
38
39
|
views={args.views}
|
|
39
40
|
size={args.size}
|
|
41
|
+
headline={args.headline}
|
|
40
42
|
/>
|
|
41
43
|
</ReferenceGenomeContext.Provider>
|
|
42
44
|
</LapisUrlContext.Provider>
|
|
@@ -50,6 +52,7 @@ export const Default: StoryObj<MutationsProps> = {
|
|
|
50
52
|
sequenceType: 'nucleotide',
|
|
51
53
|
views: ['grid', 'table', 'insertions'],
|
|
52
54
|
size: { width: '100%', height: '700px' },
|
|
55
|
+
headline: 'Mutations',
|
|
53
56
|
},
|
|
54
57
|
parameters: {
|
|
55
58
|
fetchMock: {
|
|
@@ -35,15 +35,21 @@ export interface MutationsProps {
|
|
|
35
35
|
sequenceType: SequenceType;
|
|
36
36
|
views: View[];
|
|
37
37
|
size?: Size;
|
|
38
|
+
headline?: string;
|
|
38
39
|
}
|
|
39
40
|
|
|
40
|
-
export const Mutations: FunctionComponent<MutationsProps> = ({
|
|
41
|
+
export const Mutations: FunctionComponent<MutationsProps> = ({
|
|
42
|
+
variant,
|
|
43
|
+
sequenceType,
|
|
44
|
+
views,
|
|
45
|
+
size,
|
|
46
|
+
headline = 'Mutations',
|
|
47
|
+
}) => {
|
|
41
48
|
const lapis = useContext(LapisUrlContext);
|
|
42
49
|
const { data, error, isLoading } = useQuery(async () => {
|
|
43
50
|
return queryMutationsData(variant, sequenceType, lapis);
|
|
44
51
|
}, [variant, sequenceType, lapis]);
|
|
45
52
|
|
|
46
|
-
const headline = 'Mutations';
|
|
47
53
|
if (isLoading) {
|
|
48
54
|
return (
|
|
49
55
|
<Headline heading={headline}>
|
|
@@ -197,7 +203,7 @@ const Toolbar: FunctionComponent<ToolbarProps> = ({
|
|
|
197
203
|
filename='insertions.csv'
|
|
198
204
|
/>
|
|
199
205
|
)}
|
|
200
|
-
<Info
|
|
206
|
+
<Info>Info for mutations</Info>
|
|
201
207
|
</div>
|
|
202
208
|
);
|
|
203
209
|
};
|
|
@@ -30,6 +30,7 @@ export default {
|
|
|
30
30
|
control: { type: 'check' },
|
|
31
31
|
},
|
|
32
32
|
size: [{ control: 'object' }],
|
|
33
|
+
headline: { control: 'text' },
|
|
33
34
|
},
|
|
34
35
|
};
|
|
35
36
|
|
|
@@ -44,6 +45,7 @@ const Template = {
|
|
|
44
45
|
views={args.views}
|
|
45
46
|
confidenceIntervalMethods={args.confidenceIntervalMethods}
|
|
46
47
|
size={args.size}
|
|
48
|
+
headline={args.headline}
|
|
47
49
|
/>
|
|
48
50
|
</LapisUrlContext.Provider>
|
|
49
51
|
),
|
|
@@ -62,6 +64,7 @@ export const TwoVariants = {
|
|
|
62
64
|
views: ['bar', 'line', 'bubble', 'table'],
|
|
63
65
|
confidenceIntervalMethods: ['wilson'],
|
|
64
66
|
size: { width: '100%', height: '700px' },
|
|
67
|
+
headline: 'Prevalence over time',
|
|
65
68
|
},
|
|
66
69
|
parameters: {
|
|
67
70
|
fetchMock: {
|
|
@@ -128,6 +131,7 @@ export const OneVariant = {
|
|
|
128
131
|
views: ['bar', 'line', 'bubble', 'table'],
|
|
129
132
|
confidenceIntervalMethods: ['wilson'],
|
|
130
133
|
size: { width: '100%', height: '700px' },
|
|
134
|
+
headline: 'Prevalence over time',
|
|
131
135
|
},
|
|
132
136
|
parameters: {
|
|
133
137
|
fetchMock: {
|
|
@@ -13,7 +13,7 @@ import { ConfidenceIntervalSelector } from '../components/confidence-interval-se
|
|
|
13
13
|
import { CsvDownloadButton } from '../components/csv-download-button';
|
|
14
14
|
import { ErrorDisplay } from '../components/error-display';
|
|
15
15
|
import Headline from '../components/headline';
|
|
16
|
-
import Info from '../components/info';
|
|
16
|
+
import Info, { InfoHeadline1, InfoParagraph } from '../components/info';
|
|
17
17
|
import { LoadingDisplay } from '../components/loading-display';
|
|
18
18
|
import { NoDataDisplay } from '../components/no-data-display';
|
|
19
19
|
import { ResizeContainer, type Size } from '../components/resize-container';
|
|
@@ -33,6 +33,7 @@ export interface PrevalenceOverTimeProps {
|
|
|
33
33
|
views: View[];
|
|
34
34
|
confidenceIntervalMethods: ConfidenceIntervalMethod[];
|
|
35
35
|
size?: Size;
|
|
36
|
+
headline?: string;
|
|
36
37
|
}
|
|
37
38
|
|
|
38
39
|
export const PrevalenceOverTime: FunctionComponent<PrevalenceOverTimeProps> = ({
|
|
@@ -43,6 +44,7 @@ export const PrevalenceOverTime: FunctionComponent<PrevalenceOverTimeProps> = ({
|
|
|
43
44
|
views,
|
|
44
45
|
confidenceIntervalMethods,
|
|
45
46
|
size,
|
|
47
|
+
headline = 'Prevalence over time',
|
|
46
48
|
}) => {
|
|
47
49
|
const lapis = useContext(LapisUrlContext);
|
|
48
50
|
|
|
@@ -51,8 +53,6 @@ export const PrevalenceOverTime: FunctionComponent<PrevalenceOverTimeProps> = ({
|
|
|
51
53
|
[lapis, numerator, denominator, granularity, smoothingWindow],
|
|
52
54
|
);
|
|
53
55
|
|
|
54
|
-
const headline = 'Prevalence over time';
|
|
55
|
-
|
|
56
56
|
if (isLoading) {
|
|
57
57
|
return (
|
|
58
58
|
<Headline heading={headline}>
|
|
@@ -202,9 +202,19 @@ const Toolbar: FunctionComponent<ToolbarProps> = ({
|
|
|
202
202
|
getData={() => getPrevalenceOverTimeTableData(data, granularity)}
|
|
203
203
|
filename='prevalence-over-time.csv'
|
|
204
204
|
/>
|
|
205
|
-
|
|
205
|
+
|
|
206
|
+
<PrevalenceOverTimeInfo />
|
|
206
207
|
</div>
|
|
207
208
|
);
|
|
208
209
|
};
|
|
209
210
|
|
|
211
|
+
const PrevalenceOverTimeInfo: FunctionComponent = () => {
|
|
212
|
+
return (
|
|
213
|
+
<Info size={{ width: '600px', height: '30vh' }}>
|
|
214
|
+
<InfoHeadline1>Prevalence over time</InfoHeadline1>
|
|
215
|
+
<InfoParagraph>Prevalence over time info.</InfoParagraph>
|
|
216
|
+
</Info>
|
|
217
|
+
);
|
|
218
|
+
};
|
|
219
|
+
|
|
210
220
|
export default PrevalenceOverTime;
|
|
@@ -19,6 +19,7 @@ export default {
|
|
|
19
19
|
control: { type: 'check' },
|
|
20
20
|
},
|
|
21
21
|
size: [{ control: 'object' }],
|
|
22
|
+
headline: { control: 'text' },
|
|
22
23
|
},
|
|
23
24
|
};
|
|
24
25
|
|
|
@@ -31,6 +32,7 @@ export const Primary = {
|
|
|
31
32
|
generationTime={args.generationTime}
|
|
32
33
|
views={args.views}
|
|
33
34
|
size={args.size}
|
|
35
|
+
headline={args.headline}
|
|
34
36
|
/>
|
|
35
37
|
</LapisUrlContext.Provider>
|
|
36
38
|
),
|
|
@@ -40,6 +42,7 @@ export const Primary = {
|
|
|
40
42
|
generationTime: 7,
|
|
41
43
|
views: ['line'],
|
|
42
44
|
size: { width: '100%', height: '700px' },
|
|
45
|
+
headline: 'Relative growth advantage',
|
|
43
46
|
},
|
|
44
47
|
parameters: {
|
|
45
48
|
fetchMock: {
|
|
@@ -10,7 +10,7 @@ import { type LapisFilter } from '../../types';
|
|
|
10
10
|
import { LapisUrlContext } from '../LapisUrlContext';
|
|
11
11
|
import { ErrorDisplay } from '../components/error-display';
|
|
12
12
|
import Headline from '../components/headline';
|
|
13
|
-
import Info from '../components/info';
|
|
13
|
+
import Info, { InfoHeadline1, InfoHeadline2, InfoLink, InfoParagraph } from '../components/info';
|
|
14
14
|
import { LoadingDisplay } from '../components/loading-display';
|
|
15
15
|
import { NoDataDisplay } from '../components/no-data-display';
|
|
16
16
|
import { ResizeContainer, type Size } from '../components/resize-container';
|
|
@@ -27,6 +27,7 @@ export interface RelativeGrowthAdvantageProps {
|
|
|
27
27
|
generationTime: number;
|
|
28
28
|
views: View[];
|
|
29
29
|
size?: Size;
|
|
30
|
+
headline?: string;
|
|
30
31
|
}
|
|
31
32
|
|
|
32
33
|
export const RelativeGrowthAdvantage: FunctionComponent<RelativeGrowthAdvantageProps> = ({
|
|
@@ -35,6 +36,7 @@ export const RelativeGrowthAdvantage: FunctionComponent<RelativeGrowthAdvantageP
|
|
|
35
36
|
generationTime,
|
|
36
37
|
views,
|
|
37
38
|
size,
|
|
39
|
+
headline = 'Relative growth advantage',
|
|
38
40
|
}) => {
|
|
39
41
|
const lapis = useContext(LapisUrlContext);
|
|
40
42
|
const [yAxisScaleType, setYAxisScaleType] = useState<ScaleType>('linear');
|
|
@@ -44,7 +46,6 @@ export const RelativeGrowthAdvantage: FunctionComponent<RelativeGrowthAdvantageP
|
|
|
44
46
|
[lapis, numerator, denominator, generationTime, views],
|
|
45
47
|
);
|
|
46
48
|
|
|
47
|
-
const headline = 'Relative growth advantage';
|
|
48
49
|
if (isLoading) {
|
|
49
50
|
return (
|
|
50
51
|
<Headline heading={headline}>
|
|
@@ -77,6 +78,7 @@ export const RelativeGrowthAdvantage: FunctionComponent<RelativeGrowthAdvantageP
|
|
|
77
78
|
yAxisScaleType={yAxisScaleType}
|
|
78
79
|
setYAxisScaleType={setYAxisScaleType}
|
|
79
80
|
views={views}
|
|
81
|
+
generationTime={generationTime}
|
|
80
82
|
/>
|
|
81
83
|
</Headline>
|
|
82
84
|
</ResizeContainer>
|
|
@@ -88,6 +90,7 @@ type RelativeGrowthAdvantageTabsProps = {
|
|
|
88
90
|
yAxisScaleType: ScaleType;
|
|
89
91
|
setYAxisScaleType: (scaleType: ScaleType) => void;
|
|
90
92
|
views: View[];
|
|
93
|
+
generationTime: number;
|
|
91
94
|
};
|
|
92
95
|
|
|
93
96
|
const RelativeGrowthAdvantageTabs: FunctionComponent<RelativeGrowthAdvantageTabsProps> = ({
|
|
@@ -95,6 +98,7 @@ const RelativeGrowthAdvantageTabs: FunctionComponent<RelativeGrowthAdvantageTabs
|
|
|
95
98
|
yAxisScaleType,
|
|
96
99
|
setYAxisScaleType,
|
|
97
100
|
views,
|
|
101
|
+
generationTime,
|
|
98
102
|
}) => {
|
|
99
103
|
const getTab = (view: View) => {
|
|
100
104
|
switch (view) {
|
|
@@ -117,7 +121,11 @@ const RelativeGrowthAdvantageTabs: FunctionComponent<RelativeGrowthAdvantageTabs
|
|
|
117
121
|
|
|
118
122
|
const tabs = views.map((view) => getTab(view));
|
|
119
123
|
const toolbar = () => (
|
|
120
|
-
<RelativeGrowthAdvantageToolbar
|
|
124
|
+
<RelativeGrowthAdvantageToolbar
|
|
125
|
+
generationTime={generationTime}
|
|
126
|
+
yAxisScaleType={yAxisScaleType}
|
|
127
|
+
setYAxisScaleType={setYAxisScaleType}
|
|
128
|
+
/>
|
|
121
129
|
);
|
|
122
130
|
|
|
123
131
|
return <Tabs tabs={tabs} toolbar={toolbar} />;
|
|
@@ -126,16 +134,53 @@ const RelativeGrowthAdvantageTabs: FunctionComponent<RelativeGrowthAdvantageTabs
|
|
|
126
134
|
type RelativeGrowthAdvantageToolbarProps = {
|
|
127
135
|
yAxisScaleType: ScaleType;
|
|
128
136
|
setYAxisScaleType: (scaleType: ScaleType) => void;
|
|
137
|
+
generationTime: number;
|
|
129
138
|
};
|
|
130
139
|
|
|
131
140
|
const RelativeGrowthAdvantageToolbar: FunctionComponent<RelativeGrowthAdvantageToolbarProps> = ({
|
|
132
141
|
yAxisScaleType,
|
|
133
142
|
setYAxisScaleType,
|
|
143
|
+
generationTime,
|
|
134
144
|
}) => {
|
|
135
145
|
return (
|
|
136
146
|
<div class='flex'>
|
|
137
147
|
<ScalingSelector yAxisScaleType={yAxisScaleType} setYAxisScaleType={setYAxisScaleType} />
|
|
138
|
-
<
|
|
148
|
+
<RelativeGrowthAdvantageInfo generationTime={generationTime} />
|
|
139
149
|
</div>
|
|
140
150
|
);
|
|
141
151
|
};
|
|
152
|
+
|
|
153
|
+
const RelativeGrowthAdvantageInfo: FunctionComponent<{ generationTime: number }> = ({ generationTime }) => {
|
|
154
|
+
return (
|
|
155
|
+
<Info size={{ width: '600px', height: '30vh' }}>
|
|
156
|
+
<InfoHeadline1>Relative growth advantage</InfoHeadline1>
|
|
157
|
+
<InfoParagraph>
|
|
158
|
+
If variants spread pre-dominantly by local transmission across demographic groups, this estimate
|
|
159
|
+
reflects the relative viral intrinsic growth advantage of the focal variant in the selected country and
|
|
160
|
+
time frame. We report the relative growth advantage per {generationTime} days (in percentage; 0% means
|
|
161
|
+
equal growth). Importantly, the relative growth advantage estimate reflects the advantage compared to
|
|
162
|
+
the co-circulating variants. Thus, as new variants spread, the advantage of the focal variant may
|
|
163
|
+
decrease. Different mechanisms can alter the intrinsic growth rate, including an intrinsic transmission
|
|
164
|
+
advantage, immune evasion, and a prolonged infectious period. When absolute numbers of a variant are
|
|
165
|
+
low, the growth advantage may merely reflect the current importance of introductions from abroad or the
|
|
166
|
+
variant spreading in a particular demographic group. In this case, the estimate does not provide
|
|
167
|
+
information on any intrinsic fitness advantages.
|
|
168
|
+
</InfoParagraph>
|
|
169
|
+
<InfoParagraph>
|
|
170
|
+
Example: Assume that 10 infections from the focal variant and 100 infections from the co-circulating
|
|
171
|
+
variants occur today and that the focal variant has a relative growth advantage of 50%. Then, if the
|
|
172
|
+
number of new infections from the co-circulating variants remains at 100 in {generationTime} days from
|
|
173
|
+
today, we expect the number of new infections from the focal variant to be 15.
|
|
174
|
+
</InfoParagraph>
|
|
175
|
+
|
|
176
|
+
<InfoHeadline2>Reference</InfoHeadline2>
|
|
177
|
+
<InfoParagraph>
|
|
178
|
+
Chen, Chaoran, et al. "Quantification of the spread of SARS-CoV-2 variant B.1.1.7 in Switzerland."
|
|
179
|
+
Epidemics (2021); doi:{' '}
|
|
180
|
+
<InfoLink href='https://www.sciencedirect.com/science/article/pii/S1755436521000335?via=ihub'>
|
|
181
|
+
10.1016/j.epidem.2021.100480
|
|
182
|
+
</InfoLink>
|
|
183
|
+
</InfoParagraph>
|
|
184
|
+
</Info>
|
|
185
|
+
);
|
|
186
|
+
};
|
|
@@ -19,6 +19,7 @@ const meta: Meta<AggregateProps> = {
|
|
|
19
19
|
control: { type: 'check' },
|
|
20
20
|
},
|
|
21
21
|
size: [{ control: 'object' }],
|
|
22
|
+
headline: { control: 'text' },
|
|
22
23
|
},
|
|
23
24
|
parameters: withComponentDocs({
|
|
24
25
|
fetchMock: {
|
|
@@ -59,6 +60,7 @@ export const Table: StoryObj<AggregateProps> = {
|
|
|
59
60
|
.filter=${args.filter}
|
|
60
61
|
.views=${args.views}
|
|
61
62
|
.size=${args.size}
|
|
63
|
+
.headline=${args.headline}
|
|
62
64
|
></gs-aggregate-component>
|
|
63
65
|
</gs-app>
|
|
64
66
|
`,
|
|
@@ -69,5 +71,6 @@ export const Table: StoryObj<AggregateProps> = {
|
|
|
69
71
|
country: 'USA',
|
|
70
72
|
},
|
|
71
73
|
size: { width: '100%', height: '700px' },
|
|
74
|
+
headline: 'Aggregate',
|
|
72
75
|
},
|
|
73
76
|
};
|
|
@@ -46,8 +46,22 @@ export class AggregateComponent extends PreactLitAdapterWithGridJsStyles {
|
|
|
46
46
|
@property({ type: Object })
|
|
47
47
|
size: { width?: string; height?: string } | undefined = undefined;
|
|
48
48
|
|
|
49
|
+
/**
|
|
50
|
+
* The headline of the component. Set to an empty string to hide the headline.
|
|
51
|
+
*/
|
|
52
|
+
@property({ type: String })
|
|
53
|
+
headline: string | undefined = 'Aggregate';
|
|
54
|
+
|
|
49
55
|
override render() {
|
|
50
|
-
return
|
|
56
|
+
return (
|
|
57
|
+
<Aggregate
|
|
58
|
+
fields={this.fields}
|
|
59
|
+
views={this.views}
|
|
60
|
+
filter={this.filter}
|
|
61
|
+
size={this.size}
|
|
62
|
+
headline={this.headline}
|
|
63
|
+
/>
|
|
64
|
+
);
|
|
51
65
|
}
|
|
52
66
|
}
|
|
53
67
|
|
|
@@ -32,6 +32,7 @@ const meta: Meta<MutationComparisonProps> = {
|
|
|
32
32
|
control: { type: 'check' },
|
|
33
33
|
},
|
|
34
34
|
size: { control: 'object' },
|
|
35
|
+
headline: { control: 'text' },
|
|
35
36
|
},
|
|
36
37
|
parameters: withComponentDocs({
|
|
37
38
|
componentDocs: {
|
|
@@ -54,6 +55,7 @@ const Template: StoryObj<MutationComparisonProps> = {
|
|
|
54
55
|
.sequenceType=${args.sequenceType}
|
|
55
56
|
.views=${args.views}
|
|
56
57
|
.size=${args.size}
|
|
58
|
+
.headline=${args.headline}
|
|
57
59
|
></gs-mutation-comparison-component>
|
|
58
60
|
</gs-app>
|
|
59
61
|
`,
|
|
@@ -83,6 +85,7 @@ export const Default: StoryObj<MutationComparisonProps> = {
|
|
|
83
85
|
sequenceType: 'nucleotide',
|
|
84
86
|
views: ['table', 'venn'],
|
|
85
87
|
size: { width: '100%', height: '700px' },
|
|
88
|
+
headline: 'Mutation comparison',
|
|
86
89
|
},
|
|
87
90
|
parameters: {
|
|
88
91
|
fetchMock: {
|
|
@@ -72,6 +72,12 @@ export class MutationComparisonComponent extends PreactLitAdapterWithGridJsStyle
|
|
|
72
72
|
@property({ type: Object })
|
|
73
73
|
size: { width?: string; height?: string } | undefined = undefined;
|
|
74
74
|
|
|
75
|
+
/**
|
|
76
|
+
* The headline of the component. Set to an empty string to hide the headline.
|
|
77
|
+
*/
|
|
78
|
+
@property({ type: String })
|
|
79
|
+
headline: string | undefined = 'Mutation comparison';
|
|
80
|
+
|
|
75
81
|
override render() {
|
|
76
82
|
return (
|
|
77
83
|
<MutationComparison
|
|
@@ -79,6 +85,7 @@ export class MutationComparisonComponent extends PreactLitAdapterWithGridJsStyle
|
|
|
79
85
|
sequenceType={this.sequenceType}
|
|
80
86
|
views={this.views}
|
|
81
87
|
size={this.size}
|
|
88
|
+
headline={this.headline}
|
|
82
89
|
/>
|
|
83
90
|
);
|
|
84
91
|
}
|
|
@@ -4,15 +4,23 @@ import { html } from 'lit';
|
|
|
4
4
|
|
|
5
5
|
import './mutations-component';
|
|
6
6
|
import '../app';
|
|
7
|
+
import { withComponentDocs } from '../../../.storybook/ComponentDocsBlock';
|
|
7
8
|
import { LAPIS_URL, NUCLEOTIDE_INSERTIONS_ENDPOINT, NUCLEOTIDE_MUTATIONS_ENDPOINT } from '../../constants';
|
|
8
9
|
import nucleotideInsertions from '../../preact/mutations/__mockData__/nucleotideInsertions.json';
|
|
9
10
|
import nucleotideMutations from '../../preact/mutations/__mockData__/nucleotideMutations.json';
|
|
10
11
|
import { type MutationsProps } from '../../preact/mutations/mutations';
|
|
11
12
|
import { withinShadowRoot } from '../withinShadowRoot.story';
|
|
12
13
|
|
|
14
|
+
const codeExample = String.raw`
|
|
15
|
+
<gs-mutations
|
|
16
|
+
variant='{ "country": "Switzerland", "pangoLineage": "B.1.1.7", "dateTo": "2022-01-01" }'
|
|
17
|
+
sequenceType="nucleotide"
|
|
18
|
+
views='["grid", "table", "insertions"]'
|
|
19
|
+
></gs-mutations>`;
|
|
20
|
+
|
|
13
21
|
const meta: Meta<MutationsProps> = {
|
|
14
22
|
title: 'Visualization/Mutations',
|
|
15
|
-
component: 'gs-mutations',
|
|
23
|
+
component: 'gs-mutations-component',
|
|
16
24
|
argTypes: {
|
|
17
25
|
variant: { control: 'object' },
|
|
18
26
|
sequenceType: {
|
|
@@ -24,7 +32,24 @@ const meta: Meta<MutationsProps> = {
|
|
|
24
32
|
control: { type: 'check' },
|
|
25
33
|
},
|
|
26
34
|
size: { control: 'object' },
|
|
35
|
+
headline: { control: 'text' },
|
|
36
|
+
},
|
|
37
|
+
args: {
|
|
38
|
+
variant: { country: 'Switzerland', pangoLineage: 'B.1.1.7', dateTo: '2022-01-01' },
|
|
39
|
+
sequenceType: 'nucleotide',
|
|
40
|
+
views: ['grid', 'table', 'insertions'],
|
|
41
|
+
size: { width: '100%', height: '700px' },
|
|
42
|
+
headline: 'Mutations',
|
|
27
43
|
},
|
|
44
|
+
parameters: withComponentDocs({
|
|
45
|
+
componentDocs: {
|
|
46
|
+
tag: 'gs-mutations-component',
|
|
47
|
+
opensShadowDom: true,
|
|
48
|
+
expectsChildren: false,
|
|
49
|
+
codeExample,
|
|
50
|
+
},
|
|
51
|
+
}),
|
|
52
|
+
tags: ['autodocs'],
|
|
28
53
|
};
|
|
29
54
|
|
|
30
55
|
export default meta;
|
|
@@ -37,6 +62,7 @@ const Template: StoryObj<MutationsProps> = {
|
|
|
37
62
|
.sequenceType=${args.sequenceType}
|
|
38
63
|
.views=${args.views}
|
|
39
64
|
.size=${args.size}
|
|
65
|
+
.headline=${args.headline}
|
|
40
66
|
></gs-mutations-component>
|
|
41
67
|
</gs-app>
|
|
42
68
|
`,
|
|
@@ -44,12 +70,6 @@ const Template: StoryObj<MutationsProps> = {
|
|
|
44
70
|
|
|
45
71
|
export const Default: StoryObj<MutationsProps> = {
|
|
46
72
|
...Template,
|
|
47
|
-
args: {
|
|
48
|
-
variant: { country: 'Switzerland', pangoLineage: 'B.1.1.7', dateTo: '2022-01-01' },
|
|
49
|
-
sequenceType: 'nucleotide',
|
|
50
|
-
views: ['grid', 'table', 'insertions'],
|
|
51
|
-
size: { width: '100%', height: '700px' },
|
|
52
|
-
},
|
|
53
73
|
parameters: {
|
|
54
74
|
fetchMock: {
|
|
55
75
|
mocks: [
|
|
@@ -2,18 +2,54 @@ import { customElement, property } from 'lit/decorators.js';
|
|
|
2
2
|
|
|
3
3
|
import { Mutations, type View } from '../../preact/mutations/mutations';
|
|
4
4
|
import { type LapisFilter, type SequenceType } from '../../types';
|
|
5
|
+
import type { Equals, Expect } from '../../utils/typeAssertions';
|
|
5
6
|
import { PreactLitAdapterWithGridJsStyles } from '../PreactLitAdapterWithGridJsStyles';
|
|
6
7
|
|
|
8
|
+
/**
|
|
9
|
+
* This component displays mutations (substitutions, deletions and insertions) for a given variant.
|
|
10
|
+
*
|
|
11
|
+
* ## Views
|
|
12
|
+
*
|
|
13
|
+
* ### Table View
|
|
14
|
+
*
|
|
15
|
+
* The table view shows all substitutions and deletions for the given variant.
|
|
16
|
+
* It shows the type (substitution or deletion), the total count of the mutation
|
|
17
|
+
* and the proportion of the mutation in the variant.
|
|
18
|
+
* The proportion is relative to the total number of sequences matching
|
|
19
|
+
* the specified sequence filters with non-ambiguous reads at that position.
|
|
20
|
+
*
|
|
21
|
+
* The proportion interval filter can be used to filter the displayed mutations on client side.
|
|
22
|
+
*
|
|
23
|
+
* ### Grid View
|
|
24
|
+
*
|
|
25
|
+
* The grid view shows the proportion of each sequence symbol (nucleotide or amino acid) for each position that has a mutation.
|
|
26
|
+
* Only positions with at least one mutation in the selected proportion interval are shown.
|
|
27
|
+
*
|
|
28
|
+
* ### Insertions View
|
|
29
|
+
*
|
|
30
|
+
* The insertions view shows the count of all insertions for the given variant.
|
|
31
|
+
*
|
|
32
|
+
*/
|
|
7
33
|
@customElement('gs-mutations-component')
|
|
8
34
|
export class MutationsComponent extends PreactLitAdapterWithGridJsStyles {
|
|
35
|
+
/**
|
|
36
|
+
* The `variant` will be sent as is to LAPIS to filter the mutation data.
|
|
37
|
+
* It must be a valid LAPIS filter object.
|
|
38
|
+
*/
|
|
9
39
|
@property({ type: Object })
|
|
10
|
-
variant:
|
|
40
|
+
variant: Record<string, string | number | null | boolean> = { displayName: '' };
|
|
11
41
|
|
|
42
|
+
/**
|
|
43
|
+
* The type of the sequence for which the mutations should be shown.
|
|
44
|
+
*/
|
|
12
45
|
@property({ type: String })
|
|
13
|
-
sequenceType:
|
|
46
|
+
sequenceType: 'nucleotide' | 'amino acid' = 'nucleotide';
|
|
14
47
|
|
|
48
|
+
/**
|
|
49
|
+
* A list of tabs with views that this component should provide.
|
|
50
|
+
*/
|
|
15
51
|
@property({ type: Array })
|
|
16
|
-
views:
|
|
52
|
+
views: ('table' | 'grid' | 'insertions')[] = ['table', 'grid'];
|
|
17
53
|
|
|
18
54
|
/**
|
|
19
55
|
* The size of the component.
|
|
@@ -26,9 +62,21 @@ export class MutationsComponent extends PreactLitAdapterWithGridJsStyles {
|
|
|
26
62
|
@property({ type: Object })
|
|
27
63
|
size: { width?: string; height?: string } | undefined = undefined;
|
|
28
64
|
|
|
65
|
+
/**
|
|
66
|
+
* The headline of the component. Set to an empty string to hide the headline.
|
|
67
|
+
*/
|
|
68
|
+
@property({ type: String })
|
|
69
|
+
headline: string | undefined = 'Mutations';
|
|
70
|
+
|
|
29
71
|
override render() {
|
|
30
72
|
return (
|
|
31
|
-
<Mutations
|
|
73
|
+
<Mutations
|
|
74
|
+
variant={this.variant}
|
|
75
|
+
sequenceType={this.sequenceType}
|
|
76
|
+
views={this.views}
|
|
77
|
+
size={this.size}
|
|
78
|
+
headline={this.headline}
|
|
79
|
+
/>
|
|
32
80
|
);
|
|
33
81
|
}
|
|
34
82
|
}
|
|
@@ -38,3 +86,9 @@ declare global {
|
|
|
38
86
|
'gs-mutations-component': MutationsComponent;
|
|
39
87
|
}
|
|
40
88
|
}
|
|
89
|
+
|
|
90
|
+
/* eslint-disable @typescript-eslint/no-unused-vars, no-unused-vars */
|
|
91
|
+
type VariantsMatches = Expect<Equals<typeof MutationsComponent.prototype.variant, LapisFilter>>;
|
|
92
|
+
type SequenceTypeMatches = Expect<Equals<typeof MutationsComponent.prototype.sequenceType, SequenceType>>;
|
|
93
|
+
type ViewsMatches = Expect<Equals<typeof MutationsComponent.prototype.views, View[]>>;
|
|
94
|
+
/* eslint-enable @typescript-eslint/no-unused-vars, no-unused-vars */
|
|
@@ -4,6 +4,7 @@ import { html } from 'lit';
|
|
|
4
4
|
|
|
5
5
|
import '../app';
|
|
6
6
|
import './prevalence-over-time-component';
|
|
7
|
+
import { withComponentDocs } from '../../../.storybook/ComponentDocsBlock';
|
|
7
8
|
import { AGGREGATED_ENDPOINT, LAPIS_URL } from '../../constants';
|
|
8
9
|
import denominator from '../../preact/prevalenceOverTime/__mockData__/denominator.json';
|
|
9
10
|
import denominatorOneVariant from '../../preact/prevalenceOverTime/__mockData__/denominatorOneVariant.json';
|
|
@@ -13,6 +14,16 @@ import numeratorOneVariant from '../../preact/prevalenceOverTime/__mockData__/nu
|
|
|
13
14
|
import { type PrevalenceOverTimeProps } from '../../preact/prevalenceOverTime/prevalence-over-time';
|
|
14
15
|
import { withinShadowRoot } from '../withinShadowRoot.story';
|
|
15
16
|
|
|
17
|
+
const codeExample = String.raw`
|
|
18
|
+
<gs-prevalence-over-time
|
|
19
|
+
numerator='[{ "displayName": "EG", "country": "USA", "pangoLineage": "EG*" }, { "displayName": "JN.1", "country": "USA", "pangoLineage": "JN.1*" }]'
|
|
20
|
+
denominator='{ "country": "USA", "displayName": "All" }'
|
|
21
|
+
granularity="month"
|
|
22
|
+
smoothingWindow="0"
|
|
23
|
+
views='["bar", "line", "bubble", "table"]'
|
|
24
|
+
confidenceIntervalMethods='["wilson"]'
|
|
25
|
+
></gs-prevalence-over-time>`;
|
|
26
|
+
|
|
16
27
|
const meta: Meta<PrevalenceOverTimeProps> = {
|
|
17
28
|
title: 'Visualization/Prevalence over time',
|
|
18
29
|
component: 'gs-prevalence-over-time',
|
|
@@ -33,7 +44,17 @@ const meta: Meta<PrevalenceOverTimeProps> = {
|
|
|
33
44
|
control: { type: 'check' },
|
|
34
45
|
},
|
|
35
46
|
size: [{ control: 'object' }],
|
|
47
|
+
headline: { control: 'text' },
|
|
36
48
|
},
|
|
49
|
+
parameters: withComponentDocs({
|
|
50
|
+
componentDocs: {
|
|
51
|
+
tag: 'gs-prevalence-over-time',
|
|
52
|
+
opensShadowDom: true,
|
|
53
|
+
expectsChildren: false,
|
|
54
|
+
codeExample,
|
|
55
|
+
},
|
|
56
|
+
}),
|
|
57
|
+
tags: ['autodocs'],
|
|
37
58
|
};
|
|
38
59
|
|
|
39
60
|
export default meta;
|
|
@@ -49,6 +70,7 @@ const Template: StoryObj<PrevalenceOverTimeProps> = {
|
|
|
49
70
|
.views=${args.views}
|
|
50
71
|
.confidenceIntervalMethods=${args.confidenceIntervalMethods}
|
|
51
72
|
.size=${args.size}
|
|
73
|
+
.headline=${args.headline}
|
|
52
74
|
></gs-prevalence-over-time>
|
|
53
75
|
</gs-app>
|
|
54
76
|
`,
|
|
@@ -67,6 +89,7 @@ export const TwoVariants: StoryObj<PrevalenceOverTimeProps> = {
|
|
|
67
89
|
views: ['bar', 'line', 'bubble', 'table'],
|
|
68
90
|
confidenceIntervalMethods: ['wilson'],
|
|
69
91
|
size: { width: '100%', height: '700px' },
|
|
92
|
+
headline: 'Prevalence over time',
|
|
70
93
|
},
|
|
71
94
|
parameters: {
|
|
72
95
|
fetchMock: {
|
|
@@ -133,6 +156,7 @@ export const OneVariant: StoryObj<PrevalenceOverTimeProps> = {
|
|
|
133
156
|
views: ['bar', 'line', 'bubble', 'table'],
|
|
134
157
|
confidenceIntervalMethods: ['wilson'],
|
|
135
158
|
size: { width: '100%', height: '700px' },
|
|
159
|
+
headline: 'Prevalence over time',
|
|
136
160
|
},
|
|
137
161
|
parameters: {
|
|
138
162
|
fetchMock: {
|