@genspectrum/dashboard-components 0.19.4 → 0.19.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.
Files changed (54) hide show
  1. package/custom-elements.json +99 -0
  2. package/dist/{LineageFilterChangedEvent-GgkxoF3X.js → LineageFilterChangedEvent-Cqa8Frcf.js} +2 -1
  3. package/dist/{LineageFilterChangedEvent-GgkxoF3X.js.map → LineageFilterChangedEvent-Cqa8Frcf.js.map} +1 -1
  4. package/dist/assets/mutationOverTimeWorker-DQGh08AS.js.map +1 -0
  5. package/dist/components.d.ts +64 -33
  6. package/dist/components.js +82 -22
  7. package/dist/components.js.map +1 -1
  8. package/dist/util.d.ts +47 -33
  9. package/dist/util.js +1 -1
  10. package/package.json +1 -1
  11. package/src/preact/aggregatedData/aggregate.stories.tsx +6 -0
  12. package/src/preact/aggregatedData/aggregate.tsx +10 -1
  13. package/src/preact/components/tabs.tsx +4 -4
  14. package/src/preact/genomeViewer/CDSPlot.tsx +4 -1
  15. package/src/preact/genomeViewer/genome-data-viewer.stories.tsx +6 -0
  16. package/src/preact/mutationComparison/mutation-comparison.stories.tsx +6 -0
  17. package/src/preact/mutationComparison/mutation-comparison.tsx +4 -0
  18. package/src/preact/mutations/mutations.stories.tsx +6 -0
  19. package/src/preact/mutations/mutations.tsx +4 -1
  20. package/src/preact/mutationsOverTime/getFilteredMutationsOverTimeData.ts +4 -2
  21. package/src/preact/mutationsOverTime/mutations-over-time.stories.tsx +6 -0
  22. package/src/preact/mutationsOverTime/mutations-over-time.tsx +4 -1
  23. package/src/preact/numberSequencesOverTime/number-sequences-over-time.stories.tsx +3 -1
  24. package/src/preact/numberSequencesOverTime/number-sequences-over-time.tsx +4 -0
  25. package/src/preact/prevalenceOverTime/prevalence-over-time.stories.tsx +6 -0
  26. package/src/preact/prevalenceOverTime/prevalence-over-time.tsx +4 -1
  27. package/src/preact/relativeGrowthAdvantage/relative-growth-advantage.stories.tsx +6 -0
  28. package/src/preact/relativeGrowthAdvantage/relative-growth-advantage.tsx +4 -1
  29. package/src/preact/sequencesByLocation/sequences-by-location.stories.tsx +6 -0
  30. package/src/preact/sequencesByLocation/sequences-by-location.tsx +4 -0
  31. package/src/preact/shared/stories/expectFinishedLoadingEvent.ts +12 -0
  32. package/src/preact/statistic/statistics.stories.tsx +6 -0
  33. package/src/preact/statistic/statistics.tsx +4 -1
  34. package/src/preact/wastewater/mutationsOverTime/wastewater-mutations-over-time.stories.tsx +37 -1
  35. package/src/preact/wastewater/mutationsOverTime/wastewater-mutations-over-time.tsx +44 -4
  36. package/src/utilEntrypoint.ts +2 -0
  37. package/src/utils/gsEventNames.ts +1 -0
  38. package/src/utils/useDispatchFinishedLoadingEvent.ts +19 -0
  39. package/src/web-components/visualization/gs-aggregate.tsx +3 -0
  40. package/src/web-components/visualization/gs-genome-data-viewer.tsx +2 -0
  41. package/src/web-components/visualization/gs-mutation-comparison.tsx +3 -0
  42. package/src/web-components/visualization/gs-mutations-over-time.tsx +3 -0
  43. package/src/web-components/visualization/gs-mutations.tsx +2 -0
  44. package/src/web-components/visualization/gs-number-sequences-over-time.tsx +3 -0
  45. package/src/web-components/visualization/gs-prevalence-over-time.tsx +3 -0
  46. package/src/web-components/visualization/gs-relative-growth-advantage.tsx +3 -0
  47. package/src/web-components/visualization/gs-sequences-by-location.tsx +3 -0
  48. package/src/web-components/visualization/gs-statistics.tsx +3 -0
  49. package/src/web-components/wastewaterVisualization/gs-wastewater-mutations-over-time.tsx +3 -0
  50. package/standalone-bundle/assets/mutationOverTimeWorker-DAf2_NiP.js.map +1 -0
  51. package/standalone-bundle/dashboard-components.js +7012 -6961
  52. package/standalone-bundle/dashboard-components.js.map +1 -1
  53. package/dist/assets/mutationOverTimeWorker-ChQTFL68.js.map +0 -1
  54. package/standalone-bundle/assets/mutationOverTimeWorker-jChgWnwp.js.map +0 -1
