@genspectrum/dashboard-components 0.6.6 → 0.6.8

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.
Files changed (28) hide show
  1. package/custom-elements.json +16 -0
  2. package/dist/dashboard-components.js +226 -145
  3. package/dist/dashboard-components.js.map +1 -1
  4. package/dist/style.css +42 -6
  5. package/package.json +1 -1
  6. package/src/preact/aggregatedData/aggregate.tsx +1 -1
  7. package/src/preact/components/color-scale-selector-dropdown.stories.tsx +27 -0
  8. package/src/preact/components/color-scale-selector-dropdown.tsx +17 -0
  9. package/src/preact/components/color-scale-selector.stories.tsx +61 -0
  10. package/src/preact/components/color-scale-selector.tsx +79 -0
  11. package/src/preact/components/info.stories.tsx +37 -10
  12. package/src/preact/components/info.tsx +22 -43
  13. package/src/preact/components/min-max-range-slider.tsx +1 -1
  14. package/src/preact/components/tooltip.tsx +2 -2
  15. package/src/preact/mutationComparison/mutation-comparison.tsx +1 -1
  16. package/src/preact/mutationFilter/mutation-filter-info.tsx +1 -1
  17. package/src/preact/mutationFilter/mutation-filter.stories.tsx +1 -1
  18. package/src/preact/mutationFilter/mutation-filter.tsx +2 -3
  19. package/src/preact/mutations/mutations.tsx +1 -1
  20. package/src/preact/mutationsOverTime/mutations-over-time-grid.tsx +61 -35
  21. package/src/preact/mutationsOverTime/mutations-over-time.tsx +34 -15
  22. package/src/preact/numberSequencesOverTime/number-sequences-over-time.tsx +1 -1
  23. package/src/preact/prevalenceOverTime/prevalence-over-time.tsx +1 -1
  24. package/src/preact/shared/charts/colors.ts +1 -1
  25. package/src/preact/shared/sort/sortSubstitutionsAndDeletions.spec.ts +1 -1
  26. package/src/preact/shared/sort/sortSubstitutionsAndDeletions.ts +1 -1
  27. package/src/web-components/visualization/gs-mutations-over-time.stories.ts +8 -0
  28. package/src/preact/shared/icons/DeleteIcon.tsx +0 -17
@@ -6,7 +6,7 @@ import { options, createContext as createContext$1, Fragment, render } from "pre
6
6
  import { Grid } from "gridjs";
7
7
  import { Chart, registerables, Scale } from "chart.js";
8
8
  import { VennDiagramController, ArcSlice, extractSets } from "chartjs-chart-venn";
9
- import { autoUpdate, computePosition, offset, shift, flip, size } from "@floating-ui/dom";
9
+ import { autoUpdate, computePosition, offset, shift, flip } from "@floating-ui/dom";
10
10
  import { ReactiveElement } from "@lit/reactive-element";
11
11
  import { BarWithErrorBarsController, BarWithErrorBar } from "chartjs-chart-error-bars";
12
12
  import hash from "object-hash";
@@ -884,7 +884,7 @@ const bases = {
884
884
  };
885
885
  const sortSubstitutionsAndDeletions = (a2, b3) => {
886
886
  if (a2.segment !== b3.segment) {
887
- compareSegments(a2.segment, b3.segment);
887
+ return compareSegments(a2.segment, b3.segment);
888
888
  }
889
889
  if (a2.position !== b3.position) {
890
890
  return comparePositions(a2.position, b3.position);
@@ -1361,58 +1361,32 @@ const ErrorDisplay = ({ error }) => {
1361
1361
  ] })
1362
1362
  ] });
1363
1363
  };
