@genspectrum/dashboard-components 0.11.5 → 0.11.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.
@@ -1369,7 +1369,7 @@
1369
1369
  "type": {
1370
1370
  "text": "Meta<Required<AggregateProps>>"
1371
1371
  },
1372
- "default": "{ title: 'Visualization/Aggregate', component: 'gs-aggregate', argTypes: { fields: [{ control: 'object' }], views: { options: ['table'], control: { type: 'check' }, }, width: { control: 'text' }, height: { control: 'text' }, pageSize: { control: 'object' }, 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'], }"
1372
+ "default": "{ title: 'Visualization/Aggregate', component: 'gs-aggregate', argTypes: { fields: [{ control: 'object' }], views: { options: ['table', 'bar'], control: { type: 'check' }, }, width: { control: 'text' }, height: { control: 'text' }, pageSize: { control: 'object' }, initialSortField: { control: 'text' }, initialSortDirection: { options: ['ascending', 'descending'], control: { type: 'radio' }, }, }, parameters: withComponentDocs({ componentDocs: { opensShadowDom: true, expectsChildren: false, codeExample, }, }), tags: ['autodocs'], }"
1373
1373
  },
1374
1374
  {
1375
1375
  "kind": "variable",
@@ -1377,7 +1377,23 @@
1377
1377
  "type": {
1378
1378
  "text": "StoryObj<Required<AggregateProps>>"
1379
1379
  },
1380
- "default": "{ render: (args) => html` <gs-app lapis=\"${LAPIS_URL}\"> <gs-aggregate .fields=${args.fields} .lapisFilter=${args.lapisFilter} .views=${args.views} .width=${args.width} .height=${args.height} .initialSortField=${args.initialSortField} .initialSortDirection=${args.initialSortDirection} .pageSize=${args.pageSize} ></gs-aggregate> </gs-app> `, args: { fields: ['division', 'host'], views: ['table'], lapisFilter: { country: 'USA', }, width: '100%', height: '700px', initialSortField: 'count', initialSortDirection: 'descending', pageSize: 10, }, }"
1380
+ "default": "{ render: (args) => html` <gs-app lapis=\"${LAPIS_URL}\"> <gs-aggregate .fields=${args.fields} .lapisFilter=${args.lapisFilter} .views=${args.views} .width=${args.width} .height=${args.height} .initialSortField=${args.initialSortField} .initialSortDirection=${args.initialSortDirection} .pageSize=${args.pageSize} .maxNumberOfBars=${args.maxNumberOfBars} ></gs-aggregate> </gs-app> `, parameters: { fetchMock: { mocks: [ { matcher: { name: 'aggregatedData', url: AGGREGATED_ENDPOINT, body: { fields: ['division', 'host'], country: 'USA', }, }, response: { status: 200, body: aggregatedData, }, }, ], }, }, args: { fields: ['division', 'host'], views: ['table', 'bar'], lapisFilter: { country: 'USA', }, width: '100%', height: '700px', initialSortField: 'count', initialSortDirection: 'descending', pageSize: 10, maxNumberOfBars: 10, }, }"
1381
+ },
1382
+ {
1383
+ "kind": "variable",
1384
+ "name": "BarChartWithOneField",
1385
+ "type": {
1386
+ "text": "StoryObj<Required<AggregateProps>>"
1387
+ },
1388
+ "default": "{ ...Table, args: { ...Table.args, fields: ['division'], views: ['bar', 'table'], }, parameters: { fetchMock: { mocks: [ { matcher: { name: 'aggregatedData', url: AGGREGATED_ENDPOINT, body: { fields: ['division'], country: 'USA', }, }, response: { status: 200, body: aggregatedDataWith1Field, }, }, ], }, }, }"
1389
+ },
1390
+ {
1391
+ "kind": "variable",
1392
+ "name": "BarChartWithTwoFields",
1393
+ "type": {
1394
+ "text": "StoryObj<Required<AggregateProps>>"
1395
+ },
1396
+ "default": "{ ...Table, args: { ...Table.args, fields: ['division', 'nextstrainClade'], lapisFilter: { country: 'Germany', dateTo: '2022-02-01', }, views: ['bar', 'table'], }, parameters: { fetchMock: { mocks: [ { matcher: { name: 'aggregatedData', url: AGGREGATED_ENDPOINT, body: { fields: ['division', 'nextstrainClade'], country: 'Germany', dateTo: '2022-02-01', }, }, response: { status: 200, body: aggregatedDataWith2Fields, }, }, ], }, }, }"
1381
1397
  }
