@genspectrum/dashboard-components 1.12.0 → 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 +30 -36
- package/dist/components.js +943 -757
- package/dist/components.js.map +1 -1
- package/dist/util.d.ts +46 -30
- package/package.json +1 -5
- package/src/lapisApi/lapisApi.ts +21 -1
- package/src/lapisApi/lapisTypes.ts +36 -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 +21 -232
- 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-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 -8781
- package/standalone-bundle/dashboard-components.js.map +1 -1
- package/dist/assets/mutationOverTimeWorker-f8Kp0S6V.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 -988
- package/standalone-bundle/assets/mutationOverTimeWorker-AhhjjklP.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<{
|
|
@@ -987,7 +1003,7 @@ declare global {
|
|
|
987
1003
|
|
|
988
1004
|
declare global {
|
|
989
1005
|
interface HTMLElementTagNameMap {
|
|
990
|
-
'gs-
|
|
1006
|
+
'gs-mutations': MutationsComponent;
|
|
991
1007
|
}
|
|
992
1008
|
}
|
|
993
1009
|
|
|
@@ -995,7 +1011,7 @@ declare global {
|
|
|
995
1011
|
declare global {
|
|
996
1012
|
namespace JSX {
|
|
997
1013
|
interface IntrinsicElements {
|
|
998
|
-
'gs-
|
|
1014
|
+
'gs-mutations': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
999
1015
|
}
|
|
1000
1016
|
}
|
|
1001
1017
|
}
|
|
@@ -1003,7 +1019,7 @@ declare global {
|
|
|
1003
1019
|
|
|
1004
1020
|
declare global {
|
|
1005
1021
|
interface HTMLElementTagNameMap {
|
|
1006
|
-
'gs-
|
|
1022
|
+
'gs-prevalence-over-time': PrevalenceOverTimeComponent;
|
|
1007
1023
|
}
|
|
1008
1024
|
}
|
|
1009
1025
|
|
|
@@ -1011,7 +1027,7 @@ declare global {
|
|
|
1011
1027
|
declare global {
|
|
1012
1028
|
namespace JSX {
|
|
1013
1029
|
interface IntrinsicElements {
|
|
1014
|
-
'gs-
|
|
1030
|
+
'gs-prevalence-over-time': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
1015
1031
|
}
|
|
1016
1032
|
}
|
|
1017
1033
|
}
|
|
@@ -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,7 @@ declare global {
|
|
|
1027
1043
|
declare global {
|
|
1028
1044
|
namespace JSX {
|
|
1029
1045
|
interface IntrinsicElements {
|
|
1030
|
-
'gs-
|
|
1046
|
+
'gs-mutation-comparison': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
1031
1047
|
}
|
|
1032
1048
|
}
|
|
1033
1049
|
}
|
|
@@ -1035,7 +1051,7 @@ declare global {
|
|
|
1035
1051
|
|
|
1036
1052
|
declare global {
|
|
1037
1053
|
interface HTMLElementTagNameMap {
|
|
1038
|
-
'gs-
|
|
1054
|
+
'gs-relative-growth-advantage': RelativeGrowthAdvantageComponent;
|
|
1039
1055
|
}
|
|
1040
1056
|
}
|
|
1041
1057
|
|
|
@@ -1043,7 +1059,7 @@ declare global {
|
|
|
1043
1059
|
declare global {
|
|
1044
1060
|
namespace JSX {
|
|
1045
1061
|
interface IntrinsicElements {
|
|
1046
|
-
'gs-
|
|
1062
|
+
'gs-relative-growth-advantage': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
1047
1063
|
}
|
|
1048
1064
|
}
|
|
1049
1065
|
}
|
|
@@ -1051,7 +1067,7 @@ declare global {
|
|
|
1051
1067
|
|
|
1052
1068
|
declare global {
|
|
1053
1069
|
interface HTMLElementTagNameMap {
|
|
1054
|
-
'gs-
|
|
1070
|
+
'gs-number-sequences-over-time': NumberSequencesOverTimeComponent;
|
|
1055
1071
|
}
|
|
1056
1072
|
}
|
|
1057
1073
|
|
|
@@ -1059,7 +1075,7 @@ declare global {
|
|
|
1059
1075
|
declare global {
|
|
1060
1076
|
namespace JSX {
|
|
1061
1077
|
interface IntrinsicElements {
|
|
1062
|
-
'gs-
|
|
1078
|
+
'gs-number-sequences-over-time': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
1063
1079
|
}
|
|
1064
1080
|
}
|
|
1065
1081
|
}
|
|
@@ -1067,7 +1083,7 @@ declare global {
|
|
|
1067
1083
|
|
|
1068
1084
|
declare global {
|
|
1069
1085
|
interface HTMLElementTagNameMap {
|
|
1070
|
-
'gs-
|
|
1086
|
+
'gs-aggregate': AggregateComponent;
|
|
1071
1087
|
}
|
|
1072
1088
|
}
|
|
1073
1089
|
|
|
@@ -1075,7 +1091,7 @@ declare global {
|
|
|
1075
1091
|
declare global {
|
|
1076
1092
|
namespace JSX {
|
|
1077
1093
|
interface IntrinsicElements {
|
|
1078
|
-
'gs-
|
|
1094
|
+
'gs-aggregate': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
1079
1095
|
}
|
|
1080
1096
|
}
|
|
1081
1097
|
}
|
|
@@ -1083,7 +1099,7 @@ declare global {
|
|
|
1083
1099
|
|
|
1084
1100
|
declare global {
|
|
1085
1101
|
interface HTMLElementTagNameMap {
|
|
1086
|
-
'gs-
|
|
1102
|
+
'gs-mutations-over-time': MutationsOverTimeComponent;
|
|
1087
1103
|
}
|
|
1088
1104
|
}
|
|
1089
1105
|
|
|
@@ -1091,7 +1107,7 @@ declare global {
|
|
|
1091
1107
|
declare global {
|
|
1092
1108
|
namespace JSX {
|
|
1093
1109
|
interface IntrinsicElements {
|
|
1094
|
-
'gs-
|
|
1110
|
+
'gs-mutations-over-time': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
1095
1111
|
}
|
|
1096
1112
|
}
|
|
1097
1113
|
}
|
|
@@ -1115,7 +1131,7 @@ declare global {
|
|
|
1115
1131
|
|
|
1116
1132
|
declare global {
|
|
1117
1133
|
interface HTMLElementTagNameMap {
|
|
1118
|
-
'gs-
|
|
1134
|
+
'gs-statistics': StatisticsComponent;
|
|
1119
1135
|
}
|
|
1120
1136
|
}
|
|
1121
1137
|
|
|
@@ -1123,7 +1139,7 @@ declare global {
|
|
|
1123
1139
|
declare global {
|
|
1124
1140
|
namespace JSX {
|
|
1125
1141
|
interface IntrinsicElements {
|
|
1126
|
-
'gs-
|
|
1142
|
+
'gs-statistics': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
1127
1143
|
}
|
|
1128
1144
|
}
|
|
1129
1145
|
}
|
|
@@ -1151,10 +1167,10 @@ declare global {
|
|
|
1151
1167
|
|
|
1152
1168
|
declare global {
|
|
1153
1169
|
interface HTMLElementTagNameMap {
|
|
1154
|
-
'gs-
|
|
1170
|
+
'gs-location-filter': LocationFilterComponent;
|
|
1155
1171
|
}
|
|
1156
1172
|
interface HTMLElementEventMap {
|
|
1157
|
-
[gsEventNames.
|
|
1173
|
+
[gsEventNames.locationChanged]: LocationChangedEvent;
|
|
1158
1174
|
}
|
|
1159
1175
|
}
|
|
1160
1176
|
|
|
@@ -1162,7 +1178,7 @@ declare global {
|
|
|
1162
1178
|
declare global {
|
|
1163
1179
|
namespace JSX {
|
|
1164
1180
|
interface IntrinsicElements {
|
|
1165
|
-
'gs-
|
|
1181
|
+
'gs-location-filter': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
1166
1182
|
}
|
|
1167
1183
|
}
|
|
1168
1184
|
}
|
|
@@ -1170,10 +1186,10 @@ declare global {
|
|
|
1170
1186
|
|
|
1171
1187
|
declare global {
|
|
1172
1188
|
interface HTMLElementTagNameMap {
|
|
1173
|
-
'gs-
|
|
1189
|
+
'gs-text-filter': TextFilterComponent;
|
|
1174
1190
|
}
|
|
1175
1191
|
interface HTMLElementEventMap {
|
|
1176
|
-
[gsEventNames.
|
|
1192
|
+
[gsEventNames.textFilterChanged]: TextFilterChangedEvent;
|
|
1177
1193
|
}
|
|
1178
1194
|
}
|
|
1179
1195
|
|
|
@@ -1181,7 +1197,7 @@ declare global {
|
|
|
1181
1197
|
declare global {
|
|
1182
1198
|
namespace JSX {
|
|
1183
1199
|
interface IntrinsicElements {
|
|
1184
|
-
'gs-
|
|
1200
|
+
'gs-text-filter': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
1185
1201
|
}
|
|
1186
1202
|
}
|
|
1187
1203
|
}
|
|
@@ -1208,11 +1224,11 @@ declare global {
|
|
|
1208
1224
|
|
|
1209
1225
|
declare global {
|
|
1210
1226
|
interface HTMLElementTagNameMap {
|
|
1211
|
-
'gs-
|
|
1227
|
+
'gs-lineage-filter': LineageFilterComponent;
|
|
1212
1228
|
}
|
|
1213
1229
|
interface HTMLElementEventMap {
|
|
1214
|
-
[gsEventNames.
|
|
1215
|
-
[gsEventNames.
|
|
1230
|
+
[gsEventNames.lineageFilterChanged]: LineageFilterChangedEvent;
|
|
1231
|
+
[gsEventNames.lineageFilterMultiChanged]: LineageMultiFilterChangedEvent;
|
|
1216
1232
|
}
|
|
1217
1233
|
}
|
|
1218
1234
|
|
|
@@ -1220,7 +1236,7 @@ declare global {
|
|
|
1220
1236
|
declare global {
|
|
1221
1237
|
namespace JSX {
|
|
1222
1238
|
interface IntrinsicElements {
|
|
1223
|
-
'gs-
|
|
1239
|
+
'gs-lineage-filter': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
1224
1240
|
}
|
|
1225
1241
|
}
|
|
1226
1242
|
}
|
|
@@ -1228,11 +1244,11 @@ declare global {
|
|
|
1228
1244
|
|
|
1229
1245
|
declare global {
|
|
1230
1246
|
interface HTMLElementTagNameMap {
|
|
1231
|
-
'gs-
|
|
1247
|
+
'gs-number-range-filter': NumberRangeFilterComponent;
|
|
1232
1248
|
}
|
|
1233
1249
|
interface HTMLElementEventMap {
|
|
1234
|
-
[gsEventNames.
|
|
1235
|
-
[gsEventNames.
|
|
1250
|
+
[gsEventNames.numberRangeFilterChanged]: NumberRangeFilterChangedEvent;
|
|
1251
|
+
[gsEventNames.numberRangeValueChanged]: NumberRangeValueChangedEvent;
|
|
1236
1252
|
}
|
|
1237
1253
|
}
|
|
1238
1254
|
|
|
@@ -1240,7 +1256,7 @@ declare global {
|
|
|
1240
1256
|
declare global {
|
|
1241
1257
|
namespace JSX {
|
|
1242
1258
|
interface IntrinsicElements {
|
|
1243
|
-
'gs-
|
|
1259
|
+
'gs-number-range-filter': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
1244
1260
|
}
|
|
1245
1261
|
}
|
|
1246
1262
|
}
|
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}`;
|
|
@@ -67,6 +67,42 @@ export const mutationsOverTimeResponse = makeLapisResponse(
|
|
|
67
67
|
);
|
|
68
68
|
export type MutationsOverTimeResponse = z.infer<typeof mutationsOverTimeResponse>;
|
|
69
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
|
+
|
|
70
106
|
const insertionCount = z.object({
|
|
71
107
|
insertion: z.string(),
|
|
72
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
|
}
|