@@ -7,6 +7,7 @@ import { RelativeGrowthAdvantage, type RelativeGrowthAdvantageProps } from './re
7
7
  import { AGGREGATED_ENDPOINT, LAPIS_URL } from '../../constants';
8
8
  import { LapisUrlContextProvider } from '../LapisUrlContext';
9
9
  import { expectInvalidAttributesErrorMessage } from '../shared/stories/expectErrorMessage';
10
+ import { playThatExpectsFinishedLoadingEvent } from '../shared/stories/expectFinishedLoadingEvent';
10
11
 
11
12
  export default {
12
13
  title: 'Visualization/RelativeGrowthAdvantage',
@@ -90,6 +91,11 @@ export const Primary: StoryObj<RelativeGrowthAdvantageProps> = {
90
91
  },
91
92
  };
92
93
 
94
+ export const FiresFinishedLoadingEvent: StoryObj<RelativeGrowthAdvantageProps> = {
95
+ ...Primary,
96
+ play: playThatExpectsFinishedLoadingEvent(),
97
+ };
98
+
93
99
  export const TooFewDataToComputeGrowthAdvantage: StoryObj<RelativeGrowthAdvantageProps> = {
94
100
  ...Primary,
95
101
  args: {
@@ -9,6 +9,7 @@ import {
9
9
  type RelativeGrowthAdvantageData,
10
10
  } from '../../query/queryRelativeGrowthAdvantage';
11
11
  import { lapisFilterSchema, views } from '../../types';
12
+ import { useDispatchFinishedLoadingEvent } from '../../utils/useDispatchFinishedLoadingEvent';
12
13
  import { useLapisUrl } from '../LapisUrlContext';
13
14
  import { ErrorBoundary } from '../components/error-boundary';
14
15
  import { Fullscreen } from '../components/fullscreen';
@@ -103,6 +104,8 @@ const RelativeGrowthAdvantageTabs: FunctionComponent<RelativeGrowthAdvantageTabs
103
104
  setYAxisScaleType,
104
105
  originalComponentProps,
105
106
  }) => {
107
+ const tabsRef = useDispatchFinishedLoadingEvent();
108
+
106
109
  const maintainAspectRatio = getMaintainAspectRatio(originalComponentProps.height);
107
110
 
108
111
  const getTab = (view: RelativeGrowthAdvantageView) => {
@@ -138,7 +141,7 @@ const RelativeGrowthAdvantageTabs: FunctionComponent<RelativeGrowthAdvantageTabs
138
141
  />
139
142
  );
140
143
 
141
- return <Tabs tabs={tabs} toolbar={toolbar} />;
144
+ return <Tabs ref={tabsRef} tabs={tabs} toolbar={toolbar} />;
142
145
  };
143
146
 
144
147
  type RelativeGrowthAdvantageToolbarProps = {
@@ -7,6 +7,7 @@ import { LapisUrlContextProvider } from '../LapisUrlContext';
7
7
  import aggregatedWorld from './__mockData__/aggregatedWorld.json';
8
8
  import { SequencesByLocation, type SequencesByLocationProps } from './sequences-by-location';
9
9
  import { expectInvalidAttributesErrorMessage, playThatExpectsErrorMessage } from '../shared/stories/expectErrorMessage';
10
+ import { playThatExpectsFinishedLoadingEvent } from '../shared/stories/expectFinishedLoadingEvent';
10
11
 
11
12
  import 'leaflet/dist/leaflet.css';
12
13
  import './leafletStyleModifications.css';
@@ -92,6 +93,11 @@ export const Default: StoryObj<SequencesByLocationProps> = {
92
93
  },
93
94
  };
