@genspectrum/dashboard-components 0.4.3 → 0.4.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 +40 -2
- package/dist/dashboard-components.js +49 -7
- package/dist/dashboard-components.js.map +1 -1
- package/dist/genspectrum-components.d.ts +9 -0
- package/package.json +1 -1
- package/src/preact/aggregatedData/aggregate.stories.tsx +4 -0
- package/src/preact/aggregatedData/aggregate.tsx +20 -3
- package/src/query/queryAggregateData.spec.ts +117 -3
- package/src/query/queryAggregateData.ts +31 -2
- package/src/web-components/visualization/gs-aggregate.stories.ts +11 -0
- package/src/web-components/visualization/gs-aggregate.tsx +15 -0
package/custom-elements.json
CHANGED
|
@@ -1124,7 +1124,7 @@
|
|
|
1124
1124
|
"type": {
|
|
1125
1125
|
"text": "Meta<Required<AggregateProps>>"
|
|
1126
1126
|
},
|
|
1127
|
-
"default": "{ title: 'Visualization/Aggregate', component: 'gs-aggregate', argTypes: { fields: [{ control: 'object' }], views: { options: ['table'], control: { type: 'check' }, }, width: { control: 'text' }, height: { control: 'text' }, headline: { control: 'text' }, }, parameters: withComponentDocs({ fetchMock: { mocks: [ { matcher: { name: 'aggregatedData', url: AGGREGATED_ENDPOINT, body: { fields: ['division', 'host'], country: 'USA', }, }, response: { status: 200, body: aggregatedData, }, }, ], }, componentDocs: { opensShadowDom: true, expectsChildren: false, codeExample, }, }), tags: ['autodocs'], }"
|
|
1127
|
+
"default": "{ title: 'Visualization/Aggregate', component: 'gs-aggregate', argTypes: { fields: [{ control: 'object' }], views: { options: ['table'], control: { type: 'check' }, }, width: { control: 'text' }, height: { control: 'text' }, headline: { control: 'text' }, initialSortField: { control: 'text' }, initialSortDirection: { options: ['ascending', 'descending'], control: { type: 'radio' }, }, }, parameters: withComponentDocs({ fetchMock: { mocks: [ { matcher: { name: 'aggregatedData', url: AGGREGATED_ENDPOINT, body: { fields: ['division', 'host'], country: 'USA', }, }, response: { status: 200, body: aggregatedData, }, }, ], }, componentDocs: { opensShadowDom: true, expectsChildren: false, codeExample, }, }), tags: ['autodocs'], }"
|
|
1128
1128
|
},
|
|
1129
1129
|
{
|
|
1130
1130
|
"kind": "variable",
|
|
@@ -1132,7 +1132,7 @@
|
|
|
1132
1132
|
"type": {
|
|
1133
1133
|
"text": "StoryObj<Required<AggregateProps>>"
|
|
1134
1134
|
},
|
|
1135
|
-
"default": "{ render: (args) => html` <gs-app lapis=\"${LAPIS_URL}\"> <gs-aggregate .fields=${args.fields} .filter=${args.filter} .views=${args.views} .width=${args.width} .height=${args.height} .headline=${args.headline} ></gs-aggregate> </gs-app> `, args: { fields: ['division', 'host'], views: ['table'], filter: { country: 'USA', }, width: '100%', height: '700px', headline: 'Aggregate', }, }"
|
|
1135
|
+
"default": "{ render: (args) => html` <gs-app lapis=\"${LAPIS_URL}\"> <gs-aggregate .fields=${args.fields} .filter=${args.filter} .views=${args.views} .width=${args.width} .height=${args.height} .headline=${args.headline} .initialSortField=${args.initialSortField} .initialSortDirection=${args.initialSortDirection} ></gs-aggregate> </gs-app> `, args: { fields: ['division', 'host'], views: ['table'], filter: { country: 'USA', }, width: '100%', height: '700px', headline: 'Aggregate', initialSortField: 'count', initialSortDirection: 'descending', }, }"
|
|
1136
1136
|
}
|
|
1137
1137
|
],
|
|
1138
1138
|
"exports": [
|
|
@@ -1222,6 +1222,26 @@
|
|
|
1222
1222
|
"default": "'Aggregate'",
|
|
1223
1223
|
"description": "The headline of the component. Set to an empty string to hide the headline.",
|
|
1224
1224
|
"attribute": "headline"
|
|
1225
|
+
},
|
|
1226
|
+
{
|
|
1227
|
+
"kind": "field",
|
|
1228
|
+
"name": "initialSortField",
|
|
1229
|
+
"type": {
|
|
1230
|
+
"text": "string"
|
|
1231
|
+
},
|
|
1232
|
+
"default": "'count'",
|
|
1233
|
+
"description": "The field by which the table is initially sorted.\nMust be one of the fields specified in the fields property, 'count', or 'proportion'.",
|
|
1234
|
+
"attribute": "initialSortField"
|
|
1235
|
+
},
|
|
1236
|
+
{
|
|
1237
|
+
"kind": "field",
|
|
1238
|
+
"name": "initialSortDirection",
|
|
1239
|
+
"type": {
|
|
1240
|
+
"text": "'ascending' | 'descending'"
|
|
1241
|
+
},
|
|
1242
|
+
"default": "'descending'",
|
|
1243
|
+
"description": "The initial sort direction of the table.",
|
|
1244
|
+
"attribute": "initialSortDirection"
|
|
1225
1245
|
}
|
|
1226
1246
|
],
|
|
1227
1247
|
"attributes": [
|
|
@@ -1278,6 +1298,24 @@
|
|
|
1278
1298
|
"default": "'Aggregate'",
|
|
1279
1299
|
"description": "The headline of the component. Set to an empty string to hide the headline.",
|
|
1280
1300
|
"fieldName": "headline"
|
|
1301
|
+
},
|
|
1302
|
+
{
|
|
1303
|
+
"name": "initialSortField",
|
|
1304
|
+
"type": {
|
|
1305
|
+
"text": "string"
|
|
1306
|
+
},
|
|
1307
|
+
"default": "'count'",
|
|
1308
|
+
"description": "The field by which the table is initially sorted.\nMust be one of the fields specified in the fields property, 'count', or 'proportion'.",
|
|
1309
|
+
"fieldName": "initialSortField"
|
|
1310
|
+
},
|
|
1311
|
+
{
|
|
1312
|
+
"name": "initialSortDirection",
|
|
1313
|
+
"type": {
|
|
1314
|
+
"text": "'ascending' | 'descending'"
|
|
1315
|
+
},
|
|
1316
|
+
"default": "'descending'",
|
|
1317
|
+
"description": "The initial sort direction of the table.",
|
|
1318
|
+
"fieldName": "initialSortDirection"
|
|
1281
1319
|
}
|
|
1282
1320
|
],
|
|
1283
1321
|
"superclass": {
|
|
@@ -7285,9 +7285,24 @@ const AggregateTable = ({ data, fields }) => {
|
|
|
7285
7285
|
];
|
|
7286
7286
|
return /* @__PURE__ */ u$1(Table, { data, columns: headers, pagination: true });
|
|
7287
7287
|
};
|
|
7288
|
-
|
|
7288
|
+
const compareAscending = (a2, b3) => {
|
|
7289
|
+
if (typeof a2 === "number" && typeof b3 === "number") {
|
|
7290
|
+
return a2 - b3;
|
|
7291
|
+
}
|
|
7292
|
+
const strA = a2 != null ? String(a2) : "";
|
|
7293
|
+
const strB = b3 != null ? String(b3) : "";
|
|
7294
|
+
return strA.localeCompare(strB);
|
|
7295
|
+
};
|
|
7296
|
+
async function queryAggregateData(variant, fields, lapis, initialSort = { field: "count", direction: "descending" }, signal) {
|
|
7297
|
+
const validSortFields = ["count", "proportion", ...fields];
|
|
7298
|
+
if (!validSortFields.includes(initialSort.field)) {
|
|
7299
|
+
throw new Error(`InitialSort field not in fields. Valid fields are: ${validSortFields.join(", ")}`);
|
|
7300
|
+
}
|
|
7289
7301
|
const fetchData = new FetchAggregatedOperator(variant, fields);
|
|
7290
|
-
const
|
|
7302
|
+
const sortData = new SortOperator(fetchData, (a2, b3) => {
|
|
7303
|
+
return initialSort.direction === "ascending" ? compareAscending(a2[initialSort.field], b3[initialSort.field]) : compareAscending(b3[initialSort.field], a2[initialSort.field]);
|
|
7304
|
+
});
|
|
7305
|
+
const data = (await sortData.evaluate(lapis, signal)).content;
|
|
7291
7306
|
const total = data.reduce((acc, row) => acc + row.count, 0);
|
|
7292
7307
|
return data.map(
|
|
7293
7308
|
(row) => ({
|
|
@@ -7302,15 +7317,32 @@ const Aggregate = ({
|
|
|
7302
7317
|
height,
|
|
7303
7318
|
headline = "Mutations",
|
|
7304
7319
|
filter,
|
|
7305
|
-
fields
|
|
7320
|
+
fields,
|
|
7321
|
+
initialSortField,
|
|
7322
|
+
initialSortDirection
|
|
7306
7323
|
}) => {
|
|
7307
7324
|
const size2 = { height, width };
|
|
7308
|
-
return /* @__PURE__ */ u$1(ErrorBoundary, { size: size2, headline, children: /* @__PURE__ */ u$1(ResizeContainer, { size: size2, children: /* @__PURE__ */ u$1(Headline, { heading: headline, children: /* @__PURE__ */ u$1(
|
|
7325
|
+
return /* @__PURE__ */ u$1(ErrorBoundary, { size: size2, headline, children: /* @__PURE__ */ u$1(ResizeContainer, { size: size2, children: /* @__PURE__ */ u$1(Headline, { heading: headline, children: /* @__PURE__ */ u$1(
|
|
7326
|
+
AggregateInner,
|
|
7327
|
+
{
|
|
7328
|
+
fields,
|
|
7329
|
+
filter,
|
|
7330
|
+
views,
|
|
7331
|
+
initialSortField,
|
|
7332
|
+
initialSortDirection
|
|
7333
|
+
}
|
|
7334
|
+
) }) }) });
|
|
7309
7335
|
};
|
|
7310
|
-
const AggregateInner = ({
|
|
7336
|
+
const AggregateInner = ({
|
|
7337
|
+
fields,
|
|
7338
|
+
views,
|
|
7339
|
+
filter,
|
|
7340
|
+
initialSortField,
|
|
7341
|
+
initialSortDirection
|
|
7342
|
+
}) => {
|
|
7311
7343
|
const lapis = P(LapisUrlContext);
|
|
7312
7344
|
const { data, error, isLoading } = useQuery(async () => {
|
|
7313
|
-
return queryAggregateData(filter, fields, lapis);
|
|
7345
|
+
return queryAggregateData(filter, fields, lapis, { field: initialSortField, direction: initialSortDirection });
|
|
7314
7346
|
}, [filter, fields, lapis]);
|
|
7315
7347
|
if (isLoading) {
|
|
7316
7348
|
return /* @__PURE__ */ u$1(LoadingDisplay, {});
|
|
@@ -7362,6 +7394,8 @@ let AggregateComponent = class extends PreactLitAdapterWithGridJsStyles {
|
|
|
7362
7394
|
this.width = "100%";
|
|
7363
7395
|
this.height = "700px";
|
|
7364
7396
|
this.headline = "Aggregate";
|
|
7397
|
+
this.initialSortField = "count";
|
|
7398
|
+
this.initialSortDirection = "descending";
|
|
7365
7399
|
}
|
|
7366
7400
|
render() {
|
|
7367
7401
|
return /* @__PURE__ */ u$1(
|
|
@@ -7372,7 +7406,9 @@ let AggregateComponent = class extends PreactLitAdapterWithGridJsStyles {
|
|
|
7372
7406
|
filter: this.filter,
|
|
7373
7407
|
width: this.width,
|
|
7374
7408
|
height: this.height,
|
|
7375
|
-
headline: this.headline
|
|
7409
|
+
headline: this.headline,
|
|
7410
|
+
initialSortField: this.initialSortField,
|
|
7411
|
+
initialSortDirection: this.initialSortDirection
|
|
7376
7412
|
}
|
|
7377
7413
|
);
|
|
7378
7414
|
}
|
|
@@ -7395,6 +7431,12 @@ __decorateClass$4([
|
|
|
7395
7431
|
__decorateClass$4([
|
|
7396
7432
|
n2({ type: String })
|
|
7397
7433
|
], AggregateComponent.prototype, "headline", 2);
|
|
7434
|
+
__decorateClass$4([
|
|
7435
|
+
n2({ type: String })
|
|
7436
|
+
], AggregateComponent.prototype, "initialSortField", 2);
|
|
7437
|
+
__decorateClass$4([
|
|
7438
|
+
n2({ type: String })
|
|
7439
|
+
], AggregateComponent.prototype, "initialSortDirection", 2);
|
|
7398
7440
|
AggregateComponent = __decorateClass$4([
|
|
7399
7441
|
t$2("gs-aggregate")
|
|
7400
7442
|
], AggregateComponent);
|