@genspectrum/dashboard-components 0.16.0 → 0.16.1

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.
@@ -1983,7 +1983,7 @@
1983
1983
  "type": {
1984
1984
  "text": "Meta<Required<MutationsOverTimeProps>>"
1985
1985
  },
1986
- "default": "{ title: 'Visualization/Mutations over time', component: 'gs-mutations-over-time', argTypes: { lapisFilter: { control: 'object' }, sequenceType: { options: ['nucleotide', 'amino acid'], control: { type: 'radio' }, }, views: { options: ['grid'], control: { type: 'check' }, }, width: { control: 'text' }, height: { control: 'text' }, granularity: { options: ['day', 'week', 'month', 'year'], control: { type: 'radio' }, }, lapisDateField: { control: 'text' }, }, args: { lapisFilter: { pangoLineage: 'JN.1*', dateFrom: '2024-01-15', dateTo: '2024-07-10' }, sequenceType: 'nucleotide', views: ['grid'], width: '100%', granularity: 'month', lapisDateField: 'date', }, parameters: withComponentDocs({ componentDocs: { opensShadowDom: true, expectsChildren: false, codeExample, }, fetchMock: {}, }), tags: ['autodocs'], }"
1986
+ "default": "{ title: 'Visualization/Mutations over time', component: 'gs-mutations-over-time', argTypes: { lapisFilter: { control: 'object' }, sequenceType: { options: ['nucleotide', 'amino acid'], control: { type: 'radio' }, }, views: { options: ['grid'], control: { type: 'check' }, }, width: { control: 'text' }, height: { control: 'text' }, granularity: { options: ['day', 'week', 'month', 'year'], control: { type: 'radio' }, }, lapisDateField: { control: 'text' }, displayMutations: { control: 'object' }, initialMeanProportionInterval: { control: 'object' }, }, args: { lapisFilter: { pangoLineage: 'JN.1*', dateFrom: '2024-01-15', dateTo: '2024-07-10' }, sequenceType: 'nucleotide', views: ['grid'], width: '100%', granularity: 'month', lapisDateField: 'date', initialMeanProportionInterval: { min: 0.05, max: 0.9 }, }, parameters: withComponentDocs({ componentDocs: { opensShadowDom: true, expectsChildren: false, codeExample, }, fetchMock: {}, }), tags: ['autodocs'], }"
1987
1987
  },
1988
1988
  {
1989
1989
  "kind": "variable",
@@ -1993,6 +1993,14 @@
1993
1993
  },
1994
1994
  "default": "{ ...Template, }"
1995
1995
  },
1996
+ {
1997
+ "kind": "variable",
1998
+ "name": "ByMonthWithFilterOnDisplayedMutations",
1999
+ "type": {
2000
+ "text": "StoryObj<Required<MutationsOverTimeProps>>"
2001
+ },
2002
+ "default": "{ ...Template, args: { ...Template.args, displayMutations: ['A19722G', 'G21641T', 'T21653-'], }, }"
2003
+ },
1996
2004
  {
1997
2005
  "kind": "variable",
1998
2006
  "name": "ByWeek",
@@ -2043,6 +2051,14 @@
2043
2051
  "module": "src/web-components/visualization/gs-mutations-over-time.stories.ts"
2044
2052
  }
2045
2053
  },