94
95
 
96
+ export const FiresFinishedLoadingEvent: StoryObj<SequencesByLocationProps> = {
97
+ ...Default,
98
+ play: playThatExpectsFinishedLoadingEvent(),
99
+ };
100
+
95
101
  export const NoData: StoryObj<SequencesByLocationProps> = {
96
102
  ...Default,
97
103
  parameters: {
@@ -11,6 +11,7 @@ import {
11
11
  } from '../../query/computeMapLocationData';
12
12
  import { type AggregateData } from '../../query/queryAggregateData';
13
13
  import { querySequencesByLocationData } from '../../query/querySequencesByLocationData';
14
+ import { useDispatchFinishedLoadingEvent } from '../../utils/useDispatchFinishedLoadingEvent';
14
15
  import { CsvDownloadButton } from '../components/csv-download-button';
15
16
  import { ErrorBoundary } from '../components/error-boundary';
16
17
  import { Fullscreen } from '../components/fullscreen';
@@ -93,6 +94,8 @@ const SequencesByLocationMapTabs: FunctionComponent<SequencesByLocationMapTabsPr
93
94
  originalComponentProps,
94
95
  data,
95
96
  }) => {
97
+ const tabsRef = useDispatchFinishedLoadingEvent();
98
+
96
99
  const maintainAspectRatio = getMaintainAspectRatio(originalComponentProps.height);
97
100
 
98
101
  const getTab = (view: SequencesByLocationMapView) => {
@@ -136,6 +139,7 @@ const SequencesByLocationMapTabs: FunctionComponent<SequencesByLocationMapTabsPr
136
139
 
137
140
  return (
138
141
  <Tabs
142
+ ref={tabsRef}
139
143
  tabs={tabs}
140
144
  toolbar={<Toolbar originalComponentProps={originalComponentProps} tableData={data.tableData} />}
141
145
  />
@@ -0,0 +1,12 @@
1
+ import { expect, fn, waitFor } from '@storybook/test';
2
+
3
+ import { gsEventNames } from '../../../utils/gsEventNames';
4
+
5
+ export function playThatExpectsFinishedLoadingEvent() {
6
+ return async ({ canvasElement }: { canvasElement: HTMLElement }) => {
7
+ const componentFinishedLoadingListenerMock = fn();
8
+ canvasElement.addEventListener(gsEventNames.componentFinishedLoading, componentFinishedLoadingListenerMock);
9
+
10
+ await waitFor(() => expect(componentFinishedLoadingListenerMock).toHaveBeenCalled());
11
+ };
12
+ }
@@ -6,6 +6,7 @@ import { LapisUrlContextProvider } from '../LapisUrlContext';
6
6
  import denominatorData from './__mockData__/denominator.json';
7
7
  import numeratorData from './__mockData__/numerator.json';
8
8
  import { Statistics, type StatisticsProps } from './statistics';
9
+ import { playThatExpectsFinishedLoadingEvent } from '../shared/stories/expectFinishedLoadingEvent';
9
10
 
10
11
  const meta: Meta<StatisticsProps> = {
11
12
  title: 'Visualization/Statistics',
@@ -78,3 +79,8 @@ export const Default: StoryObj<StatisticsProps> = {
78
79
  });
79
80
  },
80
81
  };
82
+
83
+ export const FiresFinishedLoadingEvent: StoryObj<StatisticsProps> = {
84
+ ...Default,
85
+ play: playThatExpectsFinishedLoadingEvent(),
86
+ };
@@ -3,6 +3,7 @@ import z from 'zod';
3
3
 
4
4
  import { queryGeneralStatistics } from '../../query/queryGeneralStatistics';
5
5
  import { lapisFilterSchema } from '../../types';
6
+ import { useDispatchFinishedLoadingEvent } from '../../utils/useDispatchFinishedLoadingEvent';
6
7
  import { useLapisUrl } from '../LapisUrlContext';
7
8
  import { ErrorBoundary } from '../components/error-boundary';
8
9
  import { LoadingDisplay } from '../components/loading-display';
@@ -60,9 +61,11 @@ type MetricDataTabsProps = {
60
61
  };
61
62
 
62
63
  const MetricDataTabs: FunctionComponent<MetricDataTabsProps> = ({ data }) => {
64
+ const ref = useDispatchFinishedLoadingEvent();
65
+
63
66
  const { count, proportion } = data;
64
67
  return (
65
- <div className='flex flex-col sm:flex-row rounded-md border-2 border-gray-100 min-w-[180px]'>
68
+ <div ref={ref} className='flex flex-col sm:flex-row rounded-md border-2 border-gray-100 min-w-[180px]'>
66
69
  <div className='stat'>
67
70
  <div className='stat-title'>Sequences</div>
68
71
  <div className='stat-value text-2xl sm:text-4xl'>{count.toLocaleString('en-us')}</div>
@@ -1,5 +1,6 @@
1
1
  import { type Meta, type StoryObj } from '@storybook/preact';
2
- import { expect, userEvent } from '@storybook/test';
2
+ import { expect, userEvent, waitFor } from '@storybook/test';
3
+ import type { Canvas } from '@storybook/types';
3
4
 
4
5
  import { WastewaterMutationsOverTime, type WastewaterMutationsOverTimeProps } from './wastewater-mutations-over-time';
5
6
  import { WISE_DETAILS_ENDPOINT, WISE_LAPIS_URL } from '../../../constants';
@@ -7,6 +8,8 @@ import referenceGenome from '../../../lapisApi/__mockData__/referenceGenome.json
7
8
  import { LapisUrlContextProvider } from '../../LapisUrlContext';
8
9
  import { ReferenceGenomeContext } from '../../ReferenceGenomeContext';
9
10
  import details from './__mockData__/details.json';
11
+ import type { MutationsOverTimeProps } from '../../mutationsOverTime/mutations-over-time';
12
+ import { playThatExpectsFinishedLoadingEvent } from '../../shared/stories/expectFinishedLoadingEvent';
10
13
 
11
14
  const meta: Meta<WastewaterMutationsOverTimeProps> = {
12
15
  title: 'Wastewater visualization/Wastewater mutations over time',
@@ -65,6 +68,7 @@ export const Default: StoryObj<WastewaterMutationsOverTimeProps> = {
65
68
  ],
66
69
  },
67
70
  },
71
+ play: playThatExpectsFinishedLoadingEvent(),
68
72
  };
69
73
 
70
74
  export const ChangingRowsPerPageChangesItForEveryTag: StoryObj<WastewaterMutationsOverTimeProps> = {
@@ -108,3 +112,35 @@ export const AminoAcids: StoryObj<WastewaterMutationsOverTimeProps> = {
108
112
  });
109
113
  },