1364
- const ResizeContainer = ({ children, size: size2 }) => {
1365
- return /* @__PURE__ */ u$1("div", { style: size2, children });
1364
+ const ResizeContainer = ({ children, size }) => {
1365
+ return /* @__PURE__ */ u$1("div", { style: size, children });
1366
1366
  };
1367
- const ErrorBoundary = ({ size: size2, children }) => {
1367
+ const ErrorBoundary = ({ size, children }) => {
1368
1368
  const [internalError] = b2();
1369
1369
  if (internalError) {
1370
- return /* @__PURE__ */ u$1(ResizeContainer, { size: size2, children: /* @__PURE__ */ u$1(ErrorDisplay, { error: internalError }) });
1370
+ return /* @__PURE__ */ u$1(ResizeContainer, { size, children: /* @__PURE__ */ u$1(ErrorDisplay, { error: internalError }) });
1371
1371
  }
1372
1372
  return /* @__PURE__ */ u$1(Fragment, { children });
1373
1373
  };
1374
- const Info = ({ children, height }) => {
1375
- const [showHelp, setShowHelp] = h(false);
1376
- const referenceRef = A(null);
1377
- const floatingRef = A(null);
1378
- useFloatingUi(referenceRef, floatingRef, [
1379
- offset(10),
1380
- shift(),
1381
- size({
1382
- apply() {
1383
- if (!floatingRef.current) {
1384
- return;
1385
- }
1386
- floatingRef.current.style.width = "100vw";
1387
- floatingRef.current.style.height = height ? height : "50vh";
1388
- }
1389
- })
1390
- ]);
1374
+ const Info = ({ children }) => {
1375
+ const dialogRef = A(null);
1391
1376
  const toggleHelp = () => {
1392
- setShowHelp(!showHelp);
1377
+ var _a;
1378
+ (_a = dialogRef.current) == null ? void 0 : _a.showModal();
1393
1379
  };
1394
- useCloseOnEsc(setShowHelp);
1395
- useCloseOnClickOutside(floatingRef, referenceRef, setShowHelp);
1396
1380
  return /* @__PURE__ */ u$1("div", { className: "relative", children: [
1397
- /* @__PURE__ */ u$1("button", { type: "button", className: "btn btn-xs", onClick: toggleHelp, ref: referenceRef, children: "?" }),
1398
- /* @__PURE__ */ u$1(
1399
- "div",
1400
- {
1401
- ref: floatingRef,
1402
- className: `${dropdownClass} overflow-y-auto opacity-90 ${showHelp ? "" : "hidden"}`,
1403
- children: [
1404
- /* @__PURE__ */ u$1("div", { className: "flex flex-col", children }),
1405
- /* @__PURE__ */ u$1(
1406
- "button",
1407
- {
1408
- onClick: () => setShowHelp(false),
1409
- className: "float-right underline text-sm hover:text-blue-700 mr-2",
1410
- children: "Close"
1411
- }
1412
- )
1413
- ]
1414
- }
1415
- )
1381
+ /* @__PURE__ */ u$1("button", { type: "button", className: "btn btn-xs", onClick: toggleHelp, children: "?" }),
1382
+ /* @__PURE__ */ u$1("dialog", { ref: dialogRef, className: "modal modal-bottom sm:modal-middle", children: [
1383
+ /* @__PURE__ */ u$1("div", { className: "modal-box", children: [
1384
+ /* @__PURE__ */ u$1("form", { method: "dialog", children: /* @__PURE__ */ u$1("button", { className: "btn btn-sm btn-circle btn-ghost absolute right-2 top-2", children: "✕" }) }),
1385
+ /* @__PURE__ */ u$1("div", { className: "flex flex-col", children }),
1386
+ /* @__PURE__ */ u$1("div", { className: "modal-action", children: /* @__PURE__ */ u$1("form", { method: "dialog", children: /* @__PURE__ */ u$1("button", { className: "float-right underline text-sm hover:text-blue-700 mr-2", children: "Close" }) }) })
1387
+ ] }),
1388
+ /* @__PURE__ */ u$1("form", { method: "dialog", className: "modal-backdrop", children: /* @__PURE__ */ u$1("button", { children: "Helper to close when clicked outside" }) })
1389
+ ] })
1416
1390
  ] });
1417
1391
  };
1418
1392
  const InfoHeadline1 = ({ children }) => {
@@ -1495,7 +1469,7 @@ const MinMaxRangeSlider = ({
1495
1469
  ${sliderColor} ${max}%,
1496
1470
  ${sliderColor} 100%)
1497
1471
  `;
1498
- return /* @__PURE__ */ u$1("div", { class: "my-4 relative", children: [
1472
+ return /* @__PURE__ */ u$1("div", { class: "my-4 relative w-full h-full", children: [
1499
1473
  /* @__PURE__ */ u$1(
1500
1474
  "input",
1501
1475
  {
@@ -1676,8 +1650,8 @@ function useQuery(fetchDataCallback, dependencies = []) {
1676
1650
  return { data, error, isLoading };
1677
1651
  }
1678
1652
  const MutationComparison = ({ width, height, ...innerProps }) => {
1679
- const size2 = { height, width };
1680
- return /* @__PURE__ */ u$1(ErrorBoundary, { size: size2, children: /* @__PURE__ */ u$1(ResizeContainer, { size: size2, children: /* @__PURE__ */ u$1(MutationComparisonInner, { ...innerProps }) }) });
1653
+ const size = { height, width };
1654
+ return /* @__PURE__ */ u$1(ErrorBoundary, { size, children: /* @__PURE__ */ u$1(ResizeContainer, { size, children: /* @__PURE__ */ u$1(MutationComparisonInner, { ...innerProps }) }) });
1681
1655
  };
1682
1656
  const MutationComparisonInner = ({
1683
1657
  lapisFilters,
@@ -1805,7 +1779,7 @@ const Toolbar$5 = ({
1805
1779
  filename: "mutation_comparison.csv"
1806
1780
  }
1807
1781
  ),
1808
- /* @__PURE__ */ u$1(Info, { height: "100px", children: "Info for mutation comparison" })
1782
+ /* @__PURE__ */ u$1(Info, { children: "Info for mutation comparison" })
1809
1783
  ] });
1810
1784
  };
1811
1785
  const gridJsStyle = '.gridjs-head button, .gridjs-footer button {\n cursor: pointer;\n background-color: transparent;\n background-image: none;\n padding: 0;\n margin: 0;\n border: none;\n outline: none;\n}\n\n.gridjs-temp {\n position: relative;\n}\n\n.gridjs-head {\n width: 100%;\n margin-bottom: 5px;\n padding: 5px 1px;\n}\n.gridjs-head::after {\n content: "";\n display: block;\n clear: both;\n}\n.gridjs-head:empty {\n padding: 0;\n border: none;\n}\n\n.gridjs-container {\n overflow: hidden;\n display: inline-block;\n padding: 2px;\n color: #000;\n position: relative;\n z-index: 0;\n}\n\n.gridjs-footer {\n display: block;\n position: relative;\n width: 100%;\n z-index: 5;\n padding: 12px 24px;\n border-top: 1px solid #e5e7eb;\n background-color: #fff;\n box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.26);\n border-radius: 0 0 8px 8px;\n border-bottom-width: 1px;\n border-color: #e5e7eb;\n}\n.gridjs-footer:empty {\n padding: 0;\n border: none;\n}\n\ninput.gridjs-input {\n outline: none;\n background-color: #fff;\n border: 1px solid #d2d6dc;\n border-radius: 5px;\n padding: 10px 13px;\n font-size: 14px;\n line-height: 1.45;\n -webkit-appearance: none;\n -moz-appearance: none;\n appearance: none;\n}\ninput.gridjs-input:focus {\n box-shadow: 0 0 0 3px rgba(149, 189, 243, 0.5);\n border-color: #9bc2f7;\n}\n\n.gridjs-pagination {\n color: #3d4044;\n}\n.gridjs-pagination::after {\n content: "";\n display: block;\n clear: both;\n}\n.gridjs-pagination .gridjs-summary {\n float: left;\n margin-top: 5px;\n}\n.gridjs-pagination .gridjs-pages {\n float: right;\n}\n.gridjs-pagination .gridjs-pages button {\n padding: 5px 14px;\n border: 1px solid #d2d6dc;\n background-color: #fff;\n border-right: none;\n outline: none;\n -webkit-user-select: none;\n -moz-user-select: none;\n user-select: none;\n}\n.gridjs-pagination .gridjs-pages button:focus {\n box-shadow: 0 0 0 2px rgba(149, 189, 243, 0.5);\n position: relative;\n margin-right: -1px;\n border-right: 1px solid #d2d6dc;\n}\n.gridjs-pagination .gridjs-pages button:hover {\n background-color: #f7f7f7;\n color: rgb(60, 66, 87);\n outline: none;\n}\n.gridjs-pagination .gridjs-pages button:disabled,\n.gridjs-pagination .gridjs-pages button[disabled],\n.gridjs-pagination .gridjs-pages button:hover:disabled {\n cursor: default;\n background-color: #fff;\n color: #6b7280;\n}\n.gridjs-pagination .gridjs-pages button.gridjs-spread {\n cursor: default;\n box-shadow: none;\n background-color: #fff;\n}\n.gridjs-pagination .gridjs-pages button.gridjs-currentPage {\n background-color: #f7f7f7;\n font-weight: bold;\n}\n.gridjs-pagination .gridjs-pages button:last-child {\n border-bottom-right-radius: 6px;\n border-top-right-radius: 6px;\n border-right: 1px solid #d2d6dc;\n}\n.gridjs-pagination .gridjs-pages button:first-child {\n border-bottom-left-radius: 6px;\n border-top-left-radius: 6px;\n}\n.gridjs-pagination .gridjs-pages button:last-child:focus {\n margin-right: 0;\n}\n\nbutton.gridjs-sort {\n float: right;\n height: 24px;\n width: 13px;\n background-color: transparent;\n background-repeat: no-repeat;\n background-position-x: center;\n cursor: pointer;\n padding: 0;\n margin: 0;\n border: none;\n outline: none;\n background-size: contain;\n}\nbutton.gridjs-sort-neutral {\n opacity: 0.3;\n background-image: url("data:image/svg+xml;base64,PHN2ZyB2ZXJzaW9uPSIxLjEiIGlkPSJDYXBhXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IgoJIHdpZHRoPSI0MDEuOTk4cHgiIGhlaWdodD0iNDAxLjk5OHB4IiB2aWV3Qm94PSIwIDAgNDAxLjk5OCA0MDEuOTk4IiBzdHlsZT0iZW5hYmxlLWJhY2tncm91bmQ6bmV3IDAgMCA0MDEuOTk4IDQwMS45OTg7IgoJIHhtbDpzcGFjZT0icHJlc2VydmUiPgo8Zz4KCTxnPgoJCTxwYXRoIGQ9Ik03My4wOTIsMTY0LjQ1MmgyNTUuODEzYzQuOTQ5LDAsOS4yMzMtMS44MDcsMTIuODQ4LTUuNDI0YzMuNjEzLTMuNjE2LDUuNDI3LTcuODk4LDUuNDI3LTEyLjg0NwoJCQljMC00Ljk0OS0xLjgxMy05LjIyOS01LjQyNy0xMi44NUwyMTMuODQ2LDUuNDI0QzIxMC4yMzIsMS44MTIsMjA1Ljk1MSwwLDIwMC45OTksMHMtOS4yMzMsMS44MTItMTIuODUsNS40MjRMNjAuMjQyLDEzMy4zMzEKCQkJYy0zLjYxNywzLjYxNy01LjQyNCw3LjkwMS01LjQyNCwxMi44NWMwLDQuOTQ4LDEuODA3LDkuMjMxLDUuNDI0LDEyLjg0N0M2My44NjMsMTYyLjY0NSw2OC4xNDQsMTY0LjQ1Miw3My4wOTIsMTY0LjQ1MnoiLz4KCQk8cGF0aCBkPSJNMzI4LjkwNSwyMzcuNTQ5SDczLjA5MmMtNC45NTIsMC05LjIzMywxLjgwOC0xMi44NSw1LjQyMWMtMy42MTcsMy42MTctNS40MjQsNy44OTgtNS40MjQsMTIuODQ3CgkJCWMwLDQuOTQ5LDEuODA3LDkuMjMzLDUuNDI0LDEyLjg0OEwxODguMTQ5LDM5Ni41N2MzLjYyMSwzLjYxNyw3LjkwMiw1LjQyOCwxMi44NSw1LjQyOHM5LjIzMy0xLjgxMSwxMi44NDctNS40MjhsMTI3LjkwNy0xMjcuOTA2CgkJCWMzLjYxMy0zLjYxNCw1LjQyNy03Ljg5OCw1LjQyNy0xMi44NDhjMC00Ljk0OC0xLjgxMy05LjIyOS01LjQyNy0xMi44NDdDMzM4LjEzOSwyMzkuMzUzLDMzMy44NTQsMjM3LjU0OSwzMjguOTA1LDIzNy41NDl6Ii8+Cgk8L2c+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPC9zdmc+");\n background-position-y: center;\n}\nbutton.gridjs-sort-asc {\n background-image: url("data:image/svg+xml;base64,PHN2ZyB2ZXJzaW9uPSIxLjEiIGlkPSJDYXBhXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IgoJIHdpZHRoPSIyOTIuMzYycHgiIGhlaWdodD0iMjkyLjM2MXB4IiB2aWV3Qm94PSIwIDAgMjkyLjM2MiAyOTIuMzYxIiBzdHlsZT0iZW5hYmxlLWJhY2tncm91bmQ6bmV3IDAgMCAyOTIuMzYyIDI5Mi4zNjE7IgoJIHhtbDpzcGFjZT0icHJlc2VydmUiPgo8Zz4KCTxwYXRoIGQ9Ik0yODYuOTM1LDE5Ny4yODdMMTU5LjAyOCw2OS4zODFjLTMuNjEzLTMuNjE3LTcuODk1LTUuNDI0LTEyLjg0Ny01LjQyNHMtOS4yMzMsMS44MDctMTIuODUsNS40MjRMNS40MjQsMTk3LjI4NwoJCUMxLjgwNywyMDAuOTA0LDAsMjA1LjE4NiwwLDIxMC4xMzRzMS44MDcsOS4yMzMsNS40MjQsMTIuODQ3YzMuNjIxLDMuNjE3LDcuOTAyLDUuNDI1LDEyLjg1LDUuNDI1aDI1NS44MTMKCQljNC45NDksMCw5LjIzMy0xLjgwOCwxMi44NDgtNS40MjVjMy42MTMtMy42MTMsNS40MjctNy44OTgsNS40MjctMTIuODQ3UzI5MC41NDgsMjAwLjkwNCwyODYuOTM1LDE5Ny4yODd6Ii8+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPC9zdmc+");\n background-position-y: 35%;\n background-size: 10px;\n}\nbutton.gridjs-sort-desc {\n background-image: url("data:image/svg+xml;base64,PHN2ZyB2ZXJzaW9uPSIxLjEiIGlkPSJDYXBhXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IgoJIHdpZHRoPSIyOTIuMzYycHgiIGhlaWdodD0iMjkyLjM2MnB4IiB2aWV3Qm94PSIwIDAgMjkyLjM2MiAyOTIuMzYyIiBzdHlsZT0iZW5hYmxlLWJhY2tncm91bmQ6bmV3IDAgMCAyOTIuMzYyIDI5Mi4zNjI7IgoJIHhtbDpzcGFjZT0icHJlc2VydmUiPgo8Zz4KCTxwYXRoIGQ9Ik0yODYuOTM1LDY5LjM3N2MtMy42MTQtMy42MTctNy44OTgtNS40MjQtMTIuODQ4LTUuNDI0SDE4LjI3NGMtNC45NTIsMC05LjIzMywxLjgwNy0xMi44NSw1LjQyNAoJCUMxLjgwNyw3Mi45OTgsMCw3Ny4yNzksMCw4Mi4yMjhjMCw0Ljk0OCwxLjgwNyw5LjIyOSw1LjQyNCwxMi44NDdsMTI3LjkwNywxMjcuOTA3YzMuNjIxLDMuNjE3LDcuOTAyLDUuNDI4LDEyLjg1LDUuNDI4CgkJczkuMjMzLTEuODExLDEyLjg0Ny01LjQyOEwyODYuOTM1LDk1LjA3NGMzLjYxMy0zLjYxNyw1LjQyNy03Ljg5OCw1LjQyNy0xMi44NDdDMjkyLjM2Miw3Ny4yNzksMjkwLjU0OCw3Mi45OTgsMjg2LjkzNSw2OS4zNzd6Ii8+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPC9zdmc+");\n background-position-y: 65%;\n background-size: 10px;\n}\nbutton.gridjs-sort:focus {\n outline: none;\n}\n\ntable.gridjs-table {\n width: 100%;\n max-width: 100%;\n border-collapse: collapse;\n text-align: left;\n display: table;\n margin: 0;\n padding: 0;\n overflow: auto;\n table-layout: fixed;\n}\n\n.gridjs-tbody {\n background-color: #fff;\n}\n\ntd.gridjs-td {\n border: 1px solid #e5e7eb;\n padding: 12px 24px;\n background-color: #fff;\n box-sizing: content-box;\n}\ntd.gridjs-td:first-child {\n border-left: none;\n}\ntd.gridjs-td:last-child {\n border-right: none;\n}\ntd.gridjs-message {\n text-align: center;\n}\n\nth.gridjs-th {\n position: relative;\n color: #6b7280;\n background-color: #f9fafb;\n border: 1px solid #e5e7eb;\n border-top: none;\n padding: 14px 24px;\n -webkit-user-select: none;\n -moz-user-select: none;\n user-select: none;\n box-sizing: border-box;\n white-space: nowrap;\n outline: none;\n vertical-align: middle;\n}\nth.gridjs-th .gridjs-th-content {\n text-overflow: ellipsis;\n overflow: hidden;\n width: 100%;\n float: left;\n}\nth.gridjs-th-sort {\n cursor: pointer;\n}\nth.gridjs-th-sort .gridjs-th-content {\n width: calc(100% - 15px);\n}\nth.gridjs-th-sort:hover {\n background-color: #e5e7eb;\n}\nth.gridjs-th-sort:focus {\n background-color: #e5e7eb;\n}\nth.gridjs-th-fixed {\n position: sticky;\n box-shadow: 0 1px 0 0 #e5e7eb;\n}\n@supports (-moz-appearance: none) {\n th.gridjs-th-fixed {\n box-shadow: 0 0 0 1px #e5e7eb;\n }\n}\nth.gridjs-th:first-child {\n border-left: none;\n}\nth.gridjs-th:last-child {\n border-right: none;\n}\n\n.gridjs-tr {\n border: none;\n}\n.gridjs-tr-selected td {\n background-color: #ebf5ff;\n}\n.gridjs-tr:last-child td {\n border-bottom: 0;\n}\n\n.gridjs *,\n.gridjs :after,\n.gridjs :before {\n box-sizing: border-box;\n}\n\n.gridjs-wrapper {\n position: relative;\n z-index: 1;\n overflow: auto;\n width: 100%;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.26);\n border-radius: 8px 8px 0 0;\n display: block;\n border-top-width: 1px;\n border-color: #e5e7eb;\n}\n.gridjs-wrapper:nth-last-of-type(2) {\n border-radius: 8px;\n border-bottom-width: 1px;\n}\n\n.gridjs-search {\n float: left;\n}\n.gridjs-search-input {\n width: 250px;\n}\n\n.gridjs-loading-bar {\n z-index: 10;\n position: absolute;\n left: 0;\n right: 0;\n top: 0;\n bottom: 0;\n background-color: #fff;\n opacity: 0.5;\n}\n.gridjs-loading-bar::after {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n transform: translateX(-100%);\n background-image: linear-gradient(90deg, rgba(204, 204, 204, 0) 0, rgba(204, 204, 204, 0.2) 20%, rgba(204, 204, 204, 0.5) 60%, rgba(204, 204, 204, 0));\n animation: shimmer 2s infinite;\n content: "";\n}\n@keyframes shimmer {\n 100% {\n transform: translateX(100%);\n }\n}\n\n.gridjs-td .gridjs-checkbox {\n display: block;\n margin: auto;\n cursor: pointer;\n}\n\n.gridjs-resizable {\n position: absolute;\n top: 0;\n bottom: 0;\n right: 0;\n width: 5px;\n}\n.gridjs-resizable:hover {\n cursor: ew-resize;\n background-color: #9bc2f7;\n}\n/*# sourceMappingURL=mermaid.css?inline.map */';
@@ -2863,6 +2837,11 @@ html {
2863
2837
  visibility: visible;
2864
2838
  opacity: 1;
2865
2839
  }
2840
+ .modal-action {
2841
+ display: flex;
2842
+ margin-top: 1.5rem;
2843
+ justify-content: flex-end;
2844
+ }
2866
2845
  :root:has(:is(.modal-open, .modal:target, .modal-toggle:checked + .modal, .modal[open])) {
2867
2846
  overflow: hidden;
2868
2847
  scrollbar-gutter: stable;
@@ -3389,6 +3368,11 @@ input.tab:checked + .tab-content,
3389
3368
  --tw-scale-y: 1;
3390
3369
  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
3391
3370
  }
3371
+ .modal-action > :not([hidden]) ~ :not([hidden]) {
3372
+ --tw-space-x-reverse: 0;
3373
+ margin-right: calc(0.5rem * var(--tw-space-x-reverse));
3374
+ margin-left: calc(0.5rem * calc(1 - var(--tw-space-x-reverse)));
3375
+ }
3392
3376
  @keyframes modal-pop {
3393
3377
 
3394
3378
  0% {
@@ -3963,6 +3947,9 @@ input.tab:checked + .tab-content,
3963
3947
  border-end-end-radius: inherit;
3964
3948
  border-start-end-radius: inherit;
3965
3949
  }
3950
+ .modal-bottom {
3951
+ place-items: end;
3952
+ }
3966
3953
  .select-xs {
3967
3954
  height: 1.5rem;
3968
3955
  min-height: 1.5rem;
@@ -4269,6 +4256,10 @@ input.tab:checked + .tab-content,
4269
4256
  margin-left: 0.25rem;
4270
4257
  margin-right: 0.25rem;
4271
4258
  }
4259
+ .mx-2 {
4260
+ margin-left: 0.5rem;
4261
+ margin-right: 0.5rem;
4262
+ }
4272
4263
  .mx-auto {
4273
4264
  margin-left: auto;
4274
4265
  margin-right: auto;
@@ -4326,9 +4317,15 @@ input.tab:checked + .tab-content,
4326
4317
  .hidden {
4327
4318
  display: none;
4328
4319
  }
4320
+ .h-8 {
4321
+ height: 2rem;
4322
+ }
4329
4323
  .h-full {
4330
4324
  height: 100%;
4331
4325
  }
4326
+ .w-10 {
4327
+ width: 2.5rem;
4328
+ }
4332
4329
  .w-16 {
4333
4330
  width: 4rem;
4334
4331
  }
@@ -4404,9 +4401,6 @@ input.tab:checked + .tab-content,
4404
4401
  .overflow-auto {
4405
4402
  overflow: auto;
4406
4403
  }
4407
- .overflow-y-auto {
4408
- overflow-y: auto;
4409
- }
4410
4404
  .whitespace-nowrap {
4411
4405
  white-space: nowrap;
4412
4406
  }
@@ -4573,9 +4567,6 @@ input.tab:checked + .tab-content,
4573
4567
  .underline {
4574
4568
  text-decoration-line: underline;
4575
4569
  }
4576
- .opacity-90 {
4577
- opacity: 0.9;
4578
- }
4579
4570
  .shadow {
4580
4571
  --tw-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);
4581
4572
  --tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color);
@@ -4601,6 +4592,25 @@ input.tab:checked + .tab-content,
4601
4592
  .duration-150 {
4602
4593
  transition-duration: 150ms;
4603
4594
  }
4595
+ @media (min-width: 640px) {
4596
+
4597
+ .sm\\:modal-middle {
4598
+ place-items: center;
4599
+ }
4600
+
4601
+ .sm\\:modal-middle :where(.modal-box) {
4602
+ width: 91.666667%;
4603
+ max-width: 32rem;
4604
+ --tw-translate-y: 0px;
4605
+ --tw-scale-x: .9;
4606
+ --tw-scale-y: .9;
4607
+ transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
4608
+ border-top-left-radius: var(--rounded-box, 1rem);
4609
+ border-top-right-radius: var(--rounded-box, 1rem);
4610
+ border-bottom-right-radius: var(--rounded-box, 1rem);
4611
+ border-bottom-left-radius: var(--rounded-box, 1rem);
4612
+ }
4613
+ }
4604
4614
  .focus-within\\:border-gray-400:focus-within {
4605
4615
  --tw-border-opacity: 1;
4606
4616
  border-color: rgb(156 163 175 / var(--tw-border-opacity));
@@ -4998,8 +5008,8 @@ function filterMutationsData(data, displayedSegments, displayedMutationTypes) {
4998
5008
  };
4999
5009
  }
5000
5010
  const Mutations = ({ width, height, ...innerProps }) => {
5001
- const size2 = { height, width };
5002
- return /* @__PURE__ */ u$1(ErrorBoundary, { size: size2, children: /* @__PURE__ */ u$1(ResizeContainer, { size: size2, children: /* @__PURE__ */ u$1(MutationsInner, { ...innerProps }) }) });
5011
+ const size = { height, width };
5012
+ return /* @__PURE__ */ u$1(ErrorBoundary, { size, children: /* @__PURE__ */ u$1(ResizeContainer, { size, children: /* @__PURE__ */ u$1(MutationsInner, { ...innerProps }) }) });
5003
5013
  };
5004
5014
  const MutationsInner = ({
5005
5015
  lapisFilter,
@@ -5130,7 +5140,7 @@ const Toolbar$4 = ({
5130
5140
  filename: "insertions.csv"
5131
5141
  }
5132
5142
  ),
5133
- /* @__PURE__ */ u$1(Info, { height: "100px", children: "Info for mutations" })
5143
+ /* @__PURE__ */ u$1(Info, { children: "Info for mutations" })
5134
5144
  ] });
5135
5145
  };
5136
5146
  var __defProp$a = Object.defineProperty;
@@ -6815,8 +6825,8 @@ const ScalingSelector = ({
6815
6825
  );
6816
6826
  };
6817
6827
  const PrevalenceOverTime = ({ width, height, ...innerProps }) => {
6818
- const size2 = { height, width };
6819
- return /* @__PURE__ */ u$1(ErrorBoundary, { size: size2, children: /* @__PURE__ */ u$1(ResizeContainer, { size: size2, children: /* @__PURE__ */ u$1(PrevalenceOverTimeInner, { ...innerProps }) }) });
6828
+ const size = { height, width };
6829
+ return /* @__PURE__ */ u$1(ErrorBoundary, { size, children: /* @__PURE__ */ u$1(ResizeContainer, { size, children: /* @__PURE__ */ u$1(PrevalenceOverTimeInner, { ...innerProps }) }) });
6820
6830
  };
6821
6831
  const PrevalenceOverTimeInner = ({
6822
6832
  numeratorFilter,
@@ -6969,7 +6979,7 @@ const Toolbar$3 = ({
6969
6979
  ] });
6970
6980
  };
6971
6981
  const PrevalenceOverTimeInfo = () => {
6972
- return /* @__PURE__ */ u$1(Info, { height: "100px", children: [
6982
+ return /* @__PURE__ */ u$1(Info, { children: [
6973
6983
  /* @__PURE__ */ u$1(InfoHeadline1, { children: "Prevalence over time" }),
6974
6984
  /* @__PURE__ */ u$1(InfoParagraph, { children: "Prevalence over time info." })
6975
6985
  ] });
@@ -7275,8 +7285,8 @@ const RelativeGrowthAdvantage = ({
7275
7285
  height,
7276
7286
  ...innerProps
7277
7287
  }) => {
7278
- const size2 = { height, width };
7279
- return /* @__PURE__ */ u$1(ErrorBoundary, { size: size2, children: /* @__PURE__ */ u$1(ResizeContainer, { size: size2, children: /* @__PURE__ */ u$1(RelativeGrowthAdvantageInner, { ...innerProps }) }) });
7288
+ const size = { height, width };
7289
+ return /* @__PURE__ */ u$1(ErrorBoundary, { size, children: /* @__PURE__ */ u$1(ResizeContainer, { size, children: /* @__PURE__ */ u$1(RelativeGrowthAdvantageInner, { ...innerProps }) }) });
7280
7290
  };
7281
7291
  const RelativeGrowthAdvantageInner = ({
7282
7292
  numeratorFilter,
@@ -7504,8 +7514,8 @@ const AggregateTable = ({ data, fields, pageSize }) => {
7504
7514
  return /* @__PURE__ */ u$1(Table, { data, columns: headers, pageSize });
7505
7515
  };
7506
7516
  const Aggregate = ({ width, height, ...innerProps }) => {
7507
- const size2 = { height, width };
7508
- return /* @__PURE__ */ u$1(ErrorBoundary, { size: size2, children: /* @__PURE__ */ u$1(ResizeContainer, { size: size2, children: /* @__PURE__ */ u$1(AggregateInner, { ...innerProps }) }) });
7517
+ const size = { height, width };
7518
+ return /* @__PURE__ */ u$1(ErrorBoundary, { size, children: /* @__PURE__ */ u$1(ResizeContainer, { size, children: /* @__PURE__ */ u$1(AggregateInner, { ...innerProps }) }) });
7509
7519
  };
7510
7520
  const AggregateInner = ({
7511
7521
  fields,
@@ -7546,7 +7556,7 @@ const AggregatedDataTabs = ({ data, views, fields, pageSize }) => {
7546
7556
  const Toolbar$2 = ({ data }) => {
7547
7557
  return /* @__PURE__ */ u$1("div", { class: "flex flex-row", children: [
7548
7558
  /* @__PURE__ */ u$1(CsvDownloadButton, { className: "mx-1 btn btn-xs", getData: () => data, filename: "aggregate.csv" }),
7549
- /* @__PURE__ */ u$1(Info, { height: "100px", children: "Info for aggregate" })
7559
+ /* @__PURE__ */ u$1(Info, { children: "Info for aggregate" })
7550
7560
  ] });
7551
7561
  };
7552
7562
  var __defProp$7 = Object.defineProperty;
@@ -7771,8 +7781,8 @@ async function queryNumberOfSequencesOverTime(lapis, lapisFilter, lapisDateField
7771
7781
  return Promise.all(queries);
7772
7782
  }
7773
7783
  const NumberSequencesOverTime = ({ width, height, ...innerProps }) => {
7774
- const size2 = { height, width };
7775
- return /* @__PURE__ */ u$1(ErrorBoundary, { size: size2, children: /* @__PURE__ */ u$1(ResizeContainer, { size: size2, children: /* @__PURE__ */ u$1(NumberSequencesOverTimeInner, { ...innerProps }) }) });
7784
+ const size = { height, width };
7785
+ return /* @__PURE__ */ u$1(ErrorBoundary, { size, children: /* @__PURE__ */ u$1(ResizeContainer, { size, children: /* @__PURE__ */ u$1(NumberSequencesOverTimeInner, { ...innerProps }) }) });
7776
7786
  };
7777
7787
  const NumberSequencesOverTimeInner = ({
7778
7788
  lapisFilter,
@@ -7858,7 +7868,7 @@ const Toolbar$1 = ({ activeTab, data, granularity, yAxisScaleType, setYAxisScale
7858
7868
  /* @__PURE__ */ u$1(NumberSequencesOverTimeInfo, {})
7859
7869
  ] });
7860
7870
  };
7861
- const NumberSequencesOverTimeInfo = () => /* @__PURE__ */ u$1(Info, { height: "100px", children: [
7871
+ const NumberSequencesOverTimeInfo = () => /* @__PURE__ */ u$1(Info, { children: [
7862
7872
  /* @__PURE__ */ u$1(InfoHeadline1, { children: "Number of sequences over time" }),
7863
7873
  /* @__PURE__ */ u$1(InfoParagraph, { children: /* @__PURE__ */ u$1("a", { href: "https://github.com/GenSpectrum/dashboard-components/issues/315", children: "TODO" }) })
7864
7874
  ] });
@@ -7966,6 +7976,62 @@ function filterProportion(data, proportionInterval) {
7966
7976
  }
7967
7977
  });
7968
7978
  }
7979
+ const ColorScaleSelector = ({ colorScale, setColorScale }) => {
7980
+ const colorDisplayCss = `w-10 h-8 border border-gray-200 mx-2 text-xs flex items-center justify-center`;
7981
+ return /* @__PURE__ */ u$1("div", { className: "flex items-center", children: [
7982
+ /* @__PURE__ */ u$1(
7983
+ "div",
7984
+ {
7985
+ style: {
7986
+ backgroundColor: singleGraphColorRGBByName(colorScale.color, 0),
7987
+ color: "black"
7988
+ },
7989
+ className: colorDisplayCss,
7990
+ children: formatProportion(colorScale.min, 0)
7991
+ }
7992
+ ),
7993
+ /* @__PURE__ */ u$1("div", { className: "w-64", children: /* @__PURE__ */ u$1(
7994
+ MinMaxRangeSlider,
7995
+ {
7996
+ min: colorScale.min * 100,
7997
+ max: colorScale.max * 100,
7998
+ setMin: (percentage) => {
7999
+ setColorScale({ ...colorScale, min: percentage / 100 });
8000
+ },
8001
+ setMax: (percentage) => {
8002
+ setColorScale({ ...colorScale, max: percentage / 100 });
8003
+ }
8004
+ }
8005
+ ) }),
8006
+ /* @__PURE__ */ u$1(
8007
+ "div",
8008
+ {
8009
+ style: {
8010
+ backgroundColor: singleGraphColorRGBByName(colorScale.color, 1),
8011
+ color: "white"
8012
+ },
8013
+ className: colorDisplayCss,
8014
+ children: formatProportion(colorScale.max, 0)
8015
+ }
8016
+ )
8017
+ ] });
8018
+ };
8019
+ const getColorWithingScale = (value, colorScale) => {
8020
+ if (colorScale.min === colorScale.max) {
8021
+ return singleGraphColorRGBByName(colorScale.color, 0);
8022
+ }
8023
+ const colorRange = colorScale.max - colorScale.min;
8024
+ const alpha = (value - colorScale.min) / colorRange;
8025
+ return singleGraphColorRGBByName(colorScale.color, alpha);
8026
+ };
8027
+ const getTextColorForScale = (value, colorScale) => {
8028
+ if (colorScale.min === colorScale.max) {
8029
+ return "black";
8030
+ }
8031
+ const colorRange = colorScale.max - colorScale.min;
8032
+ const alpha = (value - colorScale.min) / colorRange;
8033
+ return alpha <= 0.5 ? "black" : "white";
8034
+ };
7969
8035
  function getPositionCss(position) {
7970
8036
  switch (position) {
7971
8037
  case "top":
@@ -7989,8 +8055,8 @@ function getPositionCss(position) {
7989
8055
  }
7990
8056
  }
7991
8057
  const Tooltip = ({ children, content, position = "bottom" }) => {
7992
- return /* @__PURE__ */ u$1("div", { className: "relative", children: [
7993
- /* @__PURE__ */ u$1("div", { className: "peer", children }),
8058
+ return /* @__PURE__ */ u$1("div", { className: "relative w-full h-full", children: [
8059
+ /* @__PURE__ */ u$1("div", { className: "peer w-full h-full", children }),
7994
8060
  /* @__PURE__ */ u$1(
7995
8061
  "div",
7996
8062
  {
@@ -8001,10 +8067,14 @@ const Tooltip = ({ children, content, position = "bottom" }) => {
8001
8067
  ] });
8002
8068
  };
8003
8069
  const MAX_NUMBER_OF_GRID_ROWS = 100;
8004
- const MutationsOverTimeGrid = ({ data }) => {
8005
- const allMutations = data.getFirstAxisKeys();
8070
+ const MUTATION_CELL_WIDTH_REM = 8;
8071
+ const MutationsOverTimeGrid = ({ data, colorScale }) => {
8072
+ const allMutations = data.getFirstAxisKeys().sort(sortSubstitutionsAndDeletions);
8006
8073
  const shownMutations = allMutations.slice(0, MAX_NUMBER_OF_GRID_ROWS);
8007
8074
  const dates = data.getSecondAxisKeys().sort((a2, b3) => compareTemporal(a2, b3));
8075
+ const [showProportionText, setShowProportionText] = h(false);
8076
+ const gridRef = A(null);
8077
+ useShowProportion(gridRef, dates.length, setShowProportionText);
8008
8078
  return /* @__PURE__ */ u$1(Fragment, { children: [
8009
8079
  allMutations.length > MAX_NUMBER_OF_GRID_ROWS && /* @__PURE__ */ u$1("div", { className: "pl-2", children: [
8010
8080
  "Showing ",
@@ -8016,10 +8086,11 @@ const MutationsOverTimeGrid = ({ data }) => {
8016
8086
  /* @__PURE__ */ u$1(
8017
8087
  "div",
8018
8088
  {
8089
+ ref: gridRef,
8019
8090
  style: {
8020
8091
  display: "grid",
8021
8092
  gridTemplateRows: `repeat(${shownMutations.length}, 24px)`,
8022
- gridTemplateColumns: `8rem repeat(${dates.length}, minmax(1.5rem, 1fr))`
8093
+ gridTemplateColumns: `${MUTATION_CELL_WIDTH_REM}rem repeat(${dates.length}, minmax(0.05rem, 1fr))`
8023
8094
  },
8024
8095
  children: shownMutations.map((mutation, rowIndex) => {
8025
8096
  return /* @__PURE__ */ u$1(Fragment, { children: [
@@ -8049,7 +8120,9 @@ const MutationsOverTimeGrid = ({ data }) => {
8049
8120
  value,
8050
8121
  date,
8051
8122
  mutation,
8052
- tooltipPosition
8123
+ tooltipPosition,
8124
+ showProportionText,
8125
+ colorScale
8053
8126
  }
8054
8127
  )
8055
8128
  },
@@ -8062,16 +8135,34 @@ const MutationsOverTimeGrid = ({ data }) => {
8062
8135
  )
8063
8136
  ] });
8064
8137
  };
8138
+ function useShowProportion(gridRef, girdColumns, setShowProportionText) {
8139
+ y(() => {
8140
+ const checkWidth = () => {
8141
+ if (gridRef.current) {
8142
+ const width = gridRef.current.getBoundingClientRect().width;
8143
+ const widthPerDate = (width - remToPx(MUTATION_CELL_WIDTH_REM)) / girdColumns;
8144
+ const maxWidthProportionText = 28;
8145
+ setShowProportionText(widthPerDate > maxWidthProportionText);
8146
+ }
8147
+ };
8148
+ checkWidth();
8149
+ window.addEventListener("resize", checkWidth);
8150
+ return () => {
8151
+ window.removeEventListener("resize", checkWidth);
8152
+ };
8153
+ }, [girdColumns, gridRef, setShowProportionText]);
8154
+ }
8155
+ const remToPx = (rem) => rem * parseFloat(getComputedStyle(document.documentElement).fontSize);
8065
8156
  function getTooltipPosition(rowIndex, rows, columnIndex, columns) {
8066
8157
  const tooltipX = rowIndex < rows / 2 ? "bottom" : "top";
8067
8158
  const tooltipY = columnIndex < columns / 2 ? "start" : "end";
8068
8159
  return `${tooltipX}-${tooltipY}`;
8069
8160
  }
8070
- const ProportionCell = ({ value, mutation, date, tooltipPosition }) => {
8161
+ const ProportionCell = ({ value, mutation, date, tooltipPosition, showProportionText, colorScale }) => {
8071
8162
  const tooltipContent = /* @__PURE__ */ u$1("div", { children: [
8163
+ /* @__PURE__ */ u$1("p", { children: /* @__PURE__ */ u$1("span", { className: "font-bold", children: date.englishName() }) }),
8072
8164
  /* @__PURE__ */ u$1("p", { children: [
8073
- /* @__PURE__ */ u$1("span", { className: "font-bold", children: date.englishName() }),
8074
- " (",
8165
+ "(",
8075
8166
  timeIntervalDisplay(date),
8076
8167
  ")"
8077
8168
  ] }),
@@ -8085,17 +8176,17 @@ const ProportionCell = ({ value, mutation, date, tooltipPosition }) => {
8085
8176
  value.count
8086
8177
  ] })
8087
8178
  ] });
8088
- return /* @__PURE__ */ u$1(Fragment, { children: /* @__PURE__ */ u$1("div", { className: "py-1", children: /* @__PURE__ */ u$1(Tooltip, { content: tooltipContent, position: tooltipPosition, children: /* @__PURE__ */ u$1(
8179
+ return /* @__PURE__ */ u$1("div", { className: "py-1 w-full h-full", children: /* @__PURE__ */ u$1(Tooltip, { content: tooltipContent, position: tooltipPosition, children: /* @__PURE__ */ u$1(
8089
8180
  "div",
8090
8181
  {
8091
8182
  style: {
8092
- backgroundColor: backgroundColor(value.proportion),
8093
- color: textColor(value.proportion)
8183
+ backgroundColor: getColorWithingScale(value.proportion, colorScale),
8184
+ color: getTextColorForScale(value.proportion, colorScale)
8094
8185
  },
8095
- className: "text-center hover:font-bold text-xs",
8096
- children: formatProportion(value.proportion, 0)
8186
+ className: `w-full h-full text-center hover:font-bold text-xs group`,
8187
+ children: showProportionText ? formatProportion(value.proportion, 0) : void 0
8097
8188
  }
8098
- ) }) }) });
8189
+ ) }) });
8099
8190
  };
8100
8191
  const timeIntervalDisplay = (date) => {
8101
8192
  if (date instanceof YearMonthDay) {
@@ -8103,15 +8194,6 @@ const timeIntervalDisplay = (date) => {
8103
8194
  }
8104
8195
  return `${date.firstDay.toString()} - ${date.lastDay.toString()}`;
8105
8196
  };
8106
- const backgroundColor = (proportion) => {
8107
- const minAlpha = 0;
8108
- const maxAlpha = 1;
8109
- const alpha = minAlpha + (maxAlpha - minAlpha) * proportion;
8110
- return singleGraphColorRGBByName("indigo", alpha);
8111
- };
8112
- const textColor = (proportion) => {
8113
- return proportion > 0.5 ? "white" : "black";
8114
- };
8115
8197
  const MutationCell = ({ mutation }) => {
8116
8198
  return /* @__PURE__ */ u$1("div", { className: "text-center", children: mutation.toString() });
8117
8199
  };
@@ -8270,9 +8352,15 @@ function addZeroValuesForDatesWithNoMutationData(dataArray, data) {
8270
8352
  });
8271
8353
  }
8272
8354
  }
8355
+ const ColorScaleSelectorDropdown = ({
8356
+ colorScale,
8357
+ setColorScale
8358
+ }) => {
8359
+ return /* @__PURE__ */ u$1(Dropdown, { buttonTitle: `Color scale`, placement: "bottom-start", children: /* @__PURE__ */ u$1(ColorScaleSelector, { colorScale, setColorScale }) });
8360
+ };
8273
8361
  const MutationsOverTime = ({ width, height, ...innerProps }) => {
8274
- const size2 = { height, width };
8275
- return /* @__PURE__ */ u$1(ErrorBoundary, { size: size2, children: /* @__PURE__ */ u$1(ResizeContainer, { size: size2, children: /* @__PURE__ */ u$1(MutationsOverTimeInner, { ...innerProps }) }) });
8362
+ const size = { height, width };
8363
+ return /* @__PURE__ */ u$1(ErrorBoundary, { size, children: /* @__PURE__ */ u$1(ResizeContainer, { size, children: /* @__PURE__ */ u$1(MutationsOverTimeInner, { ...innerProps }) }) });
8276
8364
  };
8277
8365
  const MutationsOverTimeInner = ({
8278
8366
  lapisFilter,
@@ -8302,6 +8390,7 @@ const MutationsOverTimeTabs = ({
8302
8390
  views
8303
8391
  }) => {
8304
8392
  const [proportionInterval, setProportionInterval] = h({ min: 0.05, max: 0.9 });
8393
+ const [colorScale, setColorScale] = h({ min: 0, max: 1, color: "indigo" });
8305
8394
  const [displayedSegments, setDisplayedSegments] = useDisplayedSegments(sequenceType);
8306
8395
  const [displayedMutationTypes, setDisplayedMutationTypes] = h([
8307
8396
  { label: "Substitutions", checked: true, type: "substitution" },
@@ -8321,35 +8410,42 @@ const MutationsOverTimeTabs = ({
8321
8410
  case "grid":
8322
8411
  return {
8323
8412
  title: "Grid",
8324
- content: /* @__PURE__ */ u$1(MutationsOverTimeGrid, { data: filteredData })
8413
+ content: /* @__PURE__ */ u$1(MutationsOverTimeGrid, { data: filteredData, colorScale })
8325
8414
  };
8326
8415
  }
8327
8416
  };
8328
8417
  const tabs = views.map((view) => getTab(view));
8329
- const toolbar = () => /* @__PURE__ */ u$1(
8418
+ const toolbar = (activeTab) => /* @__PURE__ */ u$1(
8330
8419
  Toolbar,
8331
8420
  {
8421
+ activeTab,
8332
8422
  displayedSegments,
8333
8423
  setDisplayedSegments,
8334
8424
  displayedMutationTypes,
8335
8425
  setDisplayedMutationTypes,
8336
8426
  proportionInterval,
8337
8427
  setProportionInterval,
8338
- filteredData
8428
+ filteredData,
8429
+ colorScale,
8430
+ setColorScale
8339
8431
  }
8340
8432
  );
8341
8433
  return /* @__PURE__ */ u$1(Tabs, { tabs, toolbar });
8342
8434
  };
8343
8435
  const Toolbar = ({
8436
+ activeTab,
8344
8437
  displayedSegments,
8345
8438
  setDisplayedSegments,
8346
8439
  displayedMutationTypes,
8347
8440
  setDisplayedMutationTypes,
8348
8441
  proportionInterval,
8349
8442
  setProportionInterval,
8350
- filteredData
8443
+ filteredData,
8444
+ colorScale,
8445
+ setColorScale
8351
8446
  }) => {
8352
8447
  return /* @__PURE__ */ u$1(Fragment, { children: [
8448
+ activeTab === "Grid" && /* @__PURE__ */ u$1(ColorScaleSelectorDropdown, { colorScale, setColorScale }),
8353
8449
  /* @__PURE__ */ u$1(SegmentSelector, { displayedSegments, setDisplayedSegments }),
8354
8450
  /* @__PURE__ */ u$1(
8355
8451
  MutationTypeSelector,
@@ -8374,12 +8470,12 @@ const Toolbar = ({
8374
8470
  filename: "mutations_over_time.csv"
8375
8471
  }
8376
8472
  ),
8377
- /* @__PURE__ */ u$1(Info, { height: "100px", children: "Info for mutations over time" })
8473
+ /* @__PURE__ */ u$1(Info, { children: "Info for mutations over time" })
8378
8474
  ] });
8379
8475
  };
8380
8476
  function getDownloadData(filteredData) {
8381
8477
  const dates = filteredData.getSecondAxisKeys().sort((a2, b3) => compareTemporal(a2, b3));
8382
- return filteredData.getFirstAxisKeys().map((mutation) => {
8478
+ return filteredData.getFirstAxisKeys().sort(sortSubstitutionsAndDeletions).map((mutation) => {
8383
8479
  return dates.reduce(
8384
8480
  (accumulated, date) => {
8385
8481
  var _a;
@@ -8569,8 +8665,8 @@ const DateRangeSelector = ({
8569
8665
  width,
8570
8666
  ...innerProps
8571
8667
  }) => {
8572
- const size2 = { width, height: "3rem" };
8573
- return /* @__PURE__ */ u$1(ErrorBoundary, { size: size2, children: /* @__PURE__ */ u$1("div", { style: { width }, children: /* @__PURE__ */ u$1(DateRangeSelectorInner, { ...innerProps }) }) });
8668
+ const size = { width, height: "3rem" };
8669
+ return /* @__PURE__ */ u$1(ErrorBoundary, { size, children: /* @__PURE__ */ u$1("div", { style: { width }, children: /* @__PURE__ */ u$1(DateRangeSelectorInner, { ...innerProps }) }) });
8574
8670
  };
8575
8671
  const DateRangeSelectorInner = ({
8576
8672
  customSelectOptions,
@@ -8817,8 +8913,8 @@ function compareLocationEntries(fields) {
8817
8913
  };
8818
8914
  }
8819
8915
  const LocationFilter = ({ width, ...innerProps }) => {
8820
- const size2 = { width, height: "3rem" };
8821
- return /* @__PURE__ */ u$1(ErrorBoundary, { size: size2, children: /* @__PURE__ */ u$1(ResizeContainer, { size: size2, children: /* @__PURE__ */ u$1(LocationFilterInner, { ...innerProps }) }) });
8916
+ const size = { width, height: "3rem" };
8917
+ return /* @__PURE__ */ u$1(ErrorBoundary, { size, children: /* @__PURE__ */ u$1(ResizeContainer, { size, children: /* @__PURE__ */ u$1(LocationFilterInner, { ...innerProps }) }) });
8822
8918
  };
8823
8919
  const LocationFilterInner = ({ initialValue, fields, placeholderText }) => {
8824
8920
  const lapis = x(LapisUrlContext);
@@ -8937,8 +9033,8 @@ async function fetchAutocompleteList(lapis, field, signal) {
8937
9033
  return data.map((item) => item[field]);
8938
9034
  }
8939
9035
  const TextInput = ({ width, ...innerProps }) => {
8940
- const size2 = { width, height: "3rem" };
8941
- return /* @__PURE__ */ u$1(ErrorBoundary, { size: size2, children: /* @__PURE__ */ u$1(ResizeContainer, { size: size2, children: /* @__PURE__ */ u$1(TextInputInner, { ...innerProps }) }) });
9036
+ const size = { width, height: "3rem" };
9037
+ return /* @__PURE__ */ u$1(ErrorBoundary, { size, children: /* @__PURE__ */ u$1(ResizeContainer, { size, children: /* @__PURE__ */ u$1(TextInputInner, { ...innerProps }) }) });
8942
9038
  };
8943
9039
  const TextInputInner = ({ lapisField, placeholderText, initialValue }) => {
8944
9040
  const lapis = x(LapisUrlContext);
@@ -9046,7 +9142,7 @@ function isNotInitialized(referenceGenome) {
9046
9142
  const MutationFilterInfo = () => {
9047
9143
  const referenceGenome = x(ReferenceGenomeContext);
9048
9144
  const firstGene = referenceGenome.genes[0].name;
9049
- return /* @__PURE__ */ u$1(Info, { height: "80vh", children: [
9145
+ return /* @__PURE__ */ u$1(Info, { children: [
9050
9146
  /* @__PURE__ */ u$1(InfoHeadline1, { children: " Mutation Filter" }),
9051
9147
  /* @__PURE__ */ u$1(InfoParagraph, { children: "This component allows you to filter for mutations at specific positions." }),
9052
9148
  /* @__PURE__ */ u$1(InfoHeadline2, { children: " Nucleotide Mutations and Insertions" }),
@@ -9306,21 +9402,6 @@ const parseAndValidateMutation = (value, referenceGenome) => {
9306
9402
  }
9307
9403
  return null;
9308
9404
  };
9309
- const DeleteIcon = () => {
9310
- return /* @__PURE__ */ u$1(
9311
- "svg",
9312
- {
9313
- fill: "currentColor",
9314
- "stroke-width": "0",
9315
- xmlns: "http://www.w3.org/2000/svg",
9316
- viewBox: "0 0 16 16",
9317
- style: "overflow: visible; color: currentcolor;",
9318
- height: "1em",
9319
- width: "1em",
9320
- children: /* @__PURE__ */ u$1("path", { d: "M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708z" })
9321
- }
9322
- );
9323
- };
9324
9405
  const MutationFilter = ({ initialValue, width }) => {
9325
9406
  return /* @__PURE__ */ u$1(ErrorBoundary, { size: { height: "3.375rem", width }, children: /* @__PURE__ */ u$1("div", { style: width, children: /* @__PURE__ */ u$1(MutationFilterInner, { initialValue }) }) });
9326
9407
  };
@@ -9489,71 +9570,71 @@ const SelectedMutationDisplay = ({ selectedFilters, setSelectedFilters, fireChan
9489
9570
  ] });
9490
9571
  };
9491
9572
  const SelectedAminoAcidInsertion = ({ insertion, onDelete }) => {
9492
- const backgroundColor2 = singleGraphColorRGBByName("teal", 0.3);
9493
- const textColor2 = singleGraphColorRGBByName("teal", 1);
9573
+ const backgroundColor = singleGraphColorRGBByName("teal", 0.3);
9574
+ const textColor = singleGraphColorRGBByName("teal", 1);
9494
9575
  return /* @__PURE__ */ u$1(
9495
9576
  SelectedFilter,
9496
9577
  {
9497
9578
  mutation: insertion,
9498
9579
  onDelete,
9499
- backgroundColor: backgroundColor2,
9500
- textColor: textColor2
9580
+ backgroundColor,
9581
+ textColor
9501
9582
  }
9502
9583
  );
9503
9584
  };
9504
9585
  const SelectedAminoAcidMutation = ({ mutation, onDelete }) => {
9505
- const backgroundColor2 = singleGraphColorRGBByName("rose", 0.3);
9506
- const textColor2 = singleGraphColorRGBByName("rose", 1);
9586
+ const backgroundColor = singleGraphColorRGBByName("rose", 0.3);
9587
+ const textColor = singleGraphColorRGBByName("rose", 1);
9507
9588
  return /* @__PURE__ */ u$1(
9508
9589
  SelectedFilter,
9509
9590
  {
9510
9591
  mutation,
9511
9592
  onDelete,
9512
- backgroundColor: backgroundColor2,
9513
- textColor: textColor2
9593
+ backgroundColor,
9594
+ textColor
9514
9595
  }
9515
9596
  );
9516
9597
  };
9517
9598
  const SelectedNucleotideMutation = ({ mutation, onDelete }) => {
9518
- const backgroundColor2 = singleGraphColorRGBByName("indigo", 0.3);
9519
- const textColor2 = singleGraphColorRGBByName("indigo", 1);
9599
+ const backgroundColor = singleGraphColorRGBByName("indigo", 0.3);
9600
+ const textColor = singleGraphColorRGBByName("indigo", 1);
9520
9601
  return /* @__PURE__ */ u$1(
9521
9602
  SelectedFilter,
9522
9603
  {
9523
9604
  mutation,
9524
9605
  onDelete,
9525
- backgroundColor: backgroundColor2,
9526
- textColor: textColor2
9606
+ backgroundColor,
9607
+ textColor
9527
9608
  }
9528
9609
  );
9529
9610
  };
9530
9611
  const SelectedNucleotideInsertion = ({ insertion, onDelete }) => {
9531
- const backgroundColor2 = singleGraphColorRGBByName("green", 0.3);
9532
- const textColor2 = singleGraphColorRGBByName("green", 1);
9612
+ const backgroundColor = singleGraphColorRGBByName("green", 0.3);
9613
+ const textColor = singleGraphColorRGBByName("green", 1);
9533
9614
  return /* @__PURE__ */ u$1(
9534
9615
  SelectedFilter,
9535
9616
  {
9536
9617
  mutation: insertion,
9537
9618
  onDelete,
9538
- backgroundColor: backgroundColor2,
9539
- textColor: textColor2
9619
+ backgroundColor,
9620
+ textColor
9540
9621
  }
9541
9622
  );
9542
9623
  };
9543
9624
  const SelectedFilter = ({
9544
9625
  mutation,
9545
9626
  onDelete,
9546
- backgroundColor: backgroundColor2,
9547
- textColor: textColor2
9627
+ backgroundColor,
9628
+ textColor
9548
9629
  }) => {
9549
9630
  return /* @__PURE__ */ u$1(
9550
9631
  "span",
9551
9632
  {
9552
9633
  class: "inline-block mx-1 px-2 py-1 font-medium text-xs rounded-full",
9553
- style: { backgroundColor: backgroundColor2, color: textColor2 },
9634
+ style: { backgroundColor, color: textColor },
9554
9635
  children: [
9555
9636
  mutation.toString(),
9556
- /* @__PURE__ */ u$1("button", { type: "button", onClick: () => onDelete(mutation), children: /* @__PURE__ */ u$1(DeleteIcon, {}) })
9637
+ /* @__PURE__ */ u$1("button", { className: "ml-1", type: "button", onClick: () => onDelete(mutation), children: "✕" })
9557
9638
  ]
9558
9639
  }
9559
9640
  );
@@ -9601,8 +9682,8 @@ async function fetchLineageAutocompleteList(lapis, field, signal) {
9601
9682
  return data.flatMap((item) => [item[field], `${item[field]}*`]).sort();
9602
9683
  }
9603
9684
  const LineageFilter = ({ width, ...innerProps }) => {
9604
- const size2 = { width, height: "3rem" };
9605
- return /* @__PURE__ */ u$1(ErrorBoundary, { size: size2, children: /* @__PURE__ */ u$1(ResizeContainer, { size: size2, children: /* @__PURE__ */ u$1(LineageFilterInner, { ...innerProps }) }) });
9685
+ const size = { width, height: "3rem" };
9686
+ return /* @__PURE__ */ u$1(ErrorBoundary, { size, children: /* @__PURE__ */ u$1(ResizeContainer, { size, children: /* @__PURE__ */ u$1(LineageFilterInner, { ...innerProps }) }) });
9606
9687
  };
9607
9688
  const LineageFilterInner = ({
9608
9689
  lapisField,