2054
+ {
2055
+ "kind": "js",
2056
+ "name": "ByMonthWithFilterOnDisplayedMutations",
2057
+ "declaration": {
2058
+ "name": "ByMonthWithFilterOnDisplayedMutations",
2059
+ "module": "src/web-components/visualization/gs-mutations-over-time.stories.ts"
2060
+ }
2061
+ },
2046
2062
  {
2047
2063
  "kind": "js",
2048
2064
  "name": "ByWeek",
@@ -2083,7 +2099,7 @@
2083
2099
  "declarations": [
2084
2100
  {
2085
2101
  "kind": "class",
2086
- "description": "## Context\n\nThis component displays mutations (substitutions and deletions) over time for a dataset selected by a LAPIS filter.\nThe shown date range is determined by the date field in the LAPIS filter.\nIf the date field is not set, the date range is determined by all available dates in the dataset.\n\n## Views\n\n### Grid View\n\nThe grid view shows the proportion for each mutation over date ranges.\n\nThe grid limits the number of rows and columns for browser performance reasons as\ntoo much data might make the browser unresponsive.\n\nThe number of columns is limited to 200.\nIf this number are exceeded, an error message will be shown.\nIt is your responsibility to make sure that this does not happen.\nDepending on the selected date range in the `lapisFilter`, you can adapt the granularity accordingly\n(e.g. use months instead of days).\n\nThe number of rows is limited to 100.\nIf there are more, the component will only show 100 mutations and notify the user.",
2102
+ "description": "## Context\n\nThis component displays mutations (substitutions and deletions) over time for a dataset selected by a LAPIS filter.\nThe shown date range is determined by the date field in the LAPIS filter.\nIf the date field is not set, the date range is determined by all available dates in the dataset.\n\n## Views\n\n### Grid View\n\nThe grid view shows the proportion for each mutation over date ranges.\n\nThe grid limits the number of rows and columns for browser performance reasons as\ntoo much data might make the browser unresponsive.\n\nThe number of columns is limited to 200.\nIf this number are exceeded, an error message will be shown.\nIt is your responsibility to make sure that this does not happen.\nDepending on the selected date range in the `lapisFilter`, you can adapt the granularity accordingly\n(e.g. use months instead of days).\n\nThe number of rows is limited to 100.\nIf there are more, the component will only show 100 mutations and notify the user.\n\nUsers can filter the displayed rows by mean proportion via a slider in the toolbar.\nThe mean proportion of each row is calculated by LAPIS over the whole data range that the component displays.\nThe initial mean proportion can be set via `initialMeanProportionInterval`.",
2087
2103
  "name": "MutationsOverTimeComponent",
2088
2104
  "members": [
2089
2105
  {
@@ -2155,6 +2171,26 @@
2155
2171
  "default": "'date'",
2156
2172
  "description": "Required.\n\nThe LAPIS field that the data should be aggregated by.\nThe values will be used for the columns of the grid.\nMust be a field of type `date` in LAPIS.",
2157
2173
  "attribute": "lapisDateField"
2174
+ },
2175
+ {
2176
+ "kind": "field",
2177
+ "name": "displayMutations",
2178
+ "type": {
2179
+ "text": "string[] | undefined"
2180
+ },
2181
+ "default": "undefined",
2182
+ "description": "If provided, only the given mutations will be displayed.\nThe mutations must be provided in the exact format as they would be displayed by the component.",
2183
+ "attribute": "displayMutations"
2184
+ },
2185
+ {
2186
+ "kind": "field",
2187
+ "name": "initialMeanProportionInterval",
2188
+ "type": {
2189
+ "text": "{ min: number; max: number }"
2190
+ },
2191
+ "default": "{ min: 0.05, max: 0.9 }",
2192
+ "description": "The initial proportion interval for the grid view.\nThe values must be between 0 and 1, inclusive.",
2193
+ "attribute": "initialMeanProportionInterval"
2158
2194
  }
2159
2195
  ],
2160
2196
  "attributes": [
@@ -2220,6 +2256,24 @@
2220
2256
  "default": "'date'",
2221
2257
  "description": "Required.\n\nThe LAPIS field that the data should be aggregated by.\nThe values will be used for the columns of the grid.\nMust be a field of type `date` in LAPIS.",
2222
2258
  "fieldName": "lapisDateField"
2259
+ },
2260
+ {
2261
+ "name": "displayMutations",
2262
+ "type": {
2263
+ "text": "string[] | undefined"
2264
+ },
2265
+ "default": "undefined",
2266
+ "description": "If provided, only the given mutations will be displayed.\nThe mutations must be provided in the exact format as they would be displayed by the component.",
2267
+ "fieldName": "displayMutations"
2268
+ },
2269
+ {
2270
+ "name": "initialMeanProportionInterval",
2271
+ "type": {
2272
+ "text": "{ min: number; max: number }"
2273
+ },
2274
+ "default": "{ min: 0.05, max: 0.9 }",
2275
+ "description": "The initial proportion interval for the grid view.\nThe values must be between 0 and 1, inclusive.",
2276
+ "fieldName": "initialMeanProportionInterval"
2223
2277
  }
2224
2278
  ],
2225
2279
  "superclass": {
@@ -594,6 +594,10 @@ export declare class MutationsComponent extends PreactLitAdapterWithGridJsStyles
594
594
  *
595
595
  * The number of rows is limited to 100.
596
596
  * If there are more, the component will only show 100 mutations and notify the user.
597
+ *
598
+ * Users can filter the displayed rows by mean proportion via a slider in the toolbar.
599
+ * The mean proportion of each row is calculated by LAPIS over the whole data range that the component displays.
600
+ * The initial mean proportion can be set via `initialMeanProportionInterval`.
597
601
  */
598
602
  export declare class MutationsOverTimeComponent extends PreactLitAdapterWithGridJsStyles {
599
603
  /**
@@ -637,6 +641,19 @@ export declare class MutationsOverTimeComponent extends PreactLitAdapterWithGrid
637
641
  * Must be a field of type `date` in LAPIS.
638
642
  */
639
643
  lapisDateField: string;
644
+ /**
645
+ * If provided, only the given mutations will be displayed.
646
+ * The mutations must be provided in the exact format as they would be displayed by the component.
647
+ */
648
+ displayMutations: string[] | undefined;
649
+ /**
650
+ * The initial proportion interval for the grid view.
651
+ * The values must be between 0 and 1, inclusive.
652
+ */
653
+ initialMeanProportionInterval: {
654
+ min: number;
655
+ max: number;
656
+ };
640
657
  render(): JSX_2.Element;
641
658
  }
642
659
 
@@ -1390,7 +1407,7 @@ declare global {
1390
1407
 
1391
1408
  declare global {
1392
1409
  interface HTMLElementTagNameMap {
1393
- 'gs-relative-growth-advantage': RelativeGrowthAdvantageComponent;
1410
+ 'gs-aggregate': AggregateComponent;
1394
1411
  }
1395
1412
  }
1396
1413
 
@@ -1398,7 +1415,7 @@ declare global {
1398
1415
  declare global {
1399
1416
  namespace JSX {
1400
1417
  interface IntrinsicElements {
1401
- 'gs-relative-growth-advantage': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
1418
+ 'gs-aggregate': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
1402
1419
  }
1403
1420
  }
1404
1421
  }
@@ -1406,7 +1423,7 @@ declare global {
1406
1423
 
1407
1424
  declare global {
1408
1425
  interface HTMLElementTagNameMap {
1409
- 'gs-aggregate': AggregateComponent;
1426
+ 'gs-relative-growth-advantage': RelativeGrowthAdvantageComponent;
1410
1427
  }
1411
1428
  }
1412
1429
 
@@ -1414,7 +1431,7 @@ declare global {
1414
1431
  declare global {
1415
1432
  namespace JSX {
1416
1433
  interface IntrinsicElements {
1417
- 'gs-aggregate': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
1434
+ 'gs-relative-growth-advantage': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
1418
1435
  }
1419
1436
  }
1420
1437
  }
@@ -1484,6 +1501,22 @@ declare global {
1484
1501
  }
1485
1502
 
1486
1503
 
1504
+ declare global {
1505
+ interface HTMLElementTagNameMap {
1506
+ 'gs-wastewater-mutations-over-time': WastewaterMutationsOverTimeComponent;
1507
+ }
1508
+ }
1509
+
1510
+
1511
+ declare global {
1512
+ namespace JSX {
1513
+ interface IntrinsicElements {
1514
+ 'gs-wastewater-mutations-over-time': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
1515
+ }
1516
+ }
1517
+ }
1518
+
1519
+
1487
1520
  declare global {
1488
1521
  interface HTMLElementTagNameMap {
1489
1522
  'gs-date-range-filter': DateRangeFilterComponent;
@@ -1580,22 +1613,6 @@ declare global {
1580
1613
  }
1581
1614
 
1582
1615
 
1583
- declare global {
1584
- interface HTMLElementTagNameMap {
1585
- 'gs-wastewater-mutations-over-time': WastewaterMutationsOverTimeComponent;
1586
- }
1587
- }
1588
-
1589
-
1590
- declare global {
1591
- namespace JSX {
1592
- interface IntrinsicElements {
1593
- 'gs-wastewater-mutations-over-time': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
1594
- }
1595
- }
1596
- }
1597
-
1598
-
1599
1616
  declare module 'chart.js' {
1600
1617
  interface CartesianScaleTypeRegistry {
1601
1618
  logit: {
@@ -2,7 +2,7 @@ import { createContext, provide, consume } from "@lit/context";
2
2
  import { Task } from "@lit/task";
3
3
  import { LitElement, html, unsafeCSS } from "lit";
4
4
  import z$2 from "zod";
5
- import { options, createContext as createContext$1, Fragment, render, Component, createRef, createElement, toChildArray, cloneElement, hydrate } from "preact";
5
+ import { createContext as createContext$1, options, Fragment, render, Component, createRef, createElement, toChildArray, cloneElement, hydrate } from "preact";
6
6
  import { Grid } from "gridjs";
7
7
  import { Chart, registerables, Scale, BarController } from "chart.js";
8
8
  import { VennDiagramController, ArcSlice, extractSets } from "chartjs-chart-venn";
@@ -539,6 +539,15 @@ const substitutionsOrDeletionsEndpoint = (lapisUrl, sequenceType) => {
539
539
  return sequenceType === "amino acid" ? `${lapisUrl}/sample/aminoAcidMutations` : `${lapisUrl}/sample/nucleotideMutations`;
540
540
  };
541
541
  const referenceGenomeEndpoint = (lapisUrl) => `${lapisUrl}/sample/referenceGenome`;
542
+ const UNINITIALIZED_SEQUENCE = "__uninitialized__";
543
+ const INITIAL_REFERENCE_GENOMES = {
544
+ nucleotideSequences: [{ name: UNINITIALIZED_SEQUENCE, sequence: "" }],
545
+ genes: []
546
+ };
547
+ const ReferenceGenomeContext = createContext$1(INITIAL_REFERENCE_GENOMES);
548
+ function isNotInitialized(referenceGenome) {
549
+ return referenceGenome.genes.length === 0 && referenceGenome.nucleotideSequences.length === 1 && referenceGenome.nucleotideSequences[0].name === UNINITIALIZED_SEQUENCE;
550
+ }
542
551
  var __defProp$g = Object.defineProperty;
543
552
  var __getOwnPropDesc$f = Object.getOwnPropertyDescriptor;
544
553
  var __decorateClass$g = (decorators, target, key, kind) => {
@@ -554,10 +563,7 @@ let AppComponent = class extends LitElement {
554
563
  constructor() {
555
564
  super(...arguments);
556
565
  this.lapis = "";
557
- this.referenceGenome = {
558
- nucleotideSequences: [],
559
- genes: []
560
- };
566
+ this.referenceGenome = INITIAL_REFERENCE_GENOMES;
561
567
  this.updateReferenceGenome = new Task(this, {
562
568
  task: async () => {
563
569
  const lapisUrl = lapisUrlSchema.parse(this.lapis);
@@ -1375,7 +1381,7 @@ function componentParametersToCode(componentName, params, lapisUrl) {
1375
1381
  return typeof value === "object" ? JSON.stringify(value) : value;
1376
1382
  };
1377
1383
  const attributes = indentLines(
1378
- Object.entries(params).map(([key, value]) => `${key}='${stringifyIfNeeded(value)}'`).join("\n"),
1384
+ Object.entries(params).filter(([_2, value]) => value !== void 0).map(([key, value]) => `${key}='${stringifyIfNeeded(value)}'`).join("\n"),
1379
1385
  4
1380
1386
  );
1381
1387
  return `<gs-app lapis="${lapisUrl}">
@@ -2019,14 +2025,6 @@ const ProportionSelectorDropdown = ({
2019
2025
  }
2020
2026
  ) }) });
2021
2027
  };
2022
- const UNINITIALIZED_SEQUENCE = "__uninitialized__";
2023
- const ReferenceGenomeContext = createContext$1({
2024
- nucleotideSequences: [{ name: UNINITIALIZED_SEQUENCE, sequence: "" }],
2025
- genes: []
2026
- });
2027
- function isNotInitialized(referenceGenome) {
2028
- return referenceGenome.genes.length === 0 && referenceGenome.nucleotideSequences.length === 1 && referenceGenome.nucleotideSequences[0].name === UNINITIALIZED_SEQUENCE;
2029
- }
2030
2028
  const SegmentSelector = ({
2031
2029
  displayedSegments,
2032
2030
  setDisplayedSegments
@@ -5581,10 +5579,7 @@ const _PreactLitAdapter = class _PreactLitAdapter extends ReactiveElement {
5581
5579
  constructor() {
5582
5580
  super(...arguments);
5583
5581
  this.lapis = "";
5584
- this.referenceGenome = {
5585
- nucleotideSequences: [],
5586
- genes: []
5587
- };
5582
+ this.referenceGenome = INITIAL_REFERENCE_GENOMES;
5588
5583
  }
5589
5584
  update(changedProperties) {
5590
5585
  const vdom = /* @__PURE__ */ u$1(LapisUrlContextProvider, { value: this.lapis, children: /* @__PURE__ */ u$1(ReferenceGenomeContext.Provider, { value: this.referenceGenome, children: this.render() }) });
@@ -9510,8 +9505,17 @@ class BaseMutationOverTimeDataMap extends Map2dBase {
9510
9505
  super(serializeSubstitutionOrDeletion, serializeTemporal, initialContent);
9511
9506
  }
9512
9507
  }
9513
- function getFilteredMutationOverTimeData(data, overallMutationData, displayedSegments, displayedMutationTypes, proportionInterval) {
9508
+ const displayMutationsSchema = z$2.array(z$2.string()).min(1);
9509
+ function getFilteredMutationOverTimeData({
9510
+ data,
9511
+ overallMutationData,
9512
+ displayedSegments,
9513
+ displayedMutationTypes,
9514
+ proportionInterval,
9515
+ displayMutations
9516
+ }) {
9514
9517
  const filteredData = new Map2dView(data);
9518
+ const displayMutationsSet = displayMutations === void 0 ? null : new Set(displayMutations.map((it) => it.toUpperCase()));
9515
9519
  const mutationsToFilterOut = overallMutationData.filter((entry) => {
9516
9520
  if (entry.proportion < proportionInterval.min || entry.proportion > proportionInterval.max) {
9517
9521
  return true;
@@ -9519,6 +9523,9 @@ function getFilteredMutationOverTimeData(data, overallMutationData, displayedSeg
9519
9523
  if (displayedSegments.some((segment) => segment.segment === entry.mutation.segment && !segment.checked)) {
9520
9524
  return true;
9521
9525
  }
9526
+ if (displayMutationsSet !== null && !displayMutationsSet.has(entry.mutation.code)) {
9527
+ return true;
9528
+ }
9522
9529
  return displayedMutationTypes.some(
9523
9530
  (mutationType) => mutationType.type === entry.mutation.type && !mutationType.checked
9524
9531
  );
@@ -9641,8 +9648,7 @@ const MutationsOverTimeGrid = ({
9641
9648
  allMutations.length,
9642
9649
  " mutations. You can narrow the filter to reduce the number of mutations."
9643
9650
  ] }),
9644
- allMutations.length === 0 && /* @__PURE__ */ u$1("div", { className: "flex justify-center", children: "No data available for your filters." }),
9645
- /* @__PURE__ */ u$1(
9651
+ allMutations.length === 0 ? /* @__PURE__ */ u$1("div", { className: "flex justify-center", children: "No data available for your filters." }) : /* @__PURE__ */ u$1(
9646
9652
  "div",
9647
9653
  {
9648
9654
  ref: gridRef,
@@ -9816,6 +9822,11 @@ const mutationOverTimeSchema = z$2.object({
9816
9822
  views: z$2.array(mutationsOverTimeViewSchema),
9817
9823
  granularity: temporalGranularitySchema,
9818
9824
  lapisDateField: z$2.string().min(1),
9825
+ displayMutations: displayMutationsSchema.optional(),
9826
+ initialMeanProportionInterval: z$2.object({
9827
+ min: z$2.number().min(0).max(1),
9828
+ max: z$2.number().min(0).max(1)
9829
+ }),
9819
9830
  width: z$2.string(),
9820
9831
  height: z$2.string().optional()
9821
9832
  });
@@ -9866,22 +9877,31 @@ const MutationsOverTimeTabs$1 = ({
9866
9877
  originalComponentProps,
9867
9878
  overallMutationData
9868
9879
  }) => {
9869
- const [proportionInterval, setProportionInterval] = h({ min: 0.05, max: 0.9 });
9880
+ const [proportionInterval, setProportionInterval] = h(originalComponentProps.initialMeanProportionInterval);
9870
9881
  const [colorScale, setColorScale] = h({ min: 0, max: 1, color: "indigo" });
9871
9882
  const [displayedSegments, setDisplayedSegments] = useDisplayedSegments(originalComponentProps.sequenceType);
9872
9883
  const [displayedMutationTypes, setDisplayedMutationTypes] = h([
9873
9884
  { label: "Substitutions", checked: true, type: "substitution" },
9874
9885
  { label: "Deletions", checked: true, type: "deletion" }
9875
9886
  ]);
9887
+ const displayMutations = originalComponentProps.displayMutations;
9876
9888
  const filteredData = T$1(() => {
9877
- return getFilteredMutationOverTimeData(
9878
- mutationOverTimeData,
9889
+ return getFilteredMutationOverTimeData({
9890
+ data: mutationOverTimeData,
9879
9891
  overallMutationData,
9880
9892
  displayedSegments,
9881
9893
  displayedMutationTypes,
9882
- proportionInterval
9883
- );
9884
- }, [mutationOverTimeData, overallMutationData, displayedSegments, displayedMutationTypes, proportionInterval]);
9894
+ proportionInterval,
9895
+ displayMutations
9896
+ });
9897
+ }, [
9898
+ mutationOverTimeData,
9899
+ overallMutationData,
9900
+ displayedSegments,
9901
+ displayedMutationTypes,
9902
+ proportionInterval,
9903
+ displayMutations
9904
+ ]);
9885
9905
  const getTab = (view) => {
9886
9906
  if (filteredData === void 0) {
9887
9907
  return {
@@ -10011,6 +10031,8 @@ let MutationsOverTimeComponent = class extends PreactLitAdapterWithGridJsStyles
10011
10031
  this.height = void 0;
10012
10032
  this.granularity = "week";
10013
10033
  this.lapisDateField = "date";
10034
+ this.displayMutations = void 0;
10035
+ this.initialMeanProportionInterval = { min: 0.05, max: 0.9 };
10014
10036
  }
10015
10037
  render() {
10016
10038
  return /* @__PURE__ */ u$1(
@@ -10022,7 +10044,9 @@ let MutationsOverTimeComponent = class extends PreactLitAdapterWithGridJsStyles
10022
10044
  width: this.width,
10023
10045
  height: this.height,
10024
10046
  granularity: this.granularity,
10025
- lapisDateField: this.lapisDateField
10047
+ lapisDateField: this.lapisDateField,
10048
+ displayMutations: this.displayMutations,
10049
+ initialMeanProportionInterval: this.initialMeanProportionInterval
10026
10050
  }
10027
10051
  );
10028
10052
  }
@@ -10048,6 +10072,12 @@ __decorateClass$8([
10048
10072
  __decorateClass$8([
10049
10073
  n$1({ type: String })
10050
10074
  ], MutationsOverTimeComponent.prototype, "lapisDateField", 2);
10075
+ __decorateClass$8([
10076
+ n$1({ type: Array })
10077
+ ], MutationsOverTimeComponent.prototype, "displayMutations", 2);
10078
+ __decorateClass$8([
10079
+ n$1({ type: Object })
10080
+ ], MutationsOverTimeComponent.prototype, "initialMeanProportionInterval", 2);
10051
10081
  MutationsOverTimeComponent = __decorateClass$8([
10052
10082
  t$3("gs-mutations-over-time")
10053
10083
  ], MutationsOverTimeComponent);