110
114
  };
115
+
116
+ export const UsesMutationFilter: StoryObj<MutationsOverTimeProps> = {
117
+ ...Default,
118
+ play: async ({ canvas, step }) => {
119
+ await expectMutationOnPage(canvas, 'A966C');
120
+
121
+ await step('input filter', async () => {
122
+ const filterButton = canvas.getByRole('button', { name: 'Filter mutations' });
123
+ await userEvent.click(filterButton);
124
+
125
+ const filterInput = canvas.getByPlaceholderText('Filter');
126
+ await userEvent.type(filterInput, '26');
127
+ });
128
+
129
+ await step('should show only matching filter', async () => {
130
+ await expectMutationOnPage(canvas, 'T4026G');
131
+ await expectMutationOnPage(canvas, 'T5260C');
132
+
133
+ await waitFor(async () => {
134
+ const filteredMutation = canvas.queryByText('A966C');
135
+ await expect(filteredMutation).not.toBeInTheDocument();
136
+ });
137
+ });
138
+ },
139
+ };
140
+
141
+ async function expectMutationOnPage(canvas: Canvas, mutation: string) {
142
+ await waitFor(async () => {
143
+ const mutationOnFirstPage = canvas.getAllByText(mutation)[0];
144
+ await expect(mutationOnFirstPage).toBeVisible();
145
+ });
146
+ }
@@ -3,20 +3,24 @@ import { type Dispatch, type StateUpdater, useMemo, useState } from 'preact/hook
3
3
  import z from 'zod';
