@genspectrum/dashboard-components 1.11.1 → 1.13.0
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/README.md +0 -7
- package/custom-elements.json +6 -25
- package/dist/components.d.ts +24 -30
- package/dist/components.js +929 -742
- package/dist/components.js.map +1 -1
- package/dist/util.d.ts +40 -24
- package/package.json +1 -5
- package/src/lapisApi/lapisApi.ts +21 -1
- package/src/lapisApi/lapisTypes.ts +37 -0
- package/src/preact/components/annotated-mutation.tsx +2 -2
- package/src/preact/{mutationsOverTime/mutations-over-time-grid.tsx → components/features-over-time-grid.tsx} +45 -52
- package/src/preact/genomeViewer/genome-data-viewer.tsx +2 -2
- package/src/preact/mutationsOverTime/MutationOverTimeData.ts +6 -4
- package/src/preact/mutationsOverTime/__mockData__/aminoAcidMutationsByDay/aminoAcidMutations.json +5482 -0
- package/src/preact/mutationsOverTime/__mockData__/aminoAcidMutationsByDay/aminoAcidMutationsOverTime.json +5496 -0
- package/src/preact/mutationsOverTime/__mockData__/byWeek/mutationsOverTime.json +7100 -0
- package/src/preact/mutationsOverTime/__mockData__/byWeek/nucleotideMutations.json +10122 -0
- package/src/preact/mutationsOverTime/__mockData__/defaultMockData/mutationsOverTime.json +12646 -0
- package/src/preact/mutationsOverTime/__mockData__/defaultMockData/nucleotideMutations.json +12632 -0
- package/src/preact/mutationsOverTime/__mockData__/request1800s/mutationsOverTime.json +16 -0
- package/src/preact/mutationsOverTime/__mockData__/request1800s/nucleotideMutations.json +11 -0
- package/src/preact/mutationsOverTime/__mockData__/withDisplayMutations/mutationsOverTime.json +52 -0
- package/src/preact/mutationsOverTime/getFilteredMutationsOverTime.spec.ts +3 -3
- package/src/preact/mutationsOverTime/mutations-over-time-grid-tooltip.tsx +3 -6
- package/src/preact/mutationsOverTime/mutations-over-time.stories.tsx +199 -12
- package/src/preact/mutationsOverTime/mutations-over-time.tsx +30 -35
- package/src/preact/wastewater/mutationsOverTime/wastewater-mutations-over-time.tsx +30 -3
- package/src/query/queryDatesInDataset.ts +89 -0
- package/src/query/queryMutationsOverTime.spec.ts +526 -548
- package/src/query/queryMutationsOverTime.ts +22 -245
- package/src/query/queryQueriesOverTime.spec.ts +432 -0
- package/src/query/queryQueriesOverTime.ts +125 -0
- package/src/utilEntrypoint.ts +3 -1
- package/src/utils/mutations.spec.ts +6 -0
- package/src/utils/mutations.ts +1 -1
- package/src/utils/temporalClass.ts +4 -0
- package/src/web-components/visualization/gs-mutation-comparison.tsx +2 -2
- package/src/web-components/visualization/gs-mutations-over-time.spec-d.ts +0 -3
- package/src/web-components/visualization/gs-mutations-over-time.stories.ts +283 -17
- package/src/web-components/visualization/gs-mutations-over-time.tsx +0 -9
- package/standalone-bundle/dashboard-components.js +8935 -8780
- package/standalone-bundle/dashboard-components.js.map +1 -1
- package/dist/assets/mutationOverTimeWorker-CQQFRoK4.js.map +0 -1
- package/src/preact/mutationsOverTime/__mockData__/aminoAcidMutationsByDay.ts +0 -47170
- package/src/preact/mutationsOverTime/__mockData__/byWeek.ts +0 -54026
- package/src/preact/mutationsOverTime/__mockData__/defaultMockData.ts +0 -108385
- package/src/preact/mutationsOverTime/__mockData__/mockConversion.ts +0 -54
- package/src/preact/mutationsOverTime/__mockData__/noDataWhenNoMutationsAreInFilter.ts +0 -23
- package/src/preact/mutationsOverTime/__mockData__/noDataWhenThereAreNoDatesInFilter.ts +0 -23
- package/src/preact/mutationsOverTime/__mockData__/showsMessageWhenTooManyMutations.ts +0 -65527
- package/src/preact/mutationsOverTime/__mockData__/withDisplayMutations.ts +0 -352
- package/src/preact/mutationsOverTime/__mockData__/withGaps.ts +0 -298
- package/src/preact/mutationsOverTime/mutationOverTimeWorker.mock.ts +0 -33
- package/src/preact/mutationsOverTime/mutationOverTimeWorker.ts +0 -29
- package/src/preact/webWorkers/useWebWorker.ts +0 -74
- package/src/preact/webWorkers/workerFunction.ts +0 -30
- package/src/query/queryMutationsOverTimeNewEndpoint.spec.ts +0 -1179
- package/standalone-bundle/assets/mutationOverTimeWorker-DIpJukJC.js.map +0 -1
package/dist/util.d.ts
CHANGED
|
@@ -734,6 +734,22 @@ export declare type PrevalenceOverTimeView = default_2.infer<typeof prevalenceOv
|
|
|
734
734
|
|
|
735
735
|
declare const prevalenceOverTimeViewSchema: default_2.ZodUnion<[default_2.ZodLiteral<"table">, default_2.ZodLiteral<"bar">, default_2.ZodLiteral<"line">, default_2.ZodLiteral<"bubble">]>;
|
|
736
736
|
|
|
737
|
+
export declare type QueryDefinition = default_2.infer<typeof queryDefinition>;
|
|
738
|
+
|
|
739
|
+
declare const queryDefinition: default_2.ZodObject<{
|
|
740
|
+
displayLabel: default_2.ZodOptional<default_2.ZodString>;
|
|
741
|
+
countQuery: default_2.ZodString;
|
|
742
|
+
coverageQuery: default_2.ZodString;
|
|
743
|
+
}, "strip", default_2.ZodTypeAny, {
|
|
744
|
+
countQuery: string;
|
|
745
|
+
coverageQuery: string;
|
|
746
|
+
displayLabel?: string | undefined;
|
|
747
|
+
}, {
|
|
748
|
+
countQuery: string;
|
|
749
|
+
coverageQuery: string;
|
|
750
|
+
displayLabel?: string | undefined;
|
|
751
|
+
}>;
|
|
752
|
+
|
|
737
753
|
export declare type RelativeGrowthAdvantageProps = default_2.infer<typeof relativeGrowthAdvantagePropsSchema>;
|
|
738
754
|
|
|
739
755
|
declare const relativeGrowthAdvantagePropsSchema: default_2.ZodObject<{
|
|
@@ -955,7 +971,7 @@ declare global {
|
|
|
955
971
|
|
|
956
972
|
declare global {
|
|
957
973
|
interface HTMLElementTagNameMap {
|
|
958
|
-
'gs-
|
|
974
|
+
'gs-wastewater-mutations-over-time': WastewaterMutationsOverTimeComponent;
|
|
959
975
|
}
|
|
960
976
|
}
|
|
961
977
|
|
|
@@ -963,7 +979,7 @@ declare global {
|
|
|
963
979
|
declare global {
|
|
964
980
|
namespace JSX {
|
|
965
981
|
interface IntrinsicElements {
|
|
966
|
-
'gs-
|
|
982
|
+
'gs-wastewater-mutations-over-time': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
967
983
|
}
|
|
968
984
|
}
|
|
969
985
|
}
|
|
@@ -971,7 +987,7 @@ declare global {
|
|
|
971
987
|
|
|
972
988
|
declare global {
|
|
973
989
|
interface HTMLElementTagNameMap {
|
|
974
|
-
'gs-
|
|
990
|
+
'gs-genome-data-viewer': GenomeDataViewerComponent;
|
|
975
991
|
}
|
|
976
992
|
}
|
|
977
993
|
|
|
@@ -979,7 +995,7 @@ declare global {
|
|
|
979
995
|
declare global {
|
|
980
996
|
namespace JSX {
|
|
981
997
|
interface IntrinsicElements {
|
|
982
|
-
'gs-
|
|
998
|
+
'gs-genome-data-viewer': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
983
999
|
}
|
|
984
1000
|
}
|
|
985
1001
|
}
|
|
@@ -1019,7 +1035,7 @@ declare global {
|
|
|
1019
1035
|
|
|
1020
1036
|
declare global {
|
|
1021
1037
|
interface HTMLElementTagNameMap {
|
|
1022
|
-
'gs-
|
|
1038
|
+
'gs-mutation-comparison': MutationComparisonComponent;
|
|
1023
1039
|
}
|
|
1024
1040
|
}
|
|
1025
1041
|
|
|
@@ -1027,7 +1043,23 @@ declare global {
|
|
|
1027
1043
|
declare global {
|
|
1028
1044
|
namespace JSX {
|
|
1029
1045
|
interface IntrinsicElements {
|
|
1030
|
-
'gs-
|
|
1046
|
+
'gs-mutation-comparison': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
1047
|
+
}
|
|
1048
|
+
}
|
|
1049
|
+
}
|
|
1050
|
+
|
|
1051
|
+
|
|
1052
|
+
declare global {
|
|
1053
|
+
interface HTMLElementTagNameMap {
|
|
1054
|
+
'gs-relative-growth-advantage': RelativeGrowthAdvantageComponent;
|
|
1055
|
+
}
|
|
1056
|
+
}
|
|
1057
|
+
|
|
1058
|
+
|
|
1059
|
+
declare global {
|
|
1060
|
+
namespace JSX {
|
|
1061
|
+
interface IntrinsicElements {
|
|
1062
|
+
'gs-relative-growth-advantage': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
1031
1063
|
}
|
|
1032
1064
|
}
|
|
1033
1065
|
}
|
|
@@ -1051,7 +1083,7 @@ declare global {
|
|
|
1051
1083
|
|
|
1052
1084
|
declare global {
|
|
1053
1085
|
interface HTMLElementTagNameMap {
|
|
1054
|
-
'gs-
|
|
1086
|
+
'gs-aggregate': AggregateComponent;
|
|
1055
1087
|
}
|
|
1056
1088
|
}
|
|
1057
1089
|
|
|
@@ -1059,7 +1091,7 @@ declare global {
|
|
|
1059
1091
|
declare global {
|
|
1060
1092
|
namespace JSX {
|
|
1061
1093
|
interface IntrinsicElements {
|
|
1062
|
-
'gs-
|
|
1094
|
+
'gs-aggregate': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
1063
1095
|
}
|
|
1064
1096
|
}
|
|
1065
1097
|
}
|
|
@@ -1230,22 +1262,6 @@ declare global {
|
|
|
1230
1262
|
}
|
|
1231
1263
|
|
|
1232
1264
|
|
|
1233
|
-
declare global {
|
|
1234
|
-
interface HTMLElementTagNameMap {
|
|
1235
|
-
'gs-wastewater-mutations-over-time': WastewaterMutationsOverTimeComponent;
|
|
1236
|
-
}
|
|
1237
|
-
}
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
declare global {
|
|
1241
|
-
namespace JSX {
|
|
1242
|
-
interface IntrinsicElements {
|
|
1243
|
-
'gs-wastewater-mutations-over-time': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
1244
|
-
}
|
|
1245
|
-
}
|
|
1246
|
-
}
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
1265
|
declare module 'chart.js' {
|
|
1250
1266
|
interface CartesianScaleTypeRegistry {
|
|
1251
1267
|
logit: {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@genspectrum/dashboard-components",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.13.0",
|
|
4
4
|
"description": "GenSpectrum web components for building dashboards",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "AGPL-3.0-only",
|
|
@@ -16,10 +16,6 @@
|
|
|
16
16
|
"access": "public"
|
|
17
17
|
},
|
|
18
18
|
"imports": {
|
|
19
|
-
"#mutationOverTime": {
|
|
20
|
-
"storybook": "./src/preact/mutationsOverTime/mutationOverTimeWorker.mock.ts",
|
|
21
|
-
"default": "./src/preact/mutationsOverTime/mutationOverTimeWorker.ts"
|
|
22
|
-
},
|
|
23
19
|
"#*": [
|
|
24
20
|
"./*",
|
|
25
21
|
"./*.ts",
|
package/src/lapisApi/lapisApi.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { lineageDefinitionResponseSchema } from './LineageDefinition';
|
|
1
2
|
import { referenceGenomeResponse } from './ReferenceGenome';
|
|
2
3
|
import {
|
|
3
4
|
aggregatedResponse,
|
|
@@ -11,9 +12,10 @@ import {
|
|
|
11
12
|
type ProblemDetail,
|
|
12
13
|
type MutationsOverTimeRequest,
|
|
13
14
|
mutationsOverTimeResponse,
|
|
15
|
+
type QueriesOverTimeRequest,
|
|
16
|
+
queriesOverTimeResponse,
|
|
14
17
|
} from './lapisTypes';
|
|
15
18
|
import { type SequenceType } from '../types';
|
|
16
|
-
import { lineageDefinitionResponseSchema } from './LineageDefinition';
|
|
17
19
|
|
|
18
20
|
export class UnknownLapisError extends Error {
|
|
19
21
|
constructor(
|
|
@@ -136,6 +138,23 @@ export async function fetchMutationsOverTime(
|
|
|
136
138
|
return mutationsOverTimeResponse.parse(await response.json());
|
|
137
139
|
}
|
|
138
140
|
|
|
141
|
+
export async function fetchQueriesOverTime(lapisUrl: string, body: QueriesOverTimeRequest, signal?: AbortSignal) {
|
|
142
|
+
const response = await callLapis(
|
|
143
|
+
queriesOverTimeEndpoint(lapisUrl),
|
|
144
|
+
{
|
|
145
|
+
method: 'POST',
|
|
146
|
+
headers: {
|
|
147
|
+
'Content-Type': 'application/json',
|
|
148
|
+
},
|
|
149
|
+
body: JSON.stringify(body),
|
|
150
|
+
signal,
|
|
151
|
+
},
|
|
152
|
+
'queries over time',
|
|
153
|
+
);
|
|
154
|
+
|
|
155
|
+
return queriesOverTimeResponse.parse(await response.json());
|
|
156
|
+
}
|
|
157
|
+
|
|
139
158
|
export async function fetchReferenceGenome(lapisUrl: string, signal?: AbortSignal) {
|
|
140
159
|
const response = await callLapis(
|
|
141
160
|
referenceGenomeEndpoint(lapisUrl),
|
|
@@ -244,6 +263,7 @@ export const mutationsOverTimeEndpoint = (lapisUrl: string, sequenceType: Sequen
|
|
|
244
263
|
? `${lapisUrl}/component/aminoAcidMutationsOverTime`
|
|
245
264
|
: `${lapisUrl}/component/nucleotideMutationsOverTime`;
|
|
246
265
|
};
|
|
266
|
+
export const queriesOverTimeEndpoint = (lapisUrl: string) => `${lapisUrl}/component/queriesOverTime`;
|
|
247
267
|
export const referenceGenomeEndpoint = (lapisUrl: string) => `${lapisUrl}/sample/referenceGenome`;
|
|
248
268
|
export const lineageDefinitionEndpoint = (lapisUrl: string, lapisField: string) =>
|
|
249
269
|
`${lapisUrl}/sample/lineageDefinition/${lapisField}`;
|
|
@@ -62,10 +62,47 @@ export const mutationsOverTimeResponse = makeLapisResponse(
|
|
|
62
62
|
}),
|
|
63
63
|
),
|
|
64
64
|
),
|
|
65
|
+
totalCountsByDateRange: z.array(z.number()),
|
|
65
66
|
}),
|
|
66
67
|
);
|
|
67
68
|
export type MutationsOverTimeResponse = z.infer<typeof mutationsOverTimeResponse>;
|
|
68
69
|
|
|
70
|
+
const queryDefinition = z.object({
|
|
71
|
+
displayLabel: z.string().optional(),
|
|
72
|
+
countQuery: z.string(),
|
|
73
|
+
coverageQuery: z.string(),
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
export type QueryDefinition = z.infer<typeof queryDefinition>;
|
|
77
|
+
|
|
78
|
+
export const queriesOverTimeRequest = z.object({
|
|
79
|
+
filters: z.record(filterValue),
|
|
80
|
+
queries: z.array(queryDefinition),
|
|
81
|
+
dateRanges: z.array(dateRange),
|
|
82
|
+
dateField: z.string(),
|
|
83
|
+
downloadAsFile: z.boolean().optional(),
|
|
84
|
+
downloadFileBasename: z.string().optional(),
|
|
85
|
+
compression: z.enum(['gzip', 'none']).optional(),
|
|
86
|
+
});
|
|
87
|
+
export type QueriesOverTimeRequest = z.infer<typeof queriesOverTimeRequest>;
|
|
88
|
+
|
|
89
|
+
export const queriesOverTimeResponse = makeLapisResponse(
|
|
90
|
+
z.object({
|
|
91
|
+
queries: z.array(z.string()),
|
|
92
|
+
dateRanges: z.array(dateRange),
|
|
93
|
+
data: z.array(
|
|
94
|
+
z.array(
|
|
95
|
+
z.object({
|
|
96
|
+
count: z.number(),
|
|
97
|
+
coverage: z.number(),
|
|
98
|
+
}),
|
|
99
|
+
),
|
|
100
|
+
),
|
|
101
|
+
totalCountsByDateRange: z.array(z.number()),
|
|
102
|
+
}),
|
|
103
|
+
);
|
|
104
|
+
export type QueriesOverTimeResponse = z.infer<typeof queriesOverTimeResponse>;
|
|
105
|
+
|
|
69
106
|
const insertionCount = z.object({
|
|
70
107
|
insertion: z.string(),
|
|
71
108
|
count: z.number(),
|
|
@@ -2,11 +2,11 @@ import DOMPurify from 'dompurify';
|
|
|
2
2
|
import { useRef } from 'gridjs';
|
|
3
3
|
import { Fragment, type FunctionComponent, type RefObject } from 'preact';
|
|
4
4
|
|
|
5
|
+
import { InfoHeadline1, InfoHeadline2, InfoParagraph } from './info';
|
|
6
|
+
import { ButtonWithModalDialog, useModalRef } from './modal';
|
|
5
7
|
import type { SequenceType } from '../../types';
|
|
6
8
|
import type { Deletion, Substitution } from '../../utils/mutations';
|
|
7
9
|
import { useMutationAnnotationsProvider } from '../MutationAnnotationsContext';
|
|
8
|
-
import { InfoHeadline1, InfoHeadline2, InfoParagraph } from './info';
|
|
9
|
-
import { ButtonWithModalDialog, useModalRef } from './modal';
|
|
10
10
|
import { useMutationLinkProvider } from '../MutationLinkTemplateContext';
|
|
11
11
|
|
|
12
12
|
export type AnnotatedMutationProps = {
|
|
@@ -1,17 +1,13 @@
|
|
|
1
|
-
import { type FunctionComponent } from 'preact';
|
|
1
|
+
import { type FunctionComponent, type JSX } from 'preact';
|
|
2
2
|
import { useMemo } from 'preact/hooks';
|
|
3
3
|
import z from 'zod';
|
|
4
4
|
|
|
5
|
-
import { type
|
|
6
|
-
import
|
|
7
|
-
import {
|
|
8
|
-
import { type
|
|
9
|
-
import { type Deletion, type Substitution } from '../../utils/mutations';
|
|
5
|
+
import { type ColorScale, getColorWithinScale, getTextColorForScale } from './color-scale-selector';
|
|
6
|
+
import PortalTooltip from './portal-tooltip';
|
|
7
|
+
import { type TooltipPosition } from './tooltip';
|
|
8
|
+
import { getProportion, type ProportionValue } from '../../query/queryMutationsOverTime';
|
|
10
9
|
import { type Temporal } from '../../utils/temporalClass';
|
|
11
|
-
import {
|
|
12
|
-
import { type ColorScale, getColorWithinScale, getTextColorForScale } from '../components/color-scale-selector';
|
|
13
|
-
import PortalTooltip from '../components/portal-tooltip';
|
|
14
|
-
import { type TooltipPosition } from '../components/tooltip';
|
|
10
|
+
import { type TemporalDataMap } from '../mutationsOverTime/MutationOverTimeData';
|
|
15
11
|
import { formatProportion } from '../shared/table/formatProportion';
|
|
16
12
|
import { type PageSizes, Pagination } from '../shared/tanstackTable/pagination';
|
|
17
13
|
import { usePageSizeContext } from '../shared/tanstackTable/pagination-context';
|
|
@@ -31,55 +27,56 @@ export const customColumnSchema = z.object({
|
|
|
31
27
|
});
|
|
32
28
|
export type CustomColumn = z.infer<typeof customColumnSchema>;
|
|
33
29
|
|
|
34
|
-
export interface
|
|
35
|
-
|
|
30
|
+
export interface FeatureRenderer<D> {
|
|
31
|
+
asString(value: D): string;
|
|
32
|
+
renderRowLabel(value: D): JSX.Element;
|
|
33
|
+
renderTooltip(value: D, temporal: Temporal, proportionValue: ProportionValue | undefined): JSX.Element;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export interface FeaturesOverTimeGridProps<F> {
|
|
37
|
+
rowLabelHeader: string;
|
|
38
|
+
data: TemporalDataMap<F>;
|
|
36
39
|
colorScale: ColorScale;
|
|
37
|
-
sequenceType: SequenceType;
|
|
38
40
|
pageSizes: PageSizes;
|
|
39
41
|
customColumns?: CustomColumn[];
|
|
42
|
+
featureRenderer: FeatureRenderer<F>;
|
|
40
43
|
tooltipPortalTarget: HTMLElement | null;
|
|
41
44
|
}
|
|
42
45
|
|
|
43
|
-
type RowType = {
|
|
44
|
-
|
|
45
|
-
values: (
|
|
46
|
+
type RowType<F> = {
|
|
47
|
+
feature: F;
|
|
48
|
+
values: (ProportionValue | undefined)[];
|
|
46
49
|
customValues: (string | number | undefined)[];
|
|
47
50
|
};
|
|
48
51
|
|
|
49
52
|
const EMPTY_COLUMNS: CustomColumn[] = [];
|
|
50
53
|
|
|
51
|
-
|
|
54
|
+
function FeaturesOverTimeGrid<F>({
|
|
55
|
+
rowLabelHeader,
|
|
52
56
|
data,
|
|
53
57
|
colorScale,
|
|
54
|
-
sequenceType,
|
|
55
58
|
pageSizes,
|
|
56
59
|
customColumns = EMPTY_COLUMNS,
|
|
60
|
+
featureRenderer,
|
|
57
61
|
tooltipPortalTarget,
|
|
58
|
-
})
|
|
62
|
+
}: FeaturesOverTimeGridProps<F>) {
|
|
59
63
|
const tableData = useMemo(() => {
|
|
60
|
-
const
|
|
61
|
-
return data.getAsArray().map((row, index): RowType => {
|
|
62
|
-
const
|
|
63
|
-
const customValues = customColumns.map((col) => col.values[
|
|
64
|
-
return {
|
|
64
|
+
const firstAxisKeys = data.getFirstAxisKeys();
|
|
65
|
+
return data.getAsArray().map((row, index): RowType<F> => {
|
|
66
|
+
const firstAxisKey = firstAxisKeys[index];
|
|
67
|
+
const customValues = customColumns.map((col) => col.values[featureRenderer.asString(firstAxisKey)]);
|
|
68
|
+
return { feature: firstAxisKey, values: [...row], customValues };
|
|
65
69
|
});
|
|
66
|
-
}, [data, customColumns]);
|
|
70
|
+
}, [data, customColumns, featureRenderer]);
|
|
67
71
|
|
|
68
72
|
const columns = useMemo(() => {
|
|
69
|
-
const columnHelper = createColumnHelper<RowType
|
|
73
|
+
const columnHelper = createColumnHelper<RowType<F>>();
|
|
70
74
|
const dates = data.getSecondAxisKeys();
|
|
71
75
|
|
|
72
|
-
const
|
|
73
|
-
id: '
|
|
74
|
-
header: () => <span>
|
|
75
|
-
cell: ({ getValue }) =>
|
|
76
|
-
const value = getValue();
|
|
77
|
-
return (
|
|
78
|
-
<div className={'text-center'}>
|
|
79
|
-
<AnnotatedMutation mutation={value} sequenceType={sequenceType} />
|
|
80
|
-
</div>
|
|
81
|
-
);
|
|
82
|
-
},
|
|
76
|
+
const featureHeader = columnHelper.accessor((row) => row.feature, {
|
|
77
|
+
id: 'feature',
|
|
78
|
+
header: () => <span>{rowLabelHeader}</span>,
|
|
79
|
+
cell: ({ getValue }) => featureRenderer.renderRowLabel(getValue()),
|
|
83
80
|
});
|
|
84
81
|
|
|
85
82
|
const customColumnHeaders = customColumns.map((customCol, index) => {
|
|
@@ -108,12 +105,13 @@ const MutationsOverTimeGrid: FunctionComponent<MutationsOverTimeGridProps> = ({
|
|
|
108
105
|
const numberOfRows = table.getRowModel().rows.length;
|
|
109
106
|
const numberOfColumns = table.getAllColumns().length;
|
|
110
107
|
|
|
108
|
+
const tooltip = featureRenderer.renderTooltip(row.original.feature, date, value);
|
|
109
|
+
|
|
111
110
|
return (
|
|
112
111
|
<div className={'text-center'}>
|
|
113
112
|
<ProportionCell
|
|
114
113
|
value={value ?? null}
|
|
115
|
-
|
|
116
|
-
mutation={row.original.mutation}
|
|
114
|
+
tooltip={tooltip}
|
|
117
115
|
tooltipPosition={getTooltipPosition(
|
|
118
116
|
rowIndex -
|
|
119
117
|
table.getState().pagination.pageIndex * table.getState().pagination.pageSize,
|
|
@@ -130,8 +128,8 @@ const MutationsOverTimeGrid: FunctionComponent<MutationsOverTimeGridProps> = ({
|
|
|
130
128
|
});
|
|
131
129
|
});
|
|
132
130
|
|
|
133
|
-
return [
|
|
134
|
-
}, [colorScale, data,
|
|
131
|
+
return [featureHeader, ...customColumnHeaders, ...dateHeaders];
|
|
132
|
+
}, [colorScale, data, customColumns, tooltipPortalTarget, featureRenderer, rowLabelHeader]);
|
|
135
133
|
|
|
136
134
|
const { pageSize } = usePageSizeContext();
|
|
137
135
|
const table = usePreactTable({
|
|
@@ -183,7 +181,7 @@ const MutationsOverTimeGrid: FunctionComponent<MutationsOverTimeGridProps> = ({
|
|
|
183
181
|
</div>
|
|
184
182
|
</div>
|
|
185
183
|
);
|
|
186
|
-
}
|
|
184
|
+
}
|
|
187
185
|
|
|
188
186
|
function styleGridHeader(columnIndex: number, numDateColumns: number) {
|
|
189
187
|
if (columnIndex === 0) {
|
|
@@ -204,22 +202,17 @@ function getTooltipPosition(rowIndex: number, rows: number, columnIndex: number,
|
|
|
204
202
|
}
|
|
205
203
|
|
|
206
204
|
const ProportionCell: FunctionComponent<{
|
|
207
|
-
value:
|
|
208
|
-
|
|
209
|
-
mutation: Substitution | Deletion;
|
|
205
|
+
value: ProportionValue;
|
|
206
|
+
tooltip: JSX.Element;
|
|
210
207
|
tooltipPosition: TooltipPosition;
|
|
211
208
|
colorScale: ColorScale;
|
|
212
209
|
tooltipPortalTarget: HTMLElement | null;
|
|
213
|
-
}> = ({ value,
|
|
210
|
+
}> = ({ value, tooltip, tooltipPosition, colorScale, tooltipPortalTarget }) => {
|
|
214
211
|
const proportion = getProportion(value);
|
|
215
212
|
|
|
216
213
|
return (
|
|
217
214
|
<div className={'py-1 w-full h-full'}>
|
|
218
|
-
<PortalTooltip
|
|
219
|
-
content={<MutationsOverTimeGridTooltip mutation={mutation} date={date} value={value} />}
|
|
220
|
-
position={tooltipPosition}
|
|
221
|
-
portalTarget={tooltipPortalTarget}
|
|
222
|
-
>
|
|
215
|
+
<PortalTooltip content={tooltip} position={tooltipPosition} portalTarget={tooltipPortalTarget}>
|
|
223
216
|
<div
|
|
224
217
|
style={{
|
|
225
218
|
backgroundColor: getColorWithinScale(proportion, colorScale),
|
|
@@ -240,4 +233,4 @@ const ProportionCell: FunctionComponent<{
|
|
|
240
233
|
);
|
|
241
234
|
};
|
|
242
235
|
|
|
243
|
-
export default
|
|
236
|
+
export default FeaturesOverTimeGrid;
|
|
@@ -2,12 +2,12 @@ import type { FunctionComponent } from 'preact';
|
|
|
2
2
|
import { useEffect, useRef, useState } from 'preact/hooks';
|
|
3
3
|
import z from 'zod';
|
|
4
4
|
|
|
5
|
+
import CDSPlot from './CDSPlot';
|
|
6
|
+
import { loadGff3 } from './loadGff3';
|
|
5
7
|
import { ErrorBoundary } from '../components/error-boundary';
|
|
6
8
|
import { LoadingDisplay } from '../components/loading-display';
|
|
7
9
|
import { ResizeContainer } from '../components/resize-container';
|
|
8
10
|
import { useQuery } from '../useQuery';
|
|
9
|
-
import CDSPlot from './CDSPlot';
|
|
10
|
-
import { loadGff3 } from './loadGff3';
|
|
11
11
|
|
|
12
12
|
const genomeDataViewerPropsSchema = z.object({
|
|
13
13
|
gff3Source: z.string().min(1, 'gff3Source cannot be empty'),
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import {
|
|
2
|
-
type
|
|
2
|
+
type ProportionValue,
|
|
3
3
|
serializeSubstitutionOrDeletion,
|
|
4
4
|
serializeTemporal,
|
|
5
5
|
} from '../../query/queryMutationsOverTime';
|
|
@@ -7,18 +7,20 @@ import { type Map2d, Map2dBase, type Map2DContents } from '../../utils/map2d';
|
|
|
7
7
|
import type { Deletion, Substitution } from '../../utils/mutations';
|
|
8
8
|
import type { Temporal, TemporalClass } from '../../utils/temporalClass';
|
|
9
9
|
|
|
10
|
+
export type TemporalDataMap<D, T extends Temporal | TemporalClass = Temporal> = Map2d<D, T, ProportionValue>;
|
|
11
|
+
|
|
10
12
|
export type MutationOverTimeDataMap<T extends Temporal | TemporalClass = Temporal> = Map2d<
|
|
11
13
|
Substitution | Deletion,
|
|
12
14
|
T,
|
|
13
|
-
|
|
15
|
+
ProportionValue
|
|
14
16
|
>;
|
|
15
17
|
|
|
16
18
|
export class BaseMutationOverTimeDataMap<T extends Temporal | TemporalClass = Temporal> extends Map2dBase<
|
|
17
19
|
Substitution | Deletion,
|
|
18
20
|
T,
|
|
19
|
-
|
|
21
|
+
ProportionValue
|
|
20
22
|
> {
|
|
21
|
-
constructor(initialContent?: Map2DContents<Substitution | Deletion, T,
|
|
23
|
+
constructor(initialContent?: Map2DContents<Substitution | Deletion, T, ProportionValue>) {
|
|
22
24
|
super(serializeSubstitutionOrDeletion, serializeTemporal, initialContent);
|
|
23
25
|
}
|
|
24
26
|
}
|