1382
1398
  ],
1383
1399
  "exports": [
@@ -1396,6 +1412,22 @@
1396
1412
  "name": "Table",
1397
1413
  "module": "src/web-components/visualization/gs-aggregate.stories.ts"
1398
1414
  }
1415
+ },
1416
+ {
1417
+ "kind": "js",
1418
+ "name": "BarChartWithOneField",
1419
+ "declaration": {
1420
+ "name": "BarChartWithOneField",
1421
+ "module": "src/web-components/visualization/gs-aggregate.stories.ts"
1422
+ }
1423
+ },
1424
+ {
1425
+ "kind": "js",
1426
+ "name": "BarChartWithTwoFields",
1427
+ "declaration": {
1428
+ "name": "BarChartWithTwoFields",
1429
+ "module": "src/web-components/visualization/gs-aggregate.stories.ts"
1430
+ }
1399
1431
  }
1400
1432
  ]
1401
1433
  },
@@ -1405,7 +1437,7 @@
1405
1437
  "declarations": [
1406
1438
  {
1407
1439
  "kind": "class",
1408
- "description": "## Context\n\nThis component displays aggregated data in a table, which can provide an overview of the underlying data.\n\nIt expects a list of `fields` to aggregate by and a `filter` to apply to the data.\n\n## Views\n\n### Table View\n\nIn the table view, the data is presented in a table format where each field is a column,\nalong with the aggregated value and its proportion.\nThe proportion represents the ratio of the aggregated value to the total count of the data\n(considering the applied filter).",
1440
+ "description": "## Context\n\nThis component displays aggregated data in a table, which can provide an overview of the underlying data.\n\nIt expects a list of `fields` to aggregate by and a `filter` to apply to the data.\n\n## Views\n\n### Table View\n\nIn the table view, the data is presented in a table format where each field is a column,\nalong with the aggregated value and its proportion.\nThe proportion represents the ratio of the aggregated value to the total count of the data\n(considering the applied filter).\n\n### Bar Chart View\n\nIn the bar chart view, the data is presented in vertical bars.\nThe bar chart is supported when `fields` contains one or two entries.\nThe first field will be used as the y-axis.\nIf a second field is provided, it's values will be stacked along the x-axis for each key on the y-axis.\n\nThe chart shows the bars with the highest aggregated `count`.\nThe number of bars can be adjusted with the `maxNumberOfBars` property.",
1409
1441
  "name": "AggregateComponent",
1410
1442
  "members": [
1411
1443
  {
@@ -1487,6 +1519,16 @@
1487
1519
  "default": "false",
1488
1520
  "description": "The maximum number of rows to display in the table view.\nSet to `false` to disable pagination. Set to `true` to enable pagination with a default limit (10).",
1489
1521
  "attribute": "pageSize"
1522
+ },
1523
+ {
1524
+ "kind": "field",
1525
+ "name": "maxNumberOfBars",
1526
+ "type": {
1527
+ "text": "number"
1528
+ },
1529
+ "default": "20",
1530
+ "description": "The maximum number of bars to display in the bar chart view.",
1531
+ "attribute": "maxNumberOfBars"
1490
1532
  }
1491
1533
  ],
1492
1534
  "attributes": [
@@ -1561,6 +1603,15 @@
1561
1603
  "default": "false",
1562
1604
  "description": "The maximum number of rows to display in the table view.\nSet to `false` to disable pagination. Set to `true` to enable pagination with a default limit (10).",
1563
1605
  "fieldName": "pageSize"
1606
+ },
1607
+ {
1608
+ "name": "maxNumberOfBars",
1609
+ "type": {
1610
+ "text": "number"
1611
+ },
1612
+ "default": "20",
1613
+ "description": "The maximum number of bars to display in the bar chart view.",
1614
+ "fieldName": "maxNumberOfBars"
1564
1615
  }
1565
1616
  ],
1566
1617
  "superclass": {
@@ -22,6 +22,16 @@ import { TemplateResult } from 'lit-html';
22
22
  * along with the aggregated value and its proportion.
23
23
  * The proportion represents the ratio of the aggregated value to the total count of the data
24
24
  * (considering the applied filter).
25
+ *
26
+ * ### Bar Chart View
27
+ *
28
+ * In the bar chart view, the data is presented in vertical bars.
29
+ * The bar chart is supported when `fields` contains one or two entries.
30
+ * The first field will be used as the y-axis.
31
+ * If a second field is provided, it's values will be stacked along the x-axis for each key on the y-axis.
32
+ *
33
+ * The chart shows the bars with the highest aggregated `count`.
34
+ * The number of bars can be adjusted with the `maxNumberOfBars` property.
25
35
  */
26
36
  export declare class AggregateComponent extends PreactLitAdapterWithGridJsStyles {
27
37
  /**
@@ -72,12 +82,16 @@ export declare class AggregateComponent extends PreactLitAdapterWithGridJsStyles
72
82
  * Set to `false` to disable pagination. Set to `true` to enable pagination with a default limit (10).
73
83
  */
74
84
  pageSize: boolean | number;
85
+ /**
86
+ * The maximum number of bars to display in the bar chart view.
87
+ */
88
+ maxNumberOfBars: number;
75
89
  render(): JSX_2.Element;
76
90
  }
77
91
 
78
92
  declare type AggregateView = default_2.infer<typeof aggregateViewSchema>;
79
93
 
80
- declare const aggregateViewSchema: default_2.ZodLiteral<"table">;
94
+ declare const aggregateViewSchema: default_2.ZodUnion<[default_2.ZodLiteral<"table">, default_2.ZodLiteral<"bar">]>;
81
95
 
82
96
  /**
83
97
  * ## Context
@@ -1301,7 +1315,7 @@ declare global {
1301
1315
 
1302
1316
  declare global {
1303
1317
  interface HTMLElementTagNameMap {
1304
- 'gs-mutations-over-time': MutationsOverTimeComponent;
1318
+ 'gs-number-sequences-over-time': NumberSequencesOverTimeComponent;
1305
1319
  }
1306
1320
  }
1307
1321
 
@@ -1309,7 +1323,7 @@ declare global {
1309
1323
  declare global {
1310
1324
  namespace JSX {
1311
1325
  interface IntrinsicElements {
1312
- 'gs-mutations-over-time': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
1326
+ 'gs-number-sequences-over-time': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
1313
1327
  }
1314
1328
  }
1315
1329
  }
@@ -1317,7 +1331,7 @@ declare global {
1317
1331
 
1318
1332
  declare global {
1319
1333
  interface HTMLElementTagNameMap {
1320
- 'gs-number-sequences-over-time': NumberSequencesOverTimeComponent;
1334
+ 'gs-mutations-over-time': MutationsOverTimeComponent;
1321
1335
  }
1322
1336
  }
1323
1337
 
@@ -1325,7 +1339,7 @@ declare global {
1325
1339
  declare global {
1326
1340
  namespace JSX {
1327
1341
  interface IntrinsicElements {
1328
- 'gs-number-sequences-over-time': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
1342
+ 'gs-mutations-over-time': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
1329
1343
  }
1330
1344
  }
1331
1345
  }
@@ -4,7 +4,7 @@ import { LitElement, html, unsafeCSS } from "lit";
4
4
  import z$1 from "zod";
5
5
  import { options, createContext as createContext$1, Fragment, render } from "preact";
6
6
  import { Grid } from "gridjs";
7
- import { Chart, registerables, Scale } from "chart.js";
7
+ import { Chart, registerables, Scale, BarController } from "chart.js";
8
8
  import { VennDiagramController, ArcSlice, extractSets } from "chartjs-chart-venn";
9
9
  import { v as views, n as namedLapisFilterSchema, s as sequenceTypeSchema, l as lapisFilterSchema, t as temporalGranularitySchema, a as dateRangeOptionSchema, b as toYYYYMMDD, D as DateRangeOptionChangedEvent, m as mutationsFilterSchema } from "./dateRangeOption-Bh2p78z0.js";
10
10
  import { autoUpdate, computePosition, offset, shift, flip } from "@floating-ui/dom";
@@ -4742,6 +4742,9 @@ input.tab:checked + .tab-content,
4742
4742
  .static {
4743
4743
  position: static;
4744
4744
  }
4745
+ .fixed {
4746
+ position: fixed;
4747
+ }
4745
4748
  .absolute {
4746
4749
  position: absolute;
4747
4750
  }
@@ -5935,7 +5938,7 @@ const ColorsRGB = {
5935
5938
  const singleGraphColorRGBAById = (id, alpha = 1) => {
5936
5939
  const keys = Object.keys(ColorsRGB);
5937
5940
  const key = keys[id % keys.length];
5938
- return `rgba(${ColorsRGB[key].join(",")},${alpha})`;
5941
+ return singleGraphColorRGBByName(key, alpha);
5939
5942
  };
5940
5943
  const singleGraphColorRGBByName = (name, alpha = 1) => {
5941
5944
  return `rgba(${ColorsRGB[name].join(",")},${alpha})`;
@@ -8244,15 +8247,9 @@ const compareAscending = (a2, b3) => {
8244
8247
  const strB = b3 != null ? String(b3) : "";
8245
8248
  return strA.localeCompare(strB);
8246
8249
  };
8247
- async function queryAggregateData(lapisFilter, fields, lapis, initialSort = { field: "count", direction: "descending" }, signal) {
8248
- const validSortFields = ["count", "proportion", ...fields];
8249
- if (!validSortFields.includes(initialSort.field)) {
8250
- throw new Error(`InitialSort field not in fields. Valid fields are: ${validSortFields.join(", ")}`);
8251
- }
8250
+ async function queryAggregateData(lapisFilter, fields, lapis, signal) {
8252
8251
  const fetchData = new FetchAggregatedOperator(lapisFilter, fields);
8253
- const sortData = new SortOperator(fetchData, (a2, b3) => {
8254
- return initialSort.direction === "ascending" ? compareAscending(a2[initialSort.field], b3[initialSort.field]) : compareAscending(b3[initialSort.field], a2[initialSort.field]);
8255
- });
8252
+ const sortData = new SortOperator(fetchData, (a2, b3) => compareAscending(b3.count, a2.count));
8256
8253
  const data = (await sortData.evaluate(lapis, signal)).content;
8257
8254
  const total = data.reduce((acc, row) => acc + row.count, 0);
8258
8255
  return data.map(
@@ -8262,7 +8259,13 @@ async function queryAggregateData(lapisFilter, fields, lapis, initialSort = { fi
8262
8259
  })
8263
8260
  );
8264
8261
  }
8265
- const AggregateTable = ({ data, fields, pageSize }) => {
8262
+ const AggregateTable = ({
8263
+ data,
8264
+ fields,
8265
+ pageSize,
8266
+ initialSortField,
8267
+ initialSortDirection
8268
+ }) => {
8266
8269
  const headers = [
8267
8270
  ...fields.map((field) => {
8268
8271
  return {
@@ -8282,9 +8285,137 @@ const AggregateTable = ({ data, fields, pageSize }) => {
8282
8285
  formatter: (cell) => formatProportion(cell)
8283
8286
  }
8284
8287
  ];
8285
- return /* @__PURE__ */ u$1(Table, { data, columns: headers, pageSize });
8288
+ const sortedData = T(() => {
8289
+ const validSortFields = ["count", "proportion", ...fields];
8290
+ if (!validSortFields.includes(initialSortField)) {
8291
+ throw new Error(`InitialSort field not in fields. Valid fields are: ${validSortFields.join(", ")}`);
8292
+ }
8293
+ return data.sort(
8294
+ (a2, b3) => initialSortDirection === "ascending" ? compareAscending(a2[initialSortField], b3[initialSortField]) : compareAscending(b3[initialSortField], a2[initialSortField])
8295
+ );
8296
+ }, [data, initialSortField, initialSortDirection, fields]);
8297
+ return /* @__PURE__ */ u$1(Table, { data: sortedData, columns: headers, pageSize });
8298
+ };
8299
+ Chart.register(...registerables, BarController);
8300
+ const AggregateBarChart = ({ data, fields, maxNumberOfBars }) => {
8301
+ if (data.length === 0) {
8302
+ return /* @__PURE__ */ u$1(NoDataDisplay, {});
8303
+ }
8304
+ if (fields.length === 0) {
8305
+ throw new UserFacingError(
8306
+ "No fields given",
8307
+ 'Cannot display a bar chart when the "fields" attribute of this component is empty, i.e. there are no fields given that the data should be stratified by. This must be fixed by the administrator of this page.'
8308
+ );
8309
+ }
8310
+ if (fields.length > 2) {
8311
+ throw new UserFacingError(
8312
+ "Too many fields given",
8313
+ `Cannot display a bar chart when the "fields" attribute of this component contains more than two values. Got the fields: ${fields.join(", ")}. This must be fixed by the administrator of this page.`
8314
+ );
8315
+ }
8316
+ return /* @__PURE__ */ u$1(AggregateBarChartInner, { data, fields, maxNumberOfBars });
8317
+ };
8318
+ const AggregateBarChartInner = ({ data, fields, maxNumberOfBars }) => {
8319
+ const config = T(() => {
8320
+ const { datasets: datasets2, countsOfEachBar } = getDatasets$2(fields, maxNumberOfBars, data);
8321
+ return {
8322
+ type: "bar",
8323
+ data: {
8324
+ datasets: datasets2
8325
+ },
8326
+ options: {
8327
+ maintainAspectRatio: false,
8328
+ animation: false,
8329
+ indexAxis: "y",
8330
+ scales: {
8331
+ x: {
8332
+ stacked: true
8333
+ },
8334
+ y: {
8335
+ stacked: true
8336
+ }
8337
+ },
8338
+ plugins: {
8339
+ legend: {
8340
+ display: false
8341
+ },
8342
+ tooltip: {
8343
+ mode: "y",
8344
+ callbacks: {
8345
+ afterTitle: countsOfEachBar === void 0 ? void 0 : (tooltipItems) => {
8346
+ return `Total: ${countsOfEachBar.get(tooltipItems[0].label)}`;
8347
+ },
8348
+ label: (context) => {
8349
+ const { x: x2, proportion } = context.dataset.data[context.dataIndex];
8350
+ return fields.length === 1 ? `${x2} (${formatProportion(proportion)})` : `${context.dataset.label}: ${x2} (${formatProportion(proportion)})`;
8351
+ }
8352
+ }
8353
+ }
8354
+ }
8355
+ }
8356
+ };
8357
+ }, [data, fields, maxNumberOfBars]);
8358
+ return /* @__PURE__ */ u$1(GsChart, { configuration: config });
8286
8359
  };
8287
- const aggregateViewSchema = z$1.literal(views.table);
8360
+ function getDatasets$2(fields, maxNumberOfBars, data) {
8361
+ var _a;
8362
+ const sortedData = data.sort((a2, b3) => b3.count - a2.count);
8363
+ if (fields.length === 1) {
8364
+ return {
8365
+ datasets: [
8366
+ {
8367
+ borderWidth: 1,
8368
+ backgroundColor: singleGraphColorRGBAById(0, 0.3),
8369
+ borderColor: singleGraphColorRGBAById(0),
8370
+ data: sortedData.slice(0, maxNumberOfBars).map((row) => ({
8371
+ y: row[fields[0]],
8372
+ x: row.count,
8373
+ proportion: row.proportion
8374
+ }))
8375
+ }
8376
+ ]
8377
+ };
8378
+ }
8379
+ const map = /* @__PURE__ */ new Map();
8380
+ const countsOfEachBar = /* @__PURE__ */ new Map();
8381
+ for (const row of sortedData) {
8382
+ const yValue = row[fields[0]];
8383
+ const secondaryValue = row[fields[1]];
8384
+ if (yValue === null || secondaryValue === null) {
8385
+ continue;
8386
+ }
8387
+ const yAxisKey = String(yValue);
8388
+ const secondaryKey = String(secondaryValue);
8389
+ if (!map.has(secondaryKey)) {
8390
+ map.set(secondaryKey, []);
8391
+ }
8392
+ (_a = map.get(secondaryKey)) == null ? void 0 : _a.push({
8393
+ y: yAxisKey,
8394
+ x: row.count,
8395
+ proportion: row.proportion
8396
+ });
8397
+ countsOfEachBar.set(yAxisKey, (countsOfEachBar.get(yAxisKey) ?? 0) + row.count);
8398
+ }
8399
+ const datasets2 = Array.from(map.entries()).map(sortAndTruncateYAxisKeys(countsOfEachBar, maxNumberOfBars)).map(([key, value], index) => ({
8400
+ borderWidth: 1,
8401
+ backgroundColor: singleGraphColorRGBAById(index, 0.3),
8402
+ borderColor: singleGraphColorRGBAById(index),
8403
+ label: key,
8404
+ data: value
8405
+ }));
8406
+ return { datasets: datasets2, countsOfEachBar };
8407
+ }
8408
+ function sortAndTruncateYAxisKeys(countsOfEachBar, maxNumberOfBars) {
8409
+ const yAxisKeysToConsider = new Set(
8410
+ Array.from(countsOfEachBar.entries()).sort((a2, b3) => b3[1] - a2[1]).slice(0, maxNumberOfBars).map(([key]) => key)
8411
+ );
8412
+ return ([key, value]) => {
8413
+ const sortedValues = value.sort((a2, b3) => (countsOfEachBar.get(b3.y) ?? 0) - (countsOfEachBar.get(a2.y) ?? 0));
8414
+ const valuesWithLargestBars = sortedValues.slice(0, maxNumberOfBars).filter((v2) => yAxisKeysToConsider.has(v2.y));
8415
+ return [key, valuesWithLargestBars];
8416
+ };
8417
+ }
8418
+ const aggregateViewSchema = z$1.union([z$1.literal(views.table), z$1.literal(views.bar)]);
8288
8419
  const aggregatePropsSchema = z$1.object({
8289
8420
  lapisFilter: lapisFilterSchema,
8290
8421
  fields: z$1.array(z$1.string().min(1)),
@@ -8293,7 +8424,8 @@ const aggregatePropsSchema = z$1.object({
8293
8424
  initialSortDirection: z$1.union([z$1.literal("ascending"), z$1.literal("descending")]),
8294
8425
  pageSize: z$1.union([z$1.boolean(), z$1.number()]),
8295
8426
  width: z$1.string(),
8296
- height: z$1.string()
8427
+ height: z$1.string(),
8428
+ maxNumberOfBars: z$1.number()
8297
8429
  });
8298
8430
  const Aggregate = (componentProps) => {
8299
8431
  const { width, height } = componentProps;
@@ -8304,10 +8436,7 @@ const AggregateInner = (componentProps) => {
8304
8436
  const { fields, lapisFilter, initialSortField, initialSortDirection } = componentProps;
8305
8437
  const lapis = x(LapisUrlContext);
8306
8438
  const { data, error, isLoading } = useQuery(async () => {
8307
- return queryAggregateData(lapisFilter, fields, lapis, {
8308
- field: initialSortField,
8309
- direction: initialSortDirection
8310
- });
8439
+ return queryAggregateData(lapisFilter, fields, lapis);
8311
8440
  }, [lapisFilter, fields, lapis, initialSortField, initialSortDirection]);
8312
8441
  if (isLoading) {
8313
8442
  return /* @__PURE__ */ u$1(LoadingDisplay, {});
@@ -8323,7 +8452,7 @@ const AggregateInner = (componentProps) => {
8323
8452
  const AggregatedDataTabs = ({ data, originalComponentProps }) => {
8324
8453
  const getTab = (view) => {
8325
8454
  switch (view) {
8326
- case "table":
8455
+ case views.table:
8327
8456
  return {
8328
8457
  title: "Table",
8329
8458
  content: /* @__PURE__ */ u$1(
@@ -8331,7 +8460,21 @@ const AggregatedDataTabs = ({ data, originalComponentProps }) => {
8331
8460
  {
8332
8461
  data,
8333
8462
  fields: originalComponentProps.fields,
8334
- pageSize: originalComponentProps.pageSize
8463
+ pageSize: originalComponentProps.pageSize,
8464
+ initialSortField: originalComponentProps.initialSortField,
8465
+ initialSortDirection: originalComponentProps.initialSortDirection
8466
+ }
8467
+ )
8468
+ };
8469
+ case views.bar:
8470
+ return {
8471
+ title: "Bar",
8472
+ content: /* @__PURE__ */ u$1(
8473
+ AggregateBarChart,
8474
+ {
8475
+ data,
8476
+ fields: originalComponentProps.fields,
8477
+ maxNumberOfBars: originalComponentProps.maxNumberOfBars
8335
8478
  }
8336
8479
  )
8337
8480
  };
@@ -8381,6 +8524,7 @@ let AggregateComponent = class extends PreactLitAdapterWithGridJsStyles {
8381
8524
  this.initialSortField = "count";
8382
8525
  this.initialSortDirection = "descending";
8383
8526
  this.pageSize = false;
8527
+ this.maxNumberOfBars = 20;
8384
8528
  }
8385
8529
  render() {
8386
8530
  return /* @__PURE__ */ u$1(
@@ -8393,7 +8537,8 @@ let AggregateComponent = class extends PreactLitAdapterWithGridJsStyles {
8393
8537
  height: this.height,
8394
8538
  initialSortField: this.initialSortField,
8395
8539
  initialSortDirection: this.initialSortDirection,
8396
- pageSize: this.pageSize
8540
+ pageSize: this.pageSize,
8541
+ maxNumberOfBars: this.maxNumberOfBars
8397
8542
  }
8398
8543
  );
8399
8544
  }
@@ -8422,6 +8567,9 @@ __decorateClass$9([
8422
8567
  __decorateClass$9([
8423
8568
  n2({ type: Object })
8424
8569
  ], AggregateComponent.prototype, "pageSize", 2);
8570
+ __decorateClass$9([
8571
+ n2({ type: Object })
8572
+ ], AggregateComponent.prototype, "maxNumberOfBars", 2);
8425
8573
  AggregateComponent = __decorateClass$9([
8426
8574
  t$2("gs-aggregate")
8427
8575
  ], AggregateComponent);
@@ -9103,7 +9251,7 @@ const MutationsOverTimeGrid = ({ data, colorScale }) => {
9103
9251
  ] });
9104
9252
  };
9105
9253
  function getTooltipPosition(rowIndex, rows, columnIndex, columns) {
9106
- const tooltipX = rowIndex < rows / 2 ? "bottom" : "top";
9254
+ const tooltipX = rowIndex < rows / 2 || rowIndex < 6 ? "bottom" : "top";
9107
9255
  const tooltipY = columnIndex < columns / 2 ? "start" : "end";
9108
9256
  return `${tooltipX}-${tooltipY}`;
9109
9257
  }
@@ -10580,8 +10728,8 @@ SequencesByLocationComponent = __decorateClass$6([
10580
10728
  t$2("gs-sequences-by-location")
10581
10729
  ], SequencesByLocationComponent);
10582
10730
  async function queryGeneralStatistics(numeratorFilter, denominatorFilter, lapis, signal) {
10583
- const numeratorCount = await queryAggregateData(numeratorFilter, [], lapis, void 0, signal);
10584
- const denominatorCount = await queryAggregateData(denominatorFilter, [], lapis, void 0, signal);
10731
+ const numeratorCount = await queryAggregateData(numeratorFilter, [], lapis, signal);
10732
+ const denominatorCount = await queryAggregateData(denominatorFilter, [], lapis, signal);
10585
10733
  if (numeratorCount.length === 0 || denominatorCount.length === 0) {
10586
10734
  throw new Error("No data found for the given filters");
10587
10735
  }