4
4
 
5
5
  import { computeWastewaterMutationsOverTimeDataPerLocation } from './computeWastewaterMutationsOverTimeDataPerLocation';
6
- import { lapisFilterSchema, sequenceTypeSchema } from '../../../types';
6
+ import { lapisFilterSchema, type SequenceType, sequenceTypeSchema } from '../../../types';
7
7
  import { Map2dView } from '../../../utils/map2d';
8
+ import { useDispatchFinishedLoadingEvent } from '../../../utils/useDispatchFinishedLoadingEvent';
8
9
  import { useLapisUrl } from '../../LapisUrlContext';
10
+ import { useMutationAnnotationsProvider } from '../../MutationAnnotationsContext';
9
11
  import { type ColorScale } from '../../components/color-scale-selector';
10
12
  import { ColorScaleSelectorDropdown } from '../../components/color-scale-selector-dropdown';
11
13
  import { ErrorBoundary } from '../../components/error-boundary';
12
14
  import { Fullscreen } from '../../components/fullscreen';
13
15
  import Info, { InfoComponentCode, InfoHeadline1, InfoParagraph } from '../../components/info';
14
16
  import { LoadingDisplay } from '../../components/loading-display';
17
+ import { MutationsOverTimeTextFilter } from '../../components/mutations-over-time-text-filter';
15
18
  import { NoDataDisplay } from '../../components/no-data-display';
16
19
  import { ResizeContainer } from '../../components/resize-container';
17
20
  import { type DisplayedSegment, SegmentSelector } from '../../components/segment-selector';
18
21
  import Tabs from '../../components/tabs';
19
22
  import { type MutationOverTimeDataMap } from '../../mutationsOverTime/MutationOverTimeData';
23
+ import { mutationOrAnnotationDoNotMatchFilter } from '../../mutationsOverTime/getFilteredMutationsOverTimeData';
20
24
  import MutationsOverTimeGrid from '../../mutationsOverTime/mutations-over-time-grid';
21
25
  import { pageSizesSchema } from '../../shared/tanstackTable/pagination';
22
26
  import { PageSizeContextProvider } from '../../shared/tanstackTable/pagination-context';
