@genspectrum/dashboard-components 0.6.2 → 0.6.4
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 +220 -0
- package/dist/dashboard-components.js +675 -178
- package/dist/dashboard-components.js.map +1 -1
- package/dist/genspectrum-components.d.ts +70 -2
- package/dist/style.css +10 -4
- package/package.json +3 -1
- package/src/constants.ts +1 -1
- package/src/lapisApi/lapisTypes.ts +1 -0
- package/src/operator/FillMissingOperator.spec.ts +3 -1
- package/src/operator/FillMissingOperator.ts +4 -2
- package/src/preact/components/tooltip.stories.tsx +54 -0
- package/src/preact/components/tooltip.tsx +31 -0
- package/src/preact/mutationComparison/queryMutationData.ts +12 -4
- package/src/preact/mutationsOverTime/__mockData__/aggregated_date.json +642 -0
- package/src/preact/mutationsOverTime/__mockData__/nucleotideMutations_2024_01.json +1747 -0
- package/src/preact/mutationsOverTime/__mockData__/nucleotideMutations_2024_02.json +1774 -0
- package/src/preact/mutationsOverTime/__mockData__/nucleotideMutations_2024_03.json +1819 -0
- package/src/preact/mutationsOverTime/__mockData__/nucleotideMutations_2024_04.json +1864 -0
- package/src/preact/mutationsOverTime/__mockData__/nucleotideMutations_2024_05.json +1927 -0
- package/src/preact/mutationsOverTime/__mockData__/nucleotideMutations_2024_06.json +1864 -0
- package/src/preact/mutationsOverTime/__mockData__/nucleotideMutations_2024_07.json +9 -0
- package/src/preact/mutationsOverTime/getFilteredMutationsOverTime.spec.ts +98 -0
- package/src/preact/mutationsOverTime/getFilteredMutationsOverTimeData.ts +66 -0
- package/src/preact/mutationsOverTime/mutations-over-time-grid.tsx +127 -0
- package/src/preact/mutationsOverTime/mutations-over-time.stories.tsx +206 -0
- package/src/preact/mutationsOverTime/mutations-over-time.tsx +170 -0
- package/src/preact/numberSequencesOverTime/getNumberOfSequencesOverTimeTableData.ts +1 -1
- package/src/preact/prevalenceOverTime/prevalence-over-time.stories.tsx +1 -0
- package/src/preact/shared/table/formatProportion.ts +2 -2
- package/src/query/queryAggregatedDataOverTime.ts +8 -33
- package/src/query/queryMutationsOverTime.spec.ts +378 -0
- package/src/query/queryMutationsOverTime.ts +179 -0
- package/src/query/queryNumberOfSequencesOverTime.ts +0 -1
- package/src/query/queryRelativeGrowthAdvantage.ts +3 -3
- package/src/utils/Map2d.ts +75 -0
- package/src/utils/map2d.spec.ts +94 -0
- package/src/utils/mutations.ts +5 -1
- package/src/utils/temporal.spec.ts +5 -0
- package/src/utils/temporal.ts +88 -5
- package/src/web-components/visualization/gs-mutations-over-time.stories.ts +225 -0
- package/src/web-components/visualization/gs-mutations-over-time.tsx +112 -0
- package/src/web-components/visualization/index.ts +1 -0
|
@@ -488,6 +488,67 @@ export declare class MutationsComponent extends PreactLitAdapterWithGridJsStyles
|
|
|
488
488
|
render(): JSX_2.Element;
|
|
489
489
|
}
|
|
490
490
|
|
|
491
|
+
/**
|
|
492
|
+
* ## Context
|
|
493
|
+
*
|
|
494
|
+
* This component displays mutations (substitutions and deletions) over time for a dataset selected by a LAPIS filter.
|
|
495
|
+
* The shown date range is determined by the date field in the LAPIS filter.
|
|
496
|
+
* If the date field is not set, the date range is determined by all available dates in the dataset.
|
|
497
|
+
*
|
|
498
|
+
* ## Views
|
|
499
|
+
*
|
|
500
|
+
* ### Grid View
|
|
501
|
+
*
|
|
502
|
+
* The grid view shows the proportion for each mutation over date ranges.
|
|
503
|
+
*
|
|
504
|
+
* The grid will show at max 100 rows and 200 columns for browser performance reasons.
|
|
505
|
+
* More data might make the browser unresponsive.
|
|
506
|
+
* If the numbers are exceeded, an error message will be shown.
|
|
507
|
+
* In both cases, the `lapisFilter` should be narrowed down to reduce the number of mutations or date ranges.
|
|
508
|
+
* The number of date ranges can also be reduced by selecting a larger granularity (months instead of weeks).
|
|
509
|
+
*/
|
|
510
|
+
export declare class MutationsOverTimeComponent extends PreactLitAdapterWithGridJsStyles {
|
|
511
|
+
/**
|
|
512
|
+
* Required.
|
|
513
|
+
*
|
|
514
|
+
* LAPIS filter to select the displayed data.
|
|
515
|
+
*/
|
|
516
|
+
lapisFilter: Record<string, string | number | null | boolean>;
|
|
517
|
+
/**
|
|
518
|
+
* The type of the sequence for which the mutations should be shown.
|
|
519
|
+
*/
|
|
520
|
+
sequenceType: 'nucleotide' | 'amino acid';
|
|
521
|
+
/**
|
|
522
|
+
* A list of tabs with views that this component should provide.
|
|
523
|
+
*/
|
|
524
|
+
views: 'grid'[];
|
|
525
|
+
/**
|
|
526
|
+
* The width of the component.
|
|
527
|
+
*
|
|
528
|
+
* Visit https://genspectrum.github.io/dashboard-components/?path=/docs/components-size-of-components--docs for more information.
|
|
529
|
+
*/
|
|
530
|
+
width: string;
|
|
531
|
+
/**
|
|
532
|
+
* The height of the component.
|
|
533
|
+
*
|
|
534
|
+
* Visit https://genspectrum.github.io/dashboard-components/?path=/docs/components-size-of-components--docs for more information.
|
|
535
|
+
*/
|
|
536
|
+
height: string;
|
|
537
|
+
/**
|
|
538
|
+
* The granularity of the time axis.
|
|
539
|
+
*/
|
|
540
|
+
granularity: 'day' | 'week' | 'month' | 'year';
|
|
541
|
+
/**
|
|
542
|
+
* Required.
|
|
543
|
+
*
|
|
544
|
+
* The LAPIS field that the data should be aggregated by.
|
|
545
|
+
* The values will be used for the columns of the grid.
|
|
546
|
+
* Must be a field of type `date` in LAPIS.
|
|
547
|
+
*/
|
|
548
|
+
lapisDateField: string;
|
|
549
|
+
render(): JSX_2.Element;
|
|
550
|
+
}
|
|
551
|
+
|
|
491
552
|
/**
|
|
492
553
|
* ## Context
|
|
493
554
|
*
|
|
@@ -902,14 +963,14 @@ declare global {
|
|
|
902
963
|
|
|
903
964
|
declare global {
|
|
904
965
|
interface HTMLElementTagNameMap {
|
|
905
|
-
'gs-
|
|
966
|
+
'gs-prevalence-over-time': PrevalenceOverTimeComponent;
|
|
906
967
|
}
|
|
907
968
|
}
|
|
908
969
|
|
|
909
970
|
|
|
910
971
|
declare global {
|
|
911
972
|
interface HTMLElementTagNameMap {
|
|
912
|
-
'gs-
|
|
973
|
+
'gs-mutations-component': MutationsComponent;
|
|
913
974
|
}
|
|
914
975
|
}
|
|
915
976
|
|
|
@@ -935,6 +996,13 @@ declare global {
|
|
|
935
996
|
}
|
|
936
997
|
|
|
937
998
|
|
|
999
|
+
declare global {
|
|
1000
|
+
interface HTMLElementTagNameMap {
|
|
1001
|
+
'gs-mutations-over-time-component': MutationsOverTimeComponent;
|
|
1002
|
+
}
|
|
1003
|
+
}
|
|
1004
|
+
|
|
1005
|
+
|
|
938
1006
|
declare global {
|
|
939
1007
|
interface HTMLElementTagNameMap {
|
|
940
1008
|
'gs-date-range-selector': DateRangeSelectorComponent;
|
package/dist/style.css
CHANGED
|
@@ -376,7 +376,7 @@ input[type="range"] {
|
|
|
376
376
|
background-color: #C6C6C6;
|
|
377
377
|
pointer-events: none;
|
|
378
378
|
}/*
|
|
379
|
-
! tailwindcss v3.4.
|
|
379
|
+
! tailwindcss v3.4.6 | MIT License | https://tailwindcss.com
|
|
380
380
|
*//*
|
|
381
381
|
1. Prevent padding and border from affecting element width. (https://github.com/mozdevs/cssremedy/issues/4)
|
|
382
382
|
2. Allow adding a border to an element by just adding a border-width. (https://github.com/tailwindcss/tailwindcss/pull/116)
|
|
@@ -2825,9 +2825,6 @@ input.tab:checked + .tab-content,
|
|
|
2825
2825
|
.mb-2 {
|
|
2826
2826
|
margin-bottom: 0.5rem;
|
|
2827
2827
|
}
|
|
2828
|
-
.ml-2 {
|
|
2829
|
-
margin-left: 0.5rem;
|
|
2830
|
-
}
|
|
2831
2828
|
.ml-2\.5 {
|
|
2832
2829
|
margin-left: 0.625rem;
|
|
2833
2830
|
}
|
|
@@ -3032,6 +3029,9 @@ input.tab:checked + .tab-content,
|
|
|
3032
3029
|
padding-top: 1rem;
|
|
3033
3030
|
padding-bottom: 1rem;
|
|
3034
3031
|
}
|
|
3032
|
+
.text-center {
|
|
3033
|
+
text-align: center;
|
|
3034
|
+
}
|
|
3035
3035
|
.text-justify {
|
|
3036
3036
|
text-align: justify;
|
|
3037
3037
|
}
|
|
@@ -3123,6 +3123,9 @@ input.tab:checked + .tab-content,
|
|
|
3123
3123
|
--tw-bg-opacity: 1;
|
|
3124
3124
|
background-color: rgb(243 244 246 / var(--tw-bg-opacity));
|
|
3125
3125
|
}
|
|
3126
|
+
.hover\:font-bold:hover {
|
|
3127
|
+
font-weight: 700;
|
|
3128
|
+
}
|
|
3126
3129
|
.hover\:text-blue-700:hover {
|
|
3127
3130
|
--tw-text-opacity: 1;
|
|
3128
3131
|
color: rgb(29 78 216 / var(--tw-text-opacity));
|
|
@@ -3147,6 +3150,9 @@ input.tab:checked + .tab-content,
|
|
|
3147
3150
|
--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
|
|
3148
3151
|
--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(0px + var(--tw-ring-offset-width)) var(--tw-ring-color);
|
|
3149
3152
|
box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
|
|
3153
|
+
}
|
|
3154
|
+
.peer:hover ~ .peer-hover\:block {
|
|
3155
|
+
display: block;
|
|
3150
3156
|
}.flatpickr-calendar{background:transparent;opacity:0;display:none;text-align:center;visibility:hidden;padding:0;-webkit-animation:none;animation:none;direction:ltr;border:0;font-size:14px;line-height:24px;border-radius:5px;position:absolute;width:307.875px;-webkit-box-sizing:border-box;box-sizing:border-box;-ms-touch-action:manipulation;touch-action:manipulation;background:#fff;-webkit-box-shadow:1px 0 0 #e6e6e6,-1px 0 0 #e6e6e6,0 1px 0 #e6e6e6,0 -1px 0 #e6e6e6,0 3px 13px rgba(0,0,0,0.08);box-shadow:1px 0 0 #e6e6e6,-1px 0 0 #e6e6e6,0 1px 0 #e6e6e6,0 -1px 0 #e6e6e6,0 3px 13px rgba(0,0,0,0.08)}.flatpickr-calendar.open,.flatpickr-calendar.inline{opacity:1;max-height:640px;visibility:visible}.flatpickr-calendar.open{display:inline-block;z-index:99999}.flatpickr-calendar.animate.open{-webkit-animation:fpFadeInDown 300ms cubic-bezier(.23,1,.32,1);animation:fpFadeInDown 300ms cubic-bezier(.23,1,.32,1)}.flatpickr-calendar.inline{display:block;position:relative;top:2px}.flatpickr-calendar.static{position:absolute;top:calc(100% + 2px)}.flatpickr-calendar.static.open{z-index:999;display:block}.flatpickr-calendar.multiMonth .flatpickr-days .dayContainer:nth-child(n+1) .flatpickr-day.inRange:nth-child(7n+7){-webkit-box-shadow:none !important;box-shadow:none !important}.flatpickr-calendar.multiMonth .flatpickr-days .dayContainer:nth-child(n+2) .flatpickr-day.inRange:nth-child(7n+1){-webkit-box-shadow:-2px 0 0 #e6e6e6,5px 0 0 #e6e6e6;box-shadow:-2px 0 0 #e6e6e6,5px 0 0 #e6e6e6}.flatpickr-calendar .hasWeeks .dayContainer,.flatpickr-calendar .hasTime .dayContainer{border-bottom:0;border-bottom-right-radius:0;border-bottom-left-radius:0}.flatpickr-calendar .hasWeeks .dayContainer{border-left:0}.flatpickr-calendar.hasTime .flatpickr-time{height:40px;border-top:1px solid #e6e6e6}.flatpickr-calendar.noCalendar.hasTime .flatpickr-time{height:auto}.flatpickr-calendar:before,.flatpickr-calendar:after{position:absolute;display:block;pointer-events:none;border:solid transparent;content:'';height:0;width:0;left:22px}.flatpickr-calendar.rightMost:before,.flatpickr-calendar.arrowRight:before,.flatpickr-calendar.rightMost:after,.flatpickr-calendar.arrowRight:after{left:auto;right:22px}.flatpickr-calendar.arrowCenter:before,.flatpickr-calendar.arrowCenter:after{left:50%;right:50%}.flatpickr-calendar:before{border-width:5px;margin:0 -5px}.flatpickr-calendar:after{border-width:4px;margin:0 -4px}.flatpickr-calendar.arrowTop:before,.flatpickr-calendar.arrowTop:after{bottom:100%}.flatpickr-calendar.arrowTop:before{border-bottom-color:#e6e6e6}.flatpickr-calendar.arrowTop:after{border-bottom-color:#fff}.flatpickr-calendar.arrowBottom:before,.flatpickr-calendar.arrowBottom:after{top:100%}.flatpickr-calendar.arrowBottom:before{border-top-color:#e6e6e6}.flatpickr-calendar.arrowBottom:after{border-top-color:#fff}.flatpickr-calendar:focus{outline:0}.flatpickr-wrapper{position:relative;display:inline-block}.flatpickr-months{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex}.flatpickr-months .flatpickr-month{background:transparent;color:rgba(0,0,0,0.9);fill:rgba(0,0,0,0.9);height:34px;line-height:1;text-align:center;position:relative;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;overflow:hidden;-webkit-box-flex:1;-webkit-flex:1;-ms-flex:1;flex:1}.flatpickr-months .flatpickr-prev-month,.flatpickr-months .flatpickr-next-month{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-decoration:none;cursor:pointer;position:absolute;top:0;height:34px;padding:10px;z-index:3;color:rgba(0,0,0,0.9);fill:rgba(0,0,0,0.9)}.flatpickr-months .flatpickr-prev-month.flatpickr-disabled,.flatpickr-months .flatpickr-next-month.flatpickr-disabled{display:none}.flatpickr-months .flatpickr-prev-month i,.flatpickr-months .flatpickr-next-month i{position:relative}.flatpickr-months .flatpickr-prev-month.flatpickr-prev-month,.flatpickr-months .flatpickr-next-month.flatpickr-prev-month{/*
|
|
3151
3157
|
/*rtl:begin:ignore*/left:0/*
|
|
3152
3158
|
/*rtl:end:ignore*/}/*
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@genspectrum/dashboard-components",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.4",
|
|
4
4
|
"description": "GenSpectrum web components for building dashboards",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "AGPL-3.0-only",
|
|
@@ -68,6 +68,7 @@
|
|
|
68
68
|
"flatpickr": "^4.6.13",
|
|
69
69
|
"gridjs": "^6.2.0",
|
|
70
70
|
"lit": "^3.1.3",
|
|
71
|
+
"object-hash": "^3.0.0",
|
|
71
72
|
"preact": "^10.20.1",
|
|
72
73
|
"zod": "^3.23.0"
|
|
73
74
|
},
|
|
@@ -87,6 +88,7 @@
|
|
|
87
88
|
"@storybook/web-components": "^8.0.9",
|
|
88
89
|
"@storybook/web-components-vite": "^8.0.9",
|
|
89
90
|
"@types/node": "^20.12.7",
|
|
91
|
+
"@types/object-hash": "^3.0.6",
|
|
90
92
|
"@typescript-eslint/eslint-plugin": "^7.14.1",
|
|
91
93
|
"@typescript-eslint/parser": "^7.14.1",
|
|
92
94
|
"autoprefixer": "^10.4.19",
|
package/src/constants.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export const LAPIS_URL = 'https://lapis.cov-spectrum.org/open/v2
|
|
1
|
+
export const LAPIS_URL = 'https://lapis.cov-spectrum.org/open/v2';
|
|
2
2
|
|
|
3
3
|
export const AGGREGATED_ENDPOINT = `${LAPIS_URL}/sample/aggregated`;
|
|
4
4
|
export const NUCLEOTIDE_MUTATIONS_ENDPOINT = `${LAPIS_URL}/sample/nucleotideMutations`;
|
|
@@ -30,6 +30,7 @@ const mutationProportionCount = z.object({
|
|
|
30
30
|
position: z.number(),
|
|
31
31
|
});
|
|
32
32
|
export const mutationsResponse = makeLapisResponse(z.array(mutationProportionCount));
|
|
33
|
+
export type MutationsResponse = z.infer<typeof mutationsResponse>;
|
|
33
34
|
|
|
34
35
|
const insertionCount = z.object({
|
|
35
36
|
insertion: z.string(),
|
|
@@ -10,7 +10,9 @@ describe('FillMissingOperator', () => {
|
|
|
10
10
|
const query = new FillMissingOperator(
|
|
11
11
|
child,
|
|
12
12
|
'id',
|
|
13
|
-
(ids) =>
|
|
13
|
+
(ids) => {
|
|
14
|
+
return { min: Math.min(...ids), max: Math.max(...ids) };
|
|
15
|
+
},
|
|
14
16
|
(min, max) => {
|
|
15
17
|
const result = [];
|
|
16
18
|
for (let i = min; i <= max; i++) {
|
|
@@ -5,7 +5,9 @@ export class FillMissingOperator<Data, KeyToFill extends keyof Data> implements
|
|
|
5
5
|
constructor(
|
|
6
6
|
private child: Operator<Data>,
|
|
7
7
|
private keyField: KeyToFill,
|
|
8
|
-
private getMinMaxFn: (
|
|
8
|
+
private getMinMaxFn: (
|
|
9
|
+
values: Iterable<Data[KeyToFill]>,
|
|
10
|
+
) => { min: Data[KeyToFill]; max: Data[KeyToFill] } | null,
|
|
9
11
|
private getAllRequiredKeysFn: (min: Data[KeyToFill], max: Data[KeyToFill]) => Data[KeyToFill][],
|
|
10
12
|
private defaultValueFn: (key: Data[KeyToFill]) => Data,
|
|
11
13
|
) {}
|
|
@@ -17,7 +19,7 @@ export class FillMissingOperator<Data, KeyToFill extends keyof Data> implements
|
|
|
17
19
|
if (minMax === null) {
|
|
18
20
|
return childEvaluated;
|
|
19
21
|
}
|
|
20
|
-
const
|
|
22
|
+
const { min, max } = minMax;
|
|
21
23
|
const requiredKeys = this.getAllRequiredKeysFn(min, max);
|
|
22
24
|
const content = childEvaluated.content;
|
|
23
25
|
for (const key of requiredKeys) {
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { type Meta, type StoryObj } from '@storybook/preact';
|
|
2
|
+
import { expect, waitFor, within } from '@storybook/test';
|
|
3
|
+
|
|
4
|
+
import Tooltip, { type TooltipProps } from './tooltip';
|
|
5
|
+
|
|
6
|
+
const meta: Meta<TooltipProps> = {
|
|
7
|
+
title: 'Component/Tooltip',
|
|
8
|
+
component: Tooltip,
|
|
9
|
+
parameters: { fetchMock: {} },
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export default meta;
|
|
13
|
+
|
|
14
|
+
const tooltipContent = 'This is some content.';
|
|
15
|
+
|
|
16
|
+
export const TooltipStory: StoryObj<TooltipProps> = {
|
|
17
|
+
render: (args) => (
|
|
18
|
+
<div class='flex justify-center px-4 py-16'>
|
|
19
|
+
<Tooltip {...args}>
|
|
20
|
+
<div>Hover me</div>
|
|
21
|
+
</Tooltip>
|
|
22
|
+
</div>
|
|
23
|
+
),
|
|
24
|
+
args: {
|
|
25
|
+
content: tooltipContent,
|
|
26
|
+
},
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export const RendersStringContent: StoryObj<TooltipProps> = {
|
|
30
|
+
...TooltipStory,
|
|
31
|
+
play: async ({ canvasElement }) => {
|
|
32
|
+
const canvas = within(canvasElement);
|
|
33
|
+
const tooltipBase = canvas.getByText('Hover me');
|
|
34
|
+
|
|
35
|
+
await waitFor(() => expect(tooltipBase).toBeInTheDocument());
|
|
36
|
+
|
|
37
|
+
await waitFor(() => expect(canvas.queryByText(tooltipContent, { exact: false })).toBeInTheDocument());
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
export const RendersComponentConent: StoryObj<TooltipProps> = {
|
|
42
|
+
...TooltipStory,
|
|
43
|
+
args: {
|
|
44
|
+
content: <div>{tooltipContent}</div>,
|
|
45
|
+
},
|
|
46
|
+
play: async ({ canvasElement }) => {
|
|
47
|
+
const canvas = within(canvasElement);
|
|
48
|
+
const tooltipBase = canvas.getByText('Hover me');
|
|
49
|
+
|
|
50
|
+
await waitFor(() => expect(tooltipBase).toBeInTheDocument());
|
|
51
|
+
|
|
52
|
+
await waitFor(() => expect(canvas.queryByText(tooltipContent, { exact: false })).toBeInTheDocument());
|
|
53
|
+
},
|
|
54
|
+
};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { flip, offset, shift } from '@floating-ui/dom';
|
|
2
|
+
import { type FunctionComponent } from 'preact';
|
|
3
|
+
import { useRef } from 'preact/hooks';
|
|
4
|
+
import { type JSXInternal } from 'preact/src/jsx';
|
|
5
|
+
|
|
6
|
+
import { dropdownClass } from './dropdown';
|
|
7
|
+
import { useFloatingUi } from '../shared/floating-ui/hooks';
|
|
8
|
+
|
|
9
|
+
export type TooltipProps = {
|
|
10
|
+
content: string | JSXInternal.Element;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
const Tooltip: FunctionComponent<TooltipProps> = ({ children, content }) => {
|
|
14
|
+
const referenceRef = useRef<HTMLDivElement>(null);
|
|
15
|
+
const floatingRef = useRef<HTMLDivElement>(null);
|
|
16
|
+
|
|
17
|
+
useFloatingUi(referenceRef, floatingRef, [offset(5), shift(), flip()]);
|
|
18
|
+
|
|
19
|
+
return (
|
|
20
|
+
<div className='relative'>
|
|
21
|
+
<div className='peer' ref={referenceRef}>
|
|
22
|
+
{children}
|
|
23
|
+
</div>
|
|
24
|
+
<div ref={floatingRef} className={`${dropdownClass} hidden peer-hover:block`}>
|
|
25
|
+
{content}
|
|
26
|
+
</div>
|
|
27
|
+
</div>
|
|
28
|
+
);
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export default Tooltip;
|
|
@@ -28,6 +28,17 @@ export function filterMutationData(
|
|
|
28
28
|
data: MutationData[],
|
|
29
29
|
displayedSegments: DisplayedSegment[],
|
|
30
30
|
displayedMutationTypes: DisplayedMutationType[],
|
|
31
|
+
) {
|
|
32
|
+
return data.map((mutationEntry) => ({
|
|
33
|
+
displayName: mutationEntry.displayName,
|
|
34
|
+
data: filterBySegmentAndMutationType(mutationEntry.data, displayedSegments, displayedMutationTypes),
|
|
35
|
+
}));
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export function filterBySegmentAndMutationType(
|
|
39
|
+
data: SubstitutionOrDeletionEntry[],
|
|
40
|
+
displayedSegments: DisplayedSegment[],
|
|
41
|
+
displayedMutationTypes: DisplayedMutationType[],
|
|
31
42
|
) {
|
|
32
43
|
const byDisplayedSegments = (mutationEntry: SubstitutionOrDeletionEntry) => {
|
|
33
44
|
if (mutationEntry.mutation.segment === undefined) {
|
|
@@ -45,8 +56,5 @@ export function filterMutationData(
|
|
|
45
56
|
);
|
|
46
57
|
};
|
|
47
58
|
|
|
48
|
-
return data.
|
|
49
|
-
displayName: mutationEntry.displayName,
|
|
50
|
-
data: mutationEntry.data.filter(byDisplayedSegments).filter(byDisplayedMutationTypes),
|
|
51
|
-
}));
|
|
59
|
+
return data.filter(byDisplayedSegments).filter(byDisplayedMutationTypes);
|
|
52
60
|
}
|