@@ -111,13 +115,23 @@ type MutationOverTimeTabsProps = {
111
115
  function getFilteredMutationOverTimeData({
112
116
  data,
113
117
  displayedSegments,
118
+ mutationFilterValue,
119
+ annotationProvider,
120
+ sequenceType,
114
121
  }: {
115
122
  data: MutationOverTimeDataMap;
116
123
  displayedSegments: DisplayedSegment[];
124
+ mutationFilterValue: string;
125
+ sequenceType: SequenceType;
126
+ annotationProvider: ReturnType<typeof useMutationAnnotationsProvider>;
117
127
  }): MutationOverTimeDataMap {
118
128
  const filteredData = new Map2dView(data);
119
129
 
120
130
  const mutationsToFilterOut = data.getFirstAxisKeys().filter((entry) => {
131
+ if (mutationOrAnnotationDoNotMatchFilter(entry, sequenceType, mutationFilterValue, annotationProvider)) {
132
+ return true;
133
+ }
134
+
121
135
  return displayedSegments.some((segment) => segment.segment === entry.segment && !segment.checked);
122
136
  });
123
137
 
@@ -132,6 +146,11 @@ const MutationsOverTimeTabs: FunctionComponent<MutationOverTimeTabsProps> = ({
132
146
  mutationOverTimeDataPerLocation,
133
147
  originalComponentProps,
134
148
  }) => {
149
+ const tabsRef = useDispatchFinishedLoadingEvent();
150
+
151
+ const [mutationFilterValue, setMutationFilterValue] = useState('');
152
+ const annotationProvider = useMutationAnnotationsProvider();
153
+
135
154
  const [colorScale, setColorScale] = useState<ColorScale>({ min: 0, max: 1, color: 'indigo' });
136
155
  const [displayedSegments, setDisplayedSegments] = useDisplayedSegments(mutationOverTimeDataPerLocation);
137
156
 
@@ -141,14 +160,28 @@ const MutationsOverTimeTabs: FunctionComponent<MutationOverTimeTabsProps> = ({
141
160
  title: location,
142
161
  content: (
143
162
  <MutationsOverTimeGrid
144
- data={getFilteredMutationOverTimeData({ data, displayedSegments })}
163
+ data={getFilteredMutationOverTimeData({
164
+ data,
165
+ displayedSegments,
166
+ mutationFilterValue,
167
+ annotationProvider,
168
+ sequenceType: originalComponentProps.sequenceType,
169
+ })}
145
170
  colorScale={colorScale}
146
171
  pageSizes={originalComponentProps.pageSizes}
147
172
  sequenceType={originalComponentProps.sequenceType}
148
173
  />
149
174
  ),
150
175
  })),
151
- [mutationOverTimeDataPerLocation, displayedSegments, colorScale, originalComponentProps],
176
+ [
177
+ mutationOverTimeDataPerLocation,
178
+ displayedSegments,
179
+ mutationFilterValue,
180
+ annotationProvider,
181
+ colorScale,
182
+ originalComponentProps.pageSizes,
183
+ originalComponentProps.sequenceType,
184
+ ],
152
185
  );
153
186
 
154
187
  const toolbar = (
@@ -159,12 +192,14 @@ const MutationsOverTimeTabs: FunctionComponent<MutationOverTimeTabsProps> = ({
159
192
  data={mutationOverTimeDataPerLocation}
160
193
  displayedSegments={displayedSegments}
161
194
  setDisplayedSegments={setDisplayedSegments}
195
+ setFilterValue={setMutationFilterValue}
196
+ mutationFilterValue={mutationFilterValue}
162
197
  />
163
198
  );
164
199
 
165
200
  return (
166
201
  <PageSizeContextProvider pageSizes={originalComponentProps.pageSizes}>
167
- <Tabs tabs={tabs} toolbar={toolbar} />
202
+ <Tabs ref={tabsRef} tabs={tabs} toolbar={toolbar} />
168
203
  </PageSizeContextProvider>
169
204
  );
170
205
  };
@@ -176,6 +211,8 @@ type ToolbarProps = {
176
211
  data: MutationOverTimeDataPerLocation;
177
212
  displayedSegments: DisplayedSegment[];
178
213
  setDisplayedSegments: (segments: DisplayedSegment[]) => void;
214
+ mutationFilterValue: string;
215
+ setFilterValue: (filterValue: string) => void;
179
216
  };
180
217
 
181
218
  const Toolbar: FunctionComponent<ToolbarProps> = ({
@@ -184,9 +221,12 @@ const Toolbar: FunctionComponent<ToolbarProps> = ({
184
221
  originalComponentProps,
185
222
  displayedSegments,
186
223
  setDisplayedSegments,
224
+ setFilterValue,
225
+ mutationFilterValue,
187
226
  }) => {
188
227
  return (
189
228
  <>
229
+ <MutationsOverTimeTextFilter setFilterValue={setFilterValue} value={mutationFilterValue} />
190
230
  <ColorScaleSelectorDropdown colorScale={colorScale} setColorScale={setColorScale} />
191
231
  <SegmentSelector
192
232
  displayedSegments={displayedSegments}
@@ -40,3 +40,5 @@ export { TextFilterChangedEvent } from './preact/textFilter/TextFilterChangedEve
40
40
  export type { MutationAnnotations, MutationAnnotation } from './web-components/mutation-annotations-context';
41
41
 
42
42
  export { gsEventNames } from './utils/gsEventNames';
43
+
44
+ export { type NumberRange } from './preact/numberRangeFilter/NumberRangeFilterChangedEvent';
@@ -1,5 +1,6 @@
1
1
  export const gsEventNames = {
2
2
  error: 'gs-error',
3
+ componentFinishedLoading: 'gs-component-finished-loading',
3
4
  dateRangeFilterChanged: 'gs-date-range-filter-changed',
4
5
  dateRangeOptionChanged: 'gs-date-range-option-changed',
5
6
  mutationFilterChanged: 'gs-mutation-filter-changed',
@@ -0,0 +1,19 @@
1
+ import { useEffect, useRef } from 'preact/hooks';
2
+
3
+ import { gsEventNames } from './gsEventNames';
4
+
5
+ export function useDispatchFinishedLoadingEvent() {
6
+ const ref = useRef<HTMLDivElement>(null);
7
+
8
+ useEffect(() => {
9
+ if (ref.current === null) {
10
+ return;
11
+ }
12
+
13
+ ref.current.dispatchEvent(
14
+ new CustomEvent(gsEventNames.componentFinishedLoading, { bubbles: true, composed: true }),
15
+ );
16
+ }, [ref]);
17
+
18
+ return ref;
19
+ }
@@ -30,6 +30,9 @@ import { PreactLitAdapterWithGridJsStyles } from '../PreactLitAdapterWithGridJsS
30
30
  *
31
31
  * The chart shows the bars with the highest aggregated `count`.
32
32
  * The number of bars can be adjusted with the `maxNumberOfBars` property.
33
+ *
34
+ * @fires {CustomEvent<undefined>} gs-component-finished-loading
35
+ * Fired when the component has finished loading the required data from LAPIS.
33
36
  */
34
37
  @customElement('gs-aggregate')
35
38
  export class AggregateComponent extends PreactLitAdapterWithGridJsStyles {
@@ -10,6 +10,8 @@ import { PreactLitAdapter } from '../PreactLitAdapter';
10
10
  * This component shows the Coding Sequence (CDS) of a genome using a gff3 file as input.
11
11
  * The CDS shows which parts of the genome are translated into proteins.
12
12
  *
13
+ * @fires {CustomEvent<undefined>} gs-component-finished-loading
14
+ * Fired when the component has finished loading the required data.
13
15
  */
14
16
  @customElement('gs-genome-data-viewer')
15
17
  export class GenomeDataViewerComponent extends PreactLitAdapter {
@@ -34,6 +34,9 @@ import { type MutationAnnotations, mutationAnnotationsContext } from '../mutatio
34
34
  * selected proportion interval.
35
35
  * Thus, changing the proportion interval may change a mutations from being "common" between the datasets
36
36
  * to being "for one dataset only".
37
+ *
38
+ * @fires {CustomEvent<undefined>} gs-component-finished-loading
39
+ * Fired when the component has finished loading the required data from LAPIS.
37
40
  */
38
41
  @customElement('gs-mutation-comparison')
39
42
  export class MutationComparisonComponent extends PreactLitAdapterWithGridJsStyles {
@@ -38,6 +38,9 @@ import { type MutationAnnotations, mutationAnnotationsContext } from '../mutatio
38
38
  * Users can filter the displayed rows by mean proportion via a slider in the toolbar.
39
39
  * The mean proportion of each row is calculated by LAPIS over the whole data range that the component displays.
40
40
  * The initial mean proportion can be set via `initialMeanProportionInterval`.
41
+ *
42
+ * @fires {CustomEvent<undefined>} gs-component-finished-loading
43
+ * Fired when the component has finished loading the required data from LAPIS.
41
44
  */
42
45
  @customElement('gs-mutations-over-time')
43
46
  export class MutationsOverTimeComponent extends PreactLitAdapterWithGridJsStyles {
@@ -60,6 +60,8 @@ import { type MutationAnnotations, mutationAnnotationsContext } from '../mutatio
60
60
  *
61
61
  * The insertions view shows the count of all insertions for the dataset.
62
62
  *
63
+ * @fires {CustomEvent<undefined>} gs-component-finished-loading
64
+ * Fired when the component has finished loading the required data from LAPIS.
63
65
  */
64
66
  @customElement('gs-mutations')
65
67
  export class MutationsComponent extends PreactLitAdapterWithGridJsStyles {
@@ -19,6 +19,9 @@ import { PreactLitAdapterWithGridJsStyles } from '../PreactLitAdapterWithGridJsS
19
19
  * Thus, the `lapisFilter` implicitly also defines the range that is shown on the x-axis.
20
20
  * If you want to restrict the x-axis to a smaller date range,
21
21
  * then you need to set appropriate filter values in the `lapisFilter`.
22
+ *
23
+ * @fires {CustomEvent<undefined>} gs-component-finished-loading
24
+ * Fired when the component has finished loading the required data from LAPIS.
22
25
  */
23
26
  @customElement('gs-number-sequences-over-time')
24
27
  export class NumberSequencesOverTimeComponent extends PreactLitAdapterWithGridJsStyles {
@@ -41,6 +41,9 @@ import { PreactLitAdapterWithGridJsStyles } from '../PreactLitAdapterWithGridJsS
41
41
  * ### Table View
42
42
  *
43
43
  * Displays the prevalence over time as a table with one row per time point.
44
+ *
45
+ * @fires {CustomEvent<undefined>} gs-component-finished-loading
46
+ * Fired when the component has finished loading the required data from LAPIS.
44
47
  */
45
48
  @customElement('gs-prevalence-over-time')
46
49
  export class PrevalenceOverTimeComponent extends PreactLitAdapterWithGridJsStyles {
@@ -33,6 +33,9 @@ import { PreactLitAdapter } from '../PreactLitAdapter';
33
33
  * The dots in the plot show the proportions of the focal variant (defined by the `numeratorFilter`) to the baseline variant (defined by the `denominatorFilter`)
34
34
  * for every day as observed in the data.
35
35
  * The line shows a logistic curve fitted to the data points, including a 95% confidence interval.
36
+ *
37
+ * @fires {CustomEvent<undefined>} gs-component-finished-loading
38
+ * Fired when the component has finished loading the required data from LAPIS.
36
39
  */
37
40
  @customElement('gs-relative-growth-advantage')
38
41
  export class RelativeGrowthAdvantageComponent extends PreactLitAdapter {
@@ -94,6 +94,9 @@ const leafletModificationsCss = unsafeCSS(leafletStyleModifications);
94
94
  * - `lapisLocationField`,
95
95
  * - `count` (the number of samples in this location matching the `lapisFilter`),
96
96
  * - `proportion` (`count` / sum of the `count` of all locations).
97
+ *
98
+ * @fires {CustomEvent<undefined>} gs-component-finished-loading
99
+ * Fired when the component has finished loading the required data from LAPIS.
97
100
  */
98
101
  @customElement('gs-sequences-by-location')
99
102
  export class SequencesByLocationComponent extends PreactLitAdapterWithGridJsStyles {
@@ -10,6 +10,9 @@ import { PreactLitAdapterWithGridJsStyles } from '../PreactLitAdapterWithGridJsS
10
10
  *
11
11
  * This component displays general statistics (number of sequences, overall proportion)
12
12
  * for a given numerator and denominator filter.
13
+ *
14
+ * @fires {CustomEvent<undefined>} gs-component-finished-loading
15
+ * Fired when the component has finished loading the required data from LAPIS.
13
16
  */
14
17
  @customElement('gs-statistics')
15
18
  export class StatisticsComponent extends PreactLitAdapterWithGridJsStyles {
@@ -24,6 +24,9 @@ import { type MutationAnnotations, mutationAnnotationsContext } from '../mutatio
24
24
  * This component also assumes that the LAPIS instance has the field `date` which can be used for the time axis.
25
25
  *
26
26
  * @slot infoText - Additional information text to be shown in the info modal (the "?" button).
27
+ *
28
+ * @fires {CustomEvent<undefined>} gs-component-finished-loading
29
+ * Fired when the component has finished loading the required data from LAPIS.
27
30
  */
28
31
  @customElement('gs-wastewater-mutations-over-time')
29
32
  export class WastewaterMutationsOverTimeComponent extends PreactLitAdapterWithGridJsStyles {