@genspectrum/dashboard-components 0.6.11 → 0.6.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/dashboard-components.js +1079 -873
- package/dist/dashboard-components.js.map +1 -1
- package/dist/genspectrum-components.d.ts +3 -3
- package/dist/style.css +117 -24
- package/package.json +2 -2
- package/src/preact/components/checkbox-selector.stories.tsx +93 -11
- package/src/preact/components/checkbox-selector.tsx +19 -0
- package/src/preact/components/color-scale-selector-dropdown.tsx +5 -3
- package/src/preact/components/dropdown.tsx +3 -3
- package/src/preact/components/loading-display.tsx +8 -1
- package/src/preact/components/mutation-type-selector.stories.tsx +115 -0
- package/src/preact/components/mutation-type-selector.tsx +33 -8
- package/src/preact/components/percent-input.stories.tsx +93 -0
- package/src/preact/components/percent-intput.tsx +4 -0
- package/src/preact/components/proportion-selector-dropdown.stories.tsx +2 -2
- package/src/preact/components/proportion-selector-dropdown.tsx +9 -7
- package/src/preact/components/proportion-selector.stories.tsx +4 -4
- package/src/preact/components/proportion-selector.tsx +46 -12
- package/src/preact/components/segment-selector.stories.tsx +151 -0
- package/src/preact/components/{SegmentSelector.tsx → segment-selector.tsx} +29 -20
- package/src/preact/mutationComparison/mutation-comparison.stories.tsx +1 -1
- package/src/preact/mutationComparison/mutation-comparison.tsx +1 -1
- package/src/preact/mutationComparison/queryMutationData.ts +1 -1
- package/src/preact/mutations/mutations-grid.tsx +5 -1
- package/src/preact/mutations/mutations.tsx +1 -1
- package/src/preact/mutations/queryMutations.ts +1 -1
- package/src/preact/mutationsOverTime/getFilteredMutationsOverTime.spec.ts +4 -4
- package/src/preact/mutationsOverTime/getFilteredMutationsOverTimeData.ts +3 -2
- package/src/preact/mutationsOverTime/mutations-over-time.tsx +1 -1
- package/src/preact/numberSequencesOverTime/number-sequences-over-time.tsx +3 -2
- package/src/preact/useQuery.ts +1 -1
- package/src/query/queryMutationsOverTime.ts +3 -3
- package/src/utils/map2d.spec.ts +83 -22
- package/src/utils/map2d.ts +158 -0
- package/src/utils/Map2d.ts +0 -75
|
@@ -25877,6 +25877,249 @@ function filterBySegmentAndMutationType(data, displayedSegments, displayedMutati
|
|
|
25877
25877
|
return data.filter(byDisplayedSegments).filter(byDisplayedMutationTypes);
|
|
25878
25878
|
}
|
|
25879
25879
|
const LapisUrlContext = G$1("");
|
|
25880
|
+
const CsvDownloadButton = ({
|
|
25881
|
+
label = "Download",
|
|
25882
|
+
filename = "data.csv",
|
|
25883
|
+
getData,
|
|
25884
|
+
className
|
|
25885
|
+
}) => {
|
|
25886
|
+
const download = () => {
|
|
25887
|
+
const content = getDownloadContent();
|
|
25888
|
+
const blob = new Blob([content], { type: "text/csv" });
|
|
25889
|
+
const url = URL.createObjectURL(blob);
|
|
25890
|
+
const a2 = document.createElement("a");
|
|
25891
|
+
a2.href = url;
|
|
25892
|
+
a2.download = filename;
|
|
25893
|
+
a2.click();
|
|
25894
|
+
URL.revokeObjectURL(url);
|
|
25895
|
+
};
|
|
25896
|
+
const getDownloadContent = () => {
|
|
25897
|
+
const data = getData();
|
|
25898
|
+
const keys = getDataKeys(data);
|
|
25899
|
+
const header = `${keys.join(",")}
|
|
25900
|
+
`;
|
|
25901
|
+
const rows = data.map((row) => keys.map((key) => row[key]).join(",")).join("\n");
|
|
25902
|
+
return header + rows;
|
|
25903
|
+
};
|
|
25904
|
+
const getDataKeys = (data) => {
|
|
25905
|
+
const keysSet = data.map((row) => Object.keys(row)).reduce((accumulatedKeys, keys) => {
|
|
25906
|
+
keys.forEach((key) => accumulatedKeys.add(key));
|
|
25907
|
+
return accumulatedKeys;
|
|
25908
|
+
}, /* @__PURE__ */ new Set());
|
|
25909
|
+
return [...keysSet];
|
|
25910
|
+
};
|
|
25911
|
+
return /* @__PURE__ */ u$2("button", { className, onClick: download, children: label });
|
|
25912
|
+
};
|
|
25913
|
+
class UserFacingError extends Error {
|
|
25914
|
+
constructor(headline, message) {
|
|
25915
|
+
super(message);
|
|
25916
|
+
this.headline = headline;
|
|
25917
|
+
this.name = "UserFacingError";
|
|
25918
|
+
}
|
|
25919
|
+
}
|
|
25920
|
+
const ErrorDisplay = ({ error }) => {
|
|
25921
|
+
console.error(error);
|
|
25922
|
+
const ref = A$1(null);
|
|
25923
|
+
return /* @__PURE__ */ u$2("div", { className: "h-full w-full rounded-md border-2 border-gray-100 p-2 flex items-center justify-center flex-col", children: [
|
|
25924
|
+
/* @__PURE__ */ u$2("div", { className: "text-red-700 font-bold", children: "Error" }),
|
|
25925
|
+
/* @__PURE__ */ u$2("div", { children: [
|
|
25926
|
+
"Oops! Something went wrong.",
|
|
25927
|
+
error instanceof UserFacingError && /* @__PURE__ */ u$2(k$1, { children: [
|
|
25928
|
+
" ",
|
|
25929
|
+
/* @__PURE__ */ u$2(
|
|
25930
|
+
"button",
|
|
25931
|
+
{
|
|
25932
|
+
className: "text-sm text-gray-600 hover:text-gray-300",
|
|
25933
|
+
onClick: () => {
|
|
25934
|
+
var _a2;
|
|
25935
|
+
return (_a2 = ref.current) == null ? void 0 : _a2.showModal();
|
|
25936
|
+
},
|
|
25937
|
+
children: "Show details."
|
|
25938
|
+
}
|
|
25939
|
+
),
|
|
25940
|
+
/* @__PURE__ */ u$2("dialog", { ref, class: "modal", children: [
|
|
25941
|
+
/* @__PURE__ */ u$2("div", { class: "modal-box", children: [
|
|
25942
|
+
/* @__PURE__ */ u$2("form", { method: "dialog", children: /* @__PURE__ */ u$2("button", { className: "btn btn-sm btn-circle btn-ghost absolute right-2 top-2", children: "✕" }) }),
|
|
25943
|
+
/* @__PURE__ */ u$2("h1", { class: "text-lg", children: error.headline }),
|
|
25944
|
+
/* @__PURE__ */ u$2("p", { class: "py-4", children: error.message })
|
|
25945
|
+
] }),
|
|
25946
|
+
/* @__PURE__ */ u$2("form", { method: "dialog", class: "modal-backdrop", children: /* @__PURE__ */ u$2("button", { children: "close" }) })
|
|
25947
|
+
] })
|
|
25948
|
+
] })
|
|
25949
|
+
] })
|
|
25950
|
+
] });
|
|
25951
|
+
};
|
|
25952
|
+
const ResizeContainer = ({ children, size }) => {
|
|
25953
|
+
return /* @__PURE__ */ u$2("div", { style: size, className: "bg-white", children });
|
|
25954
|
+
};
|
|
25955
|
+
const ErrorBoundary = ({ size, children }) => {
|
|
25956
|
+
const [internalError] = b$1();
|
|
25957
|
+
if (internalError) {
|
|
25958
|
+
return /* @__PURE__ */ u$2(ResizeContainer, { size, children: /* @__PURE__ */ u$2(ErrorDisplay, { error: internalError }) });
|
|
25959
|
+
}
|
|
25960
|
+
return /* @__PURE__ */ u$2(k$1, { children });
|
|
25961
|
+
};
|
|
25962
|
+
const Fullscreen = () => {
|
|
25963
|
+
const element = A$1(null);
|
|
25964
|
+
const isFullscreen = useFullscreenStatus();
|
|
25965
|
+
return /* @__PURE__ */ u$2(
|
|
25966
|
+
"button",
|
|
25967
|
+
{
|
|
25968
|
+
ref: element,
|
|
25969
|
+
onClick: async () => {
|
|
25970
|
+
if (element.current) {
|
|
25971
|
+
if (isFullscreen) {
|
|
25972
|
+
await document.exitFullscreen();
|
|
25973
|
+
} else {
|
|
25974
|
+
const componentRoot = findComponentRoot(element.current);
|
|
25975
|
+
if (componentRoot) {
|
|
25976
|
+
await componentRoot.requestFullscreen();
|
|
25977
|
+
}
|
|
25978
|
+
}
|
|
25979
|
+
}
|
|
25980
|
+
},
|
|
25981
|
+
className: `mt-0.5 iconify text-2xl ${isFullscreen ? "mdi--fullscreen-exit hover:scale-90" : "mdi--fullscreen hover:scale-110"}`,
|
|
25982
|
+
title: isFullscreen ? "Exit fullscreen" : "Enter fullscreen"
|
|
25983
|
+
}
|
|
25984
|
+
);
|
|
25985
|
+
};
|
|
25986
|
+
function findComponentRoot(element) {
|
|
25987
|
+
var _a2;
|
|
25988
|
+
return (_a2 = findShadowRoot(element)) == null ? void 0 : _a2.children[0];
|
|
25989
|
+
}
|
|
25990
|
+
function findShadowRoot(element) {
|
|
25991
|
+
let current = element;
|
|
25992
|
+
while (current) {
|
|
25993
|
+
if (current instanceof ShadowRoot) {
|
|
25994
|
+
return current;
|
|
25995
|
+
}
|
|
25996
|
+
if (current.parentNode === null) {
|
|
25997
|
+
return null;
|
|
25998
|
+
}
|
|
25999
|
+
current = current.parentNode;
|
|
26000
|
+
}
|
|
26001
|
+
return null;
|
|
26002
|
+
}
|
|
26003
|
+
function useFullscreenStatus() {
|
|
26004
|
+
const [isFullscreen, setIsFullscreen] = h$1(document.fullscreenElement !== null);
|
|
26005
|
+
y$1(() => {
|
|
26006
|
+
const handleFullscreenChange = () => {
|
|
26007
|
+
setIsFullscreen(document.fullscreenElement !== null);
|
|
26008
|
+
};
|
|
26009
|
+
document.addEventListener("fullscreenchange", handleFullscreenChange);
|
|
26010
|
+
return () => {
|
|
26011
|
+
document.removeEventListener("fullscreenchange", handleFullscreenChange);
|
|
26012
|
+
};
|
|
26013
|
+
}, []);
|
|
26014
|
+
return isFullscreen;
|
|
26015
|
+
}
|
|
26016
|
+
const Info = ({ children }) => {
|
|
26017
|
+
const dialogRef = A$1(null);
|
|
26018
|
+
const toggleHelp = () => {
|
|
26019
|
+
var _a2;
|
|
26020
|
+
(_a2 = dialogRef.current) == null ? void 0 : _a2.showModal();
|
|
26021
|
+
};
|
|
26022
|
+
return /* @__PURE__ */ u$2("div", { className: "relative", children: [
|
|
26023
|
+
/* @__PURE__ */ u$2("button", { type: "button", className: "btn btn-xs", onClick: toggleHelp, children: "?" }),
|
|
26024
|
+
/* @__PURE__ */ u$2("dialog", { ref: dialogRef, className: "modal modal-bottom sm:modal-middle", children: [
|
|
26025
|
+
/* @__PURE__ */ u$2("div", { className: "modal-box sm:max-w-5xl", children: [
|
|
26026
|
+
/* @__PURE__ */ u$2("form", { method: "dialog", children: /* @__PURE__ */ u$2("button", { className: "btn btn-sm btn-circle btn-ghost absolute right-2 top-2", children: "✕" }) }),
|
|
26027
|
+
/* @__PURE__ */ u$2("div", { className: "flex flex-col", children }),
|
|
26028
|
+
/* @__PURE__ */ u$2("div", { className: "modal-action", children: /* @__PURE__ */ u$2("form", { method: "dialog", children: /* @__PURE__ */ u$2("button", { className: "float-right underline text-sm hover:text-blue-700 mr-2", children: "Close" }) }) })
|
|
26029
|
+
] }),
|
|
26030
|
+
/* @__PURE__ */ u$2("form", { method: "dialog", className: "modal-backdrop", children: /* @__PURE__ */ u$2("button", { children: "Helper to close when clicked outside" }) })
|
|
26031
|
+
] })
|
|
26032
|
+
] });
|
|
26033
|
+
};
|
|
26034
|
+
const InfoHeadline1 = ({ children }) => {
|
|
26035
|
+
return /* @__PURE__ */ u$2("h1", { className: "text-lg font-bold", children });
|
|
26036
|
+
};
|
|
26037
|
+
const InfoHeadline2 = ({ children }) => {
|
|
26038
|
+
return /* @__PURE__ */ u$2("h2", { className: "text-base font-bold mt-4", children });
|
|
26039
|
+
};
|
|
26040
|
+
const InfoParagraph = ({ children }) => {
|
|
26041
|
+
return /* @__PURE__ */ u$2("p", { className: "text-justify my-1", children });
|
|
26042
|
+
};
|
|
26043
|
+
const InfoLink = ({ children, href }) => {
|
|
26044
|
+
return /* @__PURE__ */ u$2("a", { className: "text-blue-600 hover:text-blue-800", href, target: "_blank", rel: "noopener noreferrer", children });
|
|
26045
|
+
};
|
|
26046
|
+
const InfoComponentCode = ({ componentName, params, lapisUrl }) => {
|
|
26047
|
+
const componentCode = componentParametersToCode(componentName, params, lapisUrl);
|
|
26048
|
+
const codePenData = {
|
|
26049
|
+
title: "GenSpectrum dashboard component",
|
|
26050
|
+
html: generateFullExampleCode(componentCode, componentName),
|
|
26051
|
+
layout: "left",
|
|
26052
|
+
editors: "100"
|
|
26053
|
+
};
|
|
26054
|
+
return /* @__PURE__ */ u$2(k$1, { children: [
|
|
26055
|
+
/* @__PURE__ */ u$2(InfoHeadline2, { children: "Use this component yourself" }),
|
|
26056
|
+
/* @__PURE__ */ u$2(InfoParagraph, { children: [
|
|
26057
|
+
"This component was created using the following parameters:",
|
|
26058
|
+
/* @__PURE__ */ u$2("div", { className: "p-4 border border-gray-200 rounded-lg overflow-x-auto", children: /* @__PURE__ */ u$2("pre", { children: /* @__PURE__ */ u$2("code", { children: componentCode }) }) })
|
|
26059
|
+
] }),
|
|
26060
|
+
/* @__PURE__ */ u$2(InfoParagraph, { children: [
|
|
26061
|
+
"You can add this component to your own website using the",
|
|
26062
|
+
" ",
|
|
26063
|
+
/* @__PURE__ */ u$2(InfoLink, { href: "https://github.com/GenSpectrum/dashboard-components", children: "GenSpectrum dashboard components library" }),
|
|
26064
|
+
" ",
|
|
26065
|
+
"and the code from above."
|
|
26066
|
+
] }),
|
|
26067
|
+
/* @__PURE__ */ u$2(InfoParagraph, { children: /* @__PURE__ */ u$2("form", { action: "https://codepen.io/pen/define", method: "POST", target: "_blank", children: [
|
|
26068
|
+
/* @__PURE__ */ u$2(
|
|
26069
|
+
"input",
|
|
26070
|
+
{
|
|
26071
|
+
type: "hidden",
|
|
26072
|
+
name: "data",
|
|
26073
|
+
value: JSON.stringify(codePenData).replace(/"/g, """).replace(/'/g, "'")
|
|
26074
|
+
}
|
|
26075
|
+
),
|
|
26076
|
+
/* @__PURE__ */ u$2("button", { className: "text-blue-600 hover:text-blue-800", type: "submit", children: "Click here to try it out on CodePen." })
|
|
26077
|
+
] }) })
|
|
26078
|
+
] });
|
|
26079
|
+
};
|
|
26080
|
+
function componentParametersToCode(componentName, params, lapisUrl) {
|
|
26081
|
+
const stringifyIfNeeded = (value) => {
|
|
26082
|
+
return typeof value === "object" ? JSON.stringify(value) : value;
|
|
26083
|
+
};
|
|
26084
|
+
const attributes = indentLines(
|
|
26085
|
+
Object.entries(params).map(([key, value]) => `${key}='${stringifyIfNeeded(value)}'`).join("\n"),
|
|
26086
|
+
4
|
|
26087
|
+
);
|
|
26088
|
+
return `<gs-app lapis="${lapisUrl}">
|
|
26089
|
+
<gs-${componentName}
|
|
26090
|
+
${attributes}
|
|
26091
|
+
/>
|
|
26092
|
+
</gs-app>`;
|
|
26093
|
+
}
|
|
26094
|
+
function generateFullExampleCode(componentCode, componentName) {
|
|
26095
|
+
const storyBookPath = `/docs/visualization-${componentName}--docs`;
|
|
26096
|
+
return `<html>
|
|
26097
|
+
<head>
|
|
26098
|
+
<script type="module" src="https://unpkg.com/@genspectrum/dashboard-components@latest/dist/dashboard-components.js"><\/script>
|
|
26099
|
+
<link rel="stylesheet" href="https://unpkg.com/@genspectrum/dashboard-components@latest/dist/style.css" />
|
|
26100
|
+
</head>
|
|
26101
|
+
|
|
26102
|
+
<body>
|
|
26103
|
+
<!-- Component documentation: https://genspectrum.github.io/dashboard-components/?path=${storyBookPath} -->
|
|
26104
|
+
${indentLines(componentCode, 2)}
|
|
26105
|
+
</body>
|
|
26106
|
+
</html>
|
|
26107
|
+
`;
|
|
26108
|
+
}
|
|
26109
|
+
function indentLines(text, numberSpaces) {
|
|
26110
|
+
const spaces = " ".repeat(numberSpaces);
|
|
26111
|
+
return text.split("\n").map((line) => spaces + line).join("\n");
|
|
26112
|
+
}
|
|
26113
|
+
const LoadingDisplay = () => {
|
|
26114
|
+
return /* @__PURE__ */ u$2(
|
|
26115
|
+
"div",
|
|
26116
|
+
{
|
|
26117
|
+
"aria-label": "Loading",
|
|
26118
|
+
className: "h-full w-full border-2 border-gray-100 rounded-md flex justify-center items-center",
|
|
26119
|
+
children: /* @__PURE__ */ u$2("div", { className: "loading loading-spinner loading-md text-neutral-500" })
|
|
26120
|
+
}
|
|
26121
|
+
);
|
|
26122
|
+
};
|
|
25880
26123
|
const min = Math.min;
|
|
25881
26124
|
const max = Math.max;
|
|
25882
26125
|
const round = Math.round;
|
|
@@ -27188,8 +27431,8 @@ const Dropdown = ({ children, buttonTitle, placement }) => {
|
|
|
27188
27431
|
const toggle = () => {
|
|
27189
27432
|
setShowContent(!showContent);
|
|
27190
27433
|
};
|
|
27191
|
-
return /* @__PURE__ */ u$2(
|
|
27192
|
-
/* @__PURE__ */ u$2("button", { type: "button", className: "btn btn-xs whitespace-nowrap", onClick: toggle, ref: referenceRef, children: buttonTitle }),
|
|
27434
|
+
return /* @__PURE__ */ u$2(k$1, { children: [
|
|
27435
|
+
/* @__PURE__ */ u$2("button", { type: "button", className: "btn btn-xs whitespace-nowrap w-full", onClick: toggle, ref: referenceRef, children: buttonTitle }),
|
|
27193
27436
|
/* @__PURE__ */ u$2("div", { ref: floatingRef, className: `${dropdownClass} ${showContent ? "" : "hidden"}`, children })
|
|
27194
27437
|
] });
|
|
27195
27438
|
};
|
|
@@ -27198,52 +27441,294 @@ const CheckboxSelector = ({
|
|
|
27198
27441
|
label,
|
|
27199
27442
|
setItems
|
|
27200
27443
|
}) => {
|
|
27201
|
-
return /* @__PURE__ */ u$2(Dropdown, { buttonTitle: label, placement: "bottom-start", children:
|
|
27444
|
+
return /* @__PURE__ */ u$2(Dropdown, { buttonTitle: label, placement: "bottom-start", children: [
|
|
27202
27445
|
/* @__PURE__ */ u$2(
|
|
27203
|
-
"
|
|
27446
|
+
"button",
|
|
27204
27447
|
{
|
|
27205
|
-
className: "
|
|
27206
|
-
|
|
27207
|
-
|
|
27208
|
-
checked: item.checked,
|
|
27209
|
-
onChange: () => {
|
|
27210
|
-
const newItems = items.map(
|
|
27211
|
-
(item2, i3) => i3 === index2 ? { ...item2, checked: !item2.checked } : item2
|
|
27212
|
-
);
|
|
27448
|
+
className: "btn btn-xs btn-ghost",
|
|
27449
|
+
onClick: () => {
|
|
27450
|
+
const newItems = items.map((item) => ({ ...item, checked: true }));
|
|
27213
27451
|
setItems(newItems);
|
|
27214
|
-
}
|
|
27452
|
+
},
|
|
27453
|
+
children: "Select all"
|
|
27215
27454
|
}
|
|
27216
27455
|
),
|
|
27217
|
-
|
|
27218
|
-
|
|
27219
|
-
|
|
27220
|
-
|
|
27221
|
-
|
|
27222
|
-
|
|
27223
|
-
|
|
27224
|
-
|
|
27225
|
-
|
|
27226
|
-
|
|
27227
|
-
|
|
27228
|
-
|
|
27229
|
-
|
|
27230
|
-
|
|
27231
|
-
|
|
27456
|
+
/* @__PURE__ */ u$2(
|
|
27457
|
+
"button",
|
|
27458
|
+
{
|
|
27459
|
+
className: "btn btn-xs btn-ghost",
|
|
27460
|
+
onClick: () => {
|
|
27461
|
+
const newItems = items.map((item) => ({ ...item, checked: false }));
|
|
27462
|
+
setItems(newItems);
|
|
27463
|
+
},
|
|
27464
|
+
children: "Select none"
|
|
27465
|
+
}
|
|
27466
|
+
),
|
|
27467
|
+
/* @__PURE__ */ u$2("div", { className: "divider mt-0 mb-0" }),
|
|
27468
|
+
/* @__PURE__ */ u$2("ul", { children: items.map((item, index2) => /* @__PURE__ */ u$2("li", { className: "flex flex-row items-center", children: /* @__PURE__ */ u$2("label", { children: [
|
|
27469
|
+
/* @__PURE__ */ u$2(
|
|
27470
|
+
"input",
|
|
27471
|
+
{
|
|
27472
|
+
className: "mr-2",
|
|
27473
|
+
type: "checkbox",
|
|
27474
|
+
id: `item-${index2}`,
|
|
27475
|
+
checked: item.checked,
|
|
27476
|
+
onChange: () => {
|
|
27477
|
+
const newItems = items.map(
|
|
27478
|
+
(item2, i3) => i3 === index2 ? { ...item2, checked: !item2.checked } : item2
|
|
27479
|
+
);
|
|
27480
|
+
setItems(newItems);
|
|
27481
|
+
}
|
|
27482
|
+
}
|
|
27483
|
+
),
|
|
27484
|
+
item.label
|
|
27485
|
+
] }) }, item.label)) })
|
|
27486
|
+
] });
|
|
27487
|
+
};
|
|
27488
|
+
const MutationTypeSelector = ({
|
|
27489
|
+
displayedMutationTypes,
|
|
27490
|
+
setDisplayedMutationTypes
|
|
27491
|
+
}) => {
|
|
27492
|
+
return /* @__PURE__ */ u$2("div", { className: "w-[6rem]", children: /* @__PURE__ */ u$2(
|
|
27493
|
+
CheckboxSelector,
|
|
27494
|
+
{
|
|
27495
|
+
items: displayedMutationTypes,
|
|
27496
|
+
label: getMutationTypesSelectorLabel(displayedMutationTypes),
|
|
27497
|
+
setItems: (items) => setDisplayedMutationTypes(items)
|
|
27498
|
+
}
|
|
27499
|
+
) });
|
|
27500
|
+
};
|
|
27501
|
+
const getMutationTypesSelectorLabel = (displayedMutationTypes) => {
|
|
27502
|
+
const checkedLabels = displayedMutationTypes.filter((displayedMutationType) => displayedMutationType.checked);
|
|
27503
|
+
if (checkedLabels.length === 0) {
|
|
27504
|
+
return `No types`;
|
|
27505
|
+
}
|
|
27506
|
+
if (displayedMutationTypes.length === checkedLabels.length) {
|
|
27507
|
+
return displayedMutationTypes.map((type) => {
|
|
27508
|
+
switch (type.type) {
|
|
27509
|
+
case "substitution":
|
|
27510
|
+
return "Subst.";
|
|
27511
|
+
case "deletion":
|
|
27512
|
+
return "Del.";
|
|
27513
|
+
}
|
|
27514
|
+
}).join(", ");
|
|
27515
|
+
}
|
|
27516
|
+
return checkedLabels.map((type) => {
|
|
27517
|
+
return type.label;
|
|
27518
|
+
}).join(", ");
|
|
27519
|
+
};
|
|
27520
|
+
const NoDataDisplay = () => {
|
|
27521
|
+
return /* @__PURE__ */ u$2("div", { className: "h-full w-full rounded-md border-2 border-gray-100 p-2 flex items-center justify-center", children: /* @__PURE__ */ u$2("div", { children: "No data available." }) });
|
|
27522
|
+
};
|
|
27523
|
+
const MinMaxRangeSlider = ({
|
|
27524
|
+
min: min2,
|
|
27525
|
+
max: max2,
|
|
27526
|
+
setMin,
|
|
27527
|
+
setMax,
|
|
27528
|
+
rangeMin = 0,
|
|
27529
|
+
rangeMax = 100,
|
|
27530
|
+
step = 0.1
|
|
27531
|
+
}) => {
|
|
27532
|
+
const sliderColor = "#C6C6C6";
|
|
27533
|
+
const rangeColor = "#387bbe";
|
|
27534
|
+
const [zIndexTo, setZIndexTo] = h$1(0);
|
|
27535
|
+
const onMinChange = (event) => {
|
|
27536
|
+
const input = event.target;
|
|
27537
|
+
const minValue = Number(input.value);
|
|
27538
|
+
if (minValue > max2) {
|
|
27539
|
+
setMax(minValue);
|
|
27540
|
+
setMin(minValue);
|
|
27541
|
+
} else {
|
|
27542
|
+
setMin(minValue);
|
|
27543
|
+
}
|
|
27544
|
+
};
|
|
27545
|
+
const onMaxChange = (event) => {
|
|
27546
|
+
const input = event.target;
|
|
27547
|
+
const maxValue = Number(input.value);
|
|
27548
|
+
if (maxValue <= 0) {
|
|
27549
|
+
setZIndexTo(2);
|
|
27550
|
+
} else {
|
|
27551
|
+
setZIndexTo(0);
|
|
27552
|
+
}
|
|
27553
|
+
if (maxValue < min2) {
|
|
27554
|
+
setMin(maxValue);
|
|
27555
|
+
setMax(maxValue);
|
|
27556
|
+
} else {
|
|
27557
|
+
setMax(maxValue);
|
|
27558
|
+
}
|
|
27559
|
+
};
|
|
27560
|
+
const background = `
|
|
27561
|
+
linear-gradient(
|
|
27562
|
+
to right,
|
|
27563
|
+
${sliderColor} 0%,
|
|
27564
|
+
${sliderColor} ${min2}%,
|
|
27565
|
+
${rangeColor} ${min2}%,
|
|
27566
|
+
${rangeColor} ${max2}%,
|
|
27567
|
+
${sliderColor} ${max2}%,
|
|
27568
|
+
${sliderColor} 100%)
|
|
27569
|
+
`;
|
|
27570
|
+
return /* @__PURE__ */ u$2("div", { class: "my-4 relative w-full h-full", children: [
|
|
27571
|
+
/* @__PURE__ */ u$2(
|
|
27572
|
+
"input",
|
|
27573
|
+
{
|
|
27574
|
+
id: "fromSlider",
|
|
27575
|
+
type: "range",
|
|
27576
|
+
value: min2,
|
|
27577
|
+
onInput: onMinChange,
|
|
27578
|
+
min: rangeMin,
|
|
27579
|
+
max: rangeMax,
|
|
27580
|
+
step,
|
|
27581
|
+
style: { background, zIndex: 1, height: 0 }
|
|
27582
|
+
}
|
|
27583
|
+
),
|
|
27584
|
+
/* @__PURE__ */ u$2(
|
|
27585
|
+
"input",
|
|
27586
|
+
{
|
|
27587
|
+
id: "toSlider",
|
|
27588
|
+
type: "range",
|
|
27589
|
+
value: max2,
|
|
27590
|
+
min: rangeMin,
|
|
27591
|
+
max: rangeMax,
|
|
27592
|
+
step,
|
|
27593
|
+
onInput: onMaxChange,
|
|
27594
|
+
style: { background, zIndex: zIndexTo }
|
|
27595
|
+
}
|
|
27596
|
+
)
|
|
27597
|
+
] });
|
|
27598
|
+
};
|
|
27599
|
+
const percentageInRange = (percentage) => {
|
|
27600
|
+
return percentage <= 100 && percentage >= 0;
|
|
27601
|
+
};
|
|
27602
|
+
const PercentInput = ({ percentage, setPercentage }) => {
|
|
27603
|
+
const [internalPercentage, setInternalPercentage] = h$1(percentage);
|
|
27604
|
+
y$1(() => {
|
|
27605
|
+
setInternalPercentage(percentage);
|
|
27606
|
+
}, [percentage]);
|
|
27607
|
+
const handleInputChange = (event) => {
|
|
27608
|
+
const input = event.target;
|
|
27609
|
+
const value = Number(input.value);
|
|
27610
|
+
if (value === internalPercentage || input.value === "") {
|
|
27611
|
+
return;
|
|
27612
|
+
}
|
|
27613
|
+
const inRange2 = percentageInRange(value);
|
|
27614
|
+
if (inRange2) {
|
|
27615
|
+
setPercentage(value);
|
|
27616
|
+
}
|
|
27617
|
+
setInternalPercentage(value);
|
|
27618
|
+
};
|
|
27619
|
+
const isError = !percentageInRange(internalPercentage);
|
|
27620
|
+
return /* @__PURE__ */ u$2("label", { className: `input input-bordered flex items-center gap-2 w-32 ${isError ? "input-error" : ""}`, children: [
|
|
27621
|
+
/* @__PURE__ */ u$2(
|
|
27622
|
+
"input",
|
|
27623
|
+
{
|
|
27624
|
+
type: "number",
|
|
27625
|
+
step: 0.1,
|
|
27626
|
+
min: 0,
|
|
27627
|
+
max: 100,
|
|
27628
|
+
value: internalPercentage,
|
|
27629
|
+
onInput: handleInputChange,
|
|
27630
|
+
lang: "en",
|
|
27631
|
+
className: `grow w-16`
|
|
27632
|
+
}
|
|
27633
|
+
),
|
|
27634
|
+
"%"
|
|
27635
|
+
] });
|
|
27636
|
+
};
|
|
27637
|
+
function useUpdateExternalValueInIntervals(setExternalValue, updateIntervalInMs, internalValue) {
|
|
27638
|
+
const hasMounted = A$1(false);
|
|
27639
|
+
y$1(() => {
|
|
27640
|
+
if (!hasMounted.current) {
|
|
27641
|
+
hasMounted.current = true;
|
|
27642
|
+
return;
|
|
27643
|
+
}
|
|
27644
|
+
const minTimeout = setTimeout(() => {
|
|
27645
|
+
setExternalValue(internalValue);
|
|
27646
|
+
}, updateIntervalInMs);
|
|
27647
|
+
return () => clearTimeout(minTimeout);
|
|
27648
|
+
}, [internalValue]);
|
|
27649
|
+
}
|
|
27650
|
+
const ProportionSelector = ({
|
|
27651
|
+
proportionInterval,
|
|
27652
|
+
setMinProportion,
|
|
27653
|
+
setMaxProportion
|
|
27654
|
+
}) => {
|
|
27655
|
+
const updateIntervalInMs = 300;
|
|
27656
|
+
const { min: minProportion, max: maxProportion } = proportionInterval;
|
|
27657
|
+
const [internalMinProportion, setInternalMinProportion] = h$1(minProportion);
|
|
27658
|
+
const [internalMaxProportion, setInternalMaxProportion] = h$1(maxProportion);
|
|
27659
|
+
useUpdateExternalValueInIntervals(setMinProportion, updateIntervalInMs, internalMinProportion);
|
|
27660
|
+
const updateMinPercentage = (minPercentage) => {
|
|
27661
|
+
const newMinProportion = minPercentage / 100;
|
|
27662
|
+
setInternalMinProportion(newMinProportion);
|
|
27663
|
+
};
|
|
27664
|
+
useUpdateExternalValueInIntervals(setMaxProportion, updateIntervalInMs, internalMaxProportion);
|
|
27665
|
+
const updateMaxPercentage = (maxPercentage) => {
|
|
27666
|
+
const newMaxProportion = maxPercentage / 100;
|
|
27667
|
+
setInternalMaxProportion(newMaxProportion);
|
|
27668
|
+
};
|
|
27669
|
+
return /* @__PURE__ */ u$2("div", { class: "flex flex-col w-64 mb-2", children: [
|
|
27670
|
+
/* @__PURE__ */ u$2("div", { class: "flex items-center ", children: [
|
|
27671
|
+
/* @__PURE__ */ u$2(PercentInput, { percentage: internalMinProportion * 100, setPercentage: updateMinPercentage }),
|
|
27672
|
+
/* @__PURE__ */ u$2("div", { class: "m-2", children: "-" }),
|
|
27673
|
+
/* @__PURE__ */ u$2(PercentInput, { percentage: internalMaxProportion * 100, setPercentage: updateMaxPercentage })
|
|
27674
|
+
] }),
|
|
27675
|
+
/* @__PURE__ */ u$2("div", { class: "my-1", children: /* @__PURE__ */ u$2(
|
|
27676
|
+
MinMaxRangeSlider,
|
|
27677
|
+
{
|
|
27678
|
+
min: internalMinProportion * 100,
|
|
27679
|
+
max: internalMaxProportion * 100,
|
|
27680
|
+
setMin: updateMinPercentage,
|
|
27681
|
+
setMax: updateMaxPercentage
|
|
27682
|
+
}
|
|
27683
|
+
) })
|
|
27684
|
+
] });
|
|
27685
|
+
};
|
|
27686
|
+
const ProportionSelectorDropdown = ({
|
|
27687
|
+
proportionInterval,
|
|
27688
|
+
setMinProportion,
|
|
27689
|
+
setMaxProportion
|
|
27690
|
+
}) => {
|
|
27691
|
+
const label = `${(proportionInterval.min * 100).toFixed(1)}% - ${(proportionInterval.max * 100).toFixed(1)}%`;
|
|
27692
|
+
return /* @__PURE__ */ u$2("div", { className: "w-44", children: /* @__PURE__ */ u$2(Dropdown, { buttonTitle: `Proportion ${label}`, placement: "bottom-start", children: /* @__PURE__ */ u$2(
|
|
27693
|
+
ProportionSelector,
|
|
27694
|
+
{
|
|
27695
|
+
proportionInterval,
|
|
27696
|
+
setMinProportion,
|
|
27697
|
+
setMaxProportion
|
|
27698
|
+
}
|
|
27699
|
+
) }) });
|
|
27700
|
+
};
|
|
27701
|
+
const ReferenceGenomeContext = G$1({ nucleotideSequences: [], genes: [] });
|
|
27702
|
+
const SegmentSelector = ({
|
|
27232
27703
|
displayedSegments,
|
|
27233
|
-
setDisplayedSegments
|
|
27234
|
-
prefix
|
|
27704
|
+
setDisplayedSegments
|
|
27235
27705
|
}) => {
|
|
27236
27706
|
if (displayedSegments.length <= 1) {
|
|
27237
27707
|
return null;
|
|
27238
27708
|
}
|
|
27239
|
-
return /* @__PURE__ */ u$2(
|
|
27709
|
+
return /* @__PURE__ */ u$2("div", { className: "w-24", children: /* @__PURE__ */ u$2(
|
|
27240
27710
|
CheckboxSelector,
|
|
27241
27711
|
{
|
|
27242
27712
|
items: displayedSegments,
|
|
27243
|
-
label: getSegmentSelectorLabel(displayedSegments
|
|
27713
|
+
label: getSegmentSelectorLabel(displayedSegments),
|
|
27244
27714
|
setItems: (items) => setDisplayedSegments(items)
|
|
27245
27715
|
}
|
|
27246
|
-
);
|
|
27716
|
+
) });
|
|
27717
|
+
};
|
|
27718
|
+
const getSegmentSelectorLabel = (displayedSegments) => {
|
|
27719
|
+
const allSelectedSelected = displayedSegments.filter((segment) => segment.checked).map((segment) => segment.segment);
|
|
27720
|
+
if (allSelectedSelected.length === 0) {
|
|
27721
|
+
return `No segments`;
|
|
27722
|
+
}
|
|
27723
|
+
if (displayedSegments.length === allSelectedSelected.length) {
|
|
27724
|
+
return `All segments`;
|
|
27725
|
+
}
|
|
27726
|
+
const longestDisplayString = `All segments`;
|
|
27727
|
+
const allSelectedSelectedString = allSelectedSelected.join(", ");
|
|
27728
|
+
if (longestDisplayString.length >= allSelectedSelectedString.length) {
|
|
27729
|
+
return allSelectedSelectedString;
|
|
27730
|
+
}
|
|
27731
|
+
return `${allSelectedSelected.length} ${allSelectedSelected.length === 1 ? "segment" : "segments"}`;
|
|
27247
27732
|
};
|
|
27248
27733
|
function useDisplayedSegments(sequenceType) {
|
|
27249
27734
|
const referenceGenome = x$1(ReferenceGenomeContext);
|
|
@@ -27254,517 +27739,102 @@ function useDisplayedSegments(sequenceType) {
|
|
|
27254
27739
|
}));
|
|
27255
27740
|
return h$1(displayedSegments);
|
|
27256
27741
|
}
|
|
27257
|
-
const
|
|
27258
|
-
|
|
27259
|
-
|
|
27260
|
-
|
|
27261
|
-
|
|
27262
|
-
|
|
27263
|
-
|
|
27264
|
-
|
|
27265
|
-
|
|
27266
|
-
const url = URL.createObjectURL(blob);
|
|
27267
|
-
const a2 = document.createElement("a");
|
|
27268
|
-
a2.href = url;
|
|
27269
|
-
a2.download = filename;
|
|
27270
|
-
a2.click();
|
|
27271
|
-
URL.revokeObjectURL(url);
|
|
27272
|
-
};
|
|
27273
|
-
const getDownloadContent = () => {
|
|
27274
|
-
const data = getData();
|
|
27275
|
-
const keys = getDataKeys(data);
|
|
27276
|
-
const header = `${keys.join(",")}
|
|
27277
|
-
`;
|
|
27278
|
-
const rows = data.map((row) => keys.map((key) => row[key]).join(",")).join("\n");
|
|
27279
|
-
return header + rows;
|
|
27280
|
-
};
|
|
27281
|
-
const getDataKeys = (data) => {
|
|
27282
|
-
const keysSet = data.map((row) => Object.keys(row)).reduce((accumulatedKeys, keys) => {
|
|
27283
|
-
keys.forEach((key) => accumulatedKeys.add(key));
|
|
27284
|
-
return accumulatedKeys;
|
|
27285
|
-
}, /* @__PURE__ */ new Set());
|
|
27286
|
-
return [...keysSet];
|
|
27742
|
+
const Tabs = ({ tabs, toolbar }) => {
|
|
27743
|
+
const [activeTab, setActiveTab] = h$1(tabs[0].title);
|
|
27744
|
+
const [heightOfTabs, setHeightOfTabs] = h$1("3rem");
|
|
27745
|
+
const tabRef = A$1(null);
|
|
27746
|
+
const updateHeightOfTabs = () => {
|
|
27747
|
+
if (tabRef.current) {
|
|
27748
|
+
const heightOfTabs2 = tabRef.current.getBoundingClientRect().height;
|
|
27749
|
+
setHeightOfTabs(`${heightOfTabs2}px`);
|
|
27750
|
+
}
|
|
27287
27751
|
};
|
|
27288
|
-
return /* @__PURE__ */ u$2("button", { className, onClick: download, children: label });
|
|
27289
|
-
};
|
|
27290
|
-
class UserFacingError extends Error {
|
|
27291
|
-
constructor(headline, message) {
|
|
27292
|
-
super(message);
|
|
27293
|
-
this.headline = headline;
|
|
27294
|
-
this.name = "UserFacingError";
|
|
27295
|
-
}
|
|
27296
|
-
}
|
|
27297
|
-
const ErrorDisplay = ({ error }) => {
|
|
27298
|
-
console.error(error);
|
|
27299
|
-
const ref = A$1(null);
|
|
27300
|
-
return /* @__PURE__ */ u$2("div", { className: "h-full w-full rounded-md border-2 border-gray-100 p-2 flex items-center justify-center flex-col", children: [
|
|
27301
|
-
/* @__PURE__ */ u$2("div", { className: "text-red-700 font-bold", children: "Error" }),
|
|
27302
|
-
/* @__PURE__ */ u$2("div", { children: [
|
|
27303
|
-
"Oops! Something went wrong.",
|
|
27304
|
-
error instanceof UserFacingError && /* @__PURE__ */ u$2(k$1, { children: [
|
|
27305
|
-
" ",
|
|
27306
|
-
/* @__PURE__ */ u$2(
|
|
27307
|
-
"button",
|
|
27308
|
-
{
|
|
27309
|
-
className: "text-sm text-gray-600 hover:text-gray-300",
|
|
27310
|
-
onClick: () => {
|
|
27311
|
-
var _a2;
|
|
27312
|
-
return (_a2 = ref.current) == null ? void 0 : _a2.showModal();
|
|
27313
|
-
},
|
|
27314
|
-
children: "Show details."
|
|
27315
|
-
}
|
|
27316
|
-
),
|
|
27317
|
-
/* @__PURE__ */ u$2("dialog", { ref, class: "modal", children: [
|
|
27318
|
-
/* @__PURE__ */ u$2("div", { class: "modal-box", children: [
|
|
27319
|
-
/* @__PURE__ */ u$2("form", { method: "dialog", children: /* @__PURE__ */ u$2("button", { className: "btn btn-sm btn-circle btn-ghost absolute right-2 top-2", children: "✕" }) }),
|
|
27320
|
-
/* @__PURE__ */ u$2("h1", { class: "text-lg", children: error.headline }),
|
|
27321
|
-
/* @__PURE__ */ u$2("p", { class: "py-4", children: error.message })
|
|
27322
|
-
] }),
|
|
27323
|
-
/* @__PURE__ */ u$2("form", { method: "dialog", class: "modal-backdrop", children: /* @__PURE__ */ u$2("button", { children: "close" }) })
|
|
27324
|
-
] })
|
|
27325
|
-
] })
|
|
27326
|
-
] })
|
|
27327
|
-
] });
|
|
27328
|
-
};
|
|
27329
|
-
const ResizeContainer = ({ children, size }) => {
|
|
27330
|
-
return /* @__PURE__ */ u$2("div", { style: size, className: "bg-white", children });
|
|
27331
|
-
};
|
|
27332
|
-
const ErrorBoundary = ({ size, children }) => {
|
|
27333
|
-
const [internalError] = b$1();
|
|
27334
|
-
if (internalError) {
|
|
27335
|
-
return /* @__PURE__ */ u$2(ResizeContainer, { size, children: /* @__PURE__ */ u$2(ErrorDisplay, { error: internalError }) });
|
|
27336
|
-
}
|
|
27337
|
-
return /* @__PURE__ */ u$2(k$1, { children });
|
|
27338
|
-
};
|
|
27339
|
-
const Fullscreen = () => {
|
|
27340
|
-
const element = A$1(null);
|
|
27341
|
-
const isFullscreen = useFullscreenStatus();
|
|
27342
|
-
return /* @__PURE__ */ u$2(
|
|
27343
|
-
"button",
|
|
27344
|
-
{
|
|
27345
|
-
ref: element,
|
|
27346
|
-
onClick: async () => {
|
|
27347
|
-
if (element.current) {
|
|
27348
|
-
if (isFullscreen) {
|
|
27349
|
-
await document.exitFullscreen();
|
|
27350
|
-
} else {
|
|
27351
|
-
const componentRoot = findComponentRoot(element.current);
|
|
27352
|
-
if (componentRoot) {
|
|
27353
|
-
await componentRoot.requestFullscreen();
|
|
27354
|
-
}
|
|
27355
|
-
}
|
|
27356
|
-
}
|
|
27357
|
-
},
|
|
27358
|
-
className: `mt-0.5 iconify text-2xl ${isFullscreen ? "mdi--fullscreen-exit hover:scale-90" : "mdi--fullscreen hover:scale-110"}`,
|
|
27359
|
-
title: isFullscreen ? "Exit fullscreen" : "Enter fullscreen"
|
|
27360
|
-
}
|
|
27361
|
-
);
|
|
27362
|
-
};
|
|
27363
|
-
function findComponentRoot(element) {
|
|
27364
|
-
var _a2;
|
|
27365
|
-
return (_a2 = findShadowRoot(element)) == null ? void 0 : _a2.children[0];
|
|
27366
|
-
}
|
|
27367
|
-
function findShadowRoot(element) {
|
|
27368
|
-
let current = element;
|
|
27369
|
-
while (current) {
|
|
27370
|
-
if (current instanceof ShadowRoot) {
|
|
27371
|
-
return current;
|
|
27372
|
-
}
|
|
27373
|
-
if (current.parentNode === null) {
|
|
27374
|
-
return null;
|
|
27375
|
-
}
|
|
27376
|
-
current = current.parentNode;
|
|
27377
|
-
}
|
|
27378
|
-
return null;
|
|
27379
|
-
}
|
|
27380
|
-
function useFullscreenStatus() {
|
|
27381
|
-
const [isFullscreen, setIsFullscreen] = h$1(document.fullscreenElement !== null);
|
|
27382
27752
|
y$1(() => {
|
|
27383
|
-
|
|
27384
|
-
|
|
27385
|
-
};
|
|
27386
|
-
document.addEventListener("fullscreenchange", handleFullscreenChange);
|
|
27753
|
+
updateHeightOfTabs();
|
|
27754
|
+
window.addEventListener("resize", updateHeightOfTabs);
|
|
27387
27755
|
return () => {
|
|
27388
|
-
|
|
27756
|
+
window.removeEventListener("resize", updateHeightOfTabs);
|
|
27389
27757
|
};
|
|
27390
27758
|
}, []);
|
|
27391
|
-
|
|
27392
|
-
|
|
27393
|
-
|
|
27394
|
-
|
|
27395
|
-
|
|
27396
|
-
|
|
27397
|
-
|
|
27398
|
-
|
|
27399
|
-
|
|
27400
|
-
|
|
27401
|
-
|
|
27402
|
-
|
|
27403
|
-
|
|
27404
|
-
|
|
27405
|
-
|
|
27406
|
-
|
|
27407
|
-
/* @__PURE__ */ u$2("
|
|
27408
|
-
] })
|
|
27409
|
-
] });
|
|
27410
|
-
};
|
|
27411
|
-
const InfoHeadline1 = ({ children }) => {
|
|
27412
|
-
return /* @__PURE__ */ u$2("h1", { className: "text-lg font-bold", children });
|
|
27413
|
-
};
|
|
27414
|
-
const InfoHeadline2 = ({ children }) => {
|
|
27415
|
-
return /* @__PURE__ */ u$2("h2", { className: "text-base font-bold mt-4", children });
|
|
27416
|
-
};
|
|
27417
|
-
const InfoParagraph = ({ children }) => {
|
|
27418
|
-
return /* @__PURE__ */ u$2("p", { className: "text-justify my-1", children });
|
|
27419
|
-
};
|
|
27420
|
-
const InfoLink = ({ children, href }) => {
|
|
27421
|
-
return /* @__PURE__ */ u$2("a", { className: "text-blue-600 hover:text-blue-800", href, target: "_blank", rel: "noopener noreferrer", children });
|
|
27422
|
-
};
|
|
27423
|
-
const InfoComponentCode = ({ componentName, params, lapisUrl }) => {
|
|
27424
|
-
const componentCode = componentParametersToCode(componentName, params, lapisUrl);
|
|
27425
|
-
const codePenData = {
|
|
27426
|
-
title: "GenSpectrum dashboard component",
|
|
27427
|
-
html: generateFullExampleCode(componentCode, componentName),
|
|
27428
|
-
layout: "left",
|
|
27429
|
-
editors: "100"
|
|
27430
|
-
};
|
|
27431
|
-
return /* @__PURE__ */ u$2(k$1, { children: [
|
|
27432
|
-
/* @__PURE__ */ u$2(InfoHeadline2, { children: "Use this component yourself" }),
|
|
27433
|
-
/* @__PURE__ */ u$2(InfoParagraph, { children: [
|
|
27434
|
-
"This component was created using the following parameters:",
|
|
27435
|
-
/* @__PURE__ */ u$2("div", { className: "p-4 border border-gray-200 rounded-lg overflow-x-auto", children: /* @__PURE__ */ u$2("pre", { children: /* @__PURE__ */ u$2("code", { children: componentCode }) }) })
|
|
27436
|
-
] }),
|
|
27437
|
-
/* @__PURE__ */ u$2(InfoParagraph, { children: [
|
|
27438
|
-
"You can add this component to your own website using the",
|
|
27439
|
-
" ",
|
|
27440
|
-
/* @__PURE__ */ u$2(InfoLink, { href: "https://github.com/GenSpectrum/dashboard-components", children: "GenSpectrum dashboard components library" }),
|
|
27441
|
-
" ",
|
|
27442
|
-
"and the code from above."
|
|
27759
|
+
const tabElements = /* @__PURE__ */ u$2("div", { className: "flex flex-row", children: tabs.map((tab) => {
|
|
27760
|
+
return /* @__PURE__ */ u$2(k$1, { children: /* @__PURE__ */ u$2(
|
|
27761
|
+
"button",
|
|
27762
|
+
{
|
|
27763
|
+
className: `px-4 py-2 text-sm font-medium leading-5 transition-colors duration-150 ${activeTab === tab.title ? "border-b-2 border-gray-400" : "text-gray-600 hover:bg-gray-100 hover:text-gray-700"}`,
|
|
27764
|
+
onClick: () => {
|
|
27765
|
+
setActiveTab(tab.title);
|
|
27766
|
+
},
|
|
27767
|
+
children: tab.title
|
|
27768
|
+
}
|
|
27769
|
+
) }, tab.title);
|
|
27770
|
+
}) });
|
|
27771
|
+
const toolbarElement = typeof toolbar === "function" ? toolbar(activeTab) : toolbar;
|
|
27772
|
+
return /* @__PURE__ */ u$2("div", { className: "h-full w-full", children: [
|
|
27773
|
+
/* @__PURE__ */ u$2("div", { ref: tabRef, className: "flex flex-row justify-between flex-wrap", children: [
|
|
27774
|
+
tabElements,
|
|
27775
|
+
toolbar && /* @__PURE__ */ u$2("div", { className: "py-2 flex flex-wrap gap-y-1", children: toolbarElement })
|
|
27443
27776
|
] }),
|
|
27444
|
-
/* @__PURE__ */ u$2(
|
|
27445
|
-
|
|
27446
|
-
|
|
27447
|
-
{
|
|
27448
|
-
|
|
27449
|
-
|
|
27450
|
-
|
|
27451
|
-
|
|
27452
|
-
),
|
|
27453
|
-
/* @__PURE__ */ u$2("button", { className: "text-blue-600 hover:text-blue-800", type: "submit", children: "Click here to try it out on CodePen." })
|
|
27454
|
-
] }) })
|
|
27777
|
+
/* @__PURE__ */ u$2(
|
|
27778
|
+
"div",
|
|
27779
|
+
{
|
|
27780
|
+
className: `p-2 border-2 border-gray-100 rounded-b-md rounded-tr-md ${activeTab === tabs[0].title ? "" : "rounded-tl-md"}`,
|
|
27781
|
+
style: { height: `calc(100% - ${heightOfTabs})` },
|
|
27782
|
+
children: tabs.map((tab) => /* @__PURE__ */ u$2("div", { className: "h-full overflow-auto", hidden: activeTab !== tab.title, children: tab.content }, tab.title))
|
|
27783
|
+
}
|
|
27784
|
+
)
|
|
27455
27785
|
] });
|
|
27456
27786
|
};
|
|
27457
|
-
function
|
|
27458
|
-
const
|
|
27459
|
-
|
|
27460
|
-
|
|
27461
|
-
|
|
27462
|
-
|
|
27463
|
-
|
|
27464
|
-
|
|
27465
|
-
|
|
27466
|
-
|
|
27467
|
-
|
|
27468
|
-
|
|
27469
|
-
|
|
27470
|
-
}
|
|
27471
|
-
|
|
27472
|
-
|
|
27473
|
-
|
|
27474
|
-
|
|
27475
|
-
|
|
27476
|
-
|
|
27477
|
-
</head>
|
|
27478
|
-
|
|
27479
|
-
<body>
|
|
27480
|
-
<!-- Component documentation: https://genspectrum.github.io/dashboard-components/?path=${storyBookPath} -->
|
|
27481
|
-
${indentLines(componentCode, 2)}
|
|
27482
|
-
</body>
|
|
27483
|
-
</html>
|
|
27484
|
-
`;
|
|
27485
|
-
}
|
|
27486
|
-
function indentLines(text, numberSpaces) {
|
|
27487
|
-
const spaces = " ".repeat(numberSpaces);
|
|
27488
|
-
return text.split("\n").map((line) => spaces + line).join("\n");
|
|
27787
|
+
function useQuery(fetchDataCallback, dependencies) {
|
|
27788
|
+
const [data, setData] = h$1(null);
|
|
27789
|
+
const [error, setError] = h$1(null);
|
|
27790
|
+
const [isLoading, setIsLoading] = h$1(true);
|
|
27791
|
+
y$1(() => {
|
|
27792
|
+
const fetchData = async () => {
|
|
27793
|
+
setIsLoading(true);
|
|
27794
|
+
try {
|
|
27795
|
+
const result = await fetchDataCallback();
|
|
27796
|
+
setData(result);
|
|
27797
|
+
setError(null);
|
|
27798
|
+
} catch (error2) {
|
|
27799
|
+
setError(error2);
|
|
27800
|
+
} finally {
|
|
27801
|
+
setIsLoading(false);
|
|
27802
|
+
}
|
|
27803
|
+
};
|
|
27804
|
+
fetchData();
|
|
27805
|
+
}, [JSON.stringify(dependencies)]);
|
|
27806
|
+
return { data, error, isLoading };
|
|
27489
27807
|
}
|
|
27490
|
-
const
|
|
27491
|
-
|
|
27808
|
+
const MutationComparison = ({ width, height, ...innerProps }) => {
|
|
27809
|
+
const size = { height, width };
|
|
27810
|
+
return /* @__PURE__ */ u$2(ErrorBoundary, { size, children: /* @__PURE__ */ u$2(ResizeContainer, { size, children: /* @__PURE__ */ u$2(MutationComparisonInner, { ...innerProps }) }) });
|
|
27492
27811
|
};
|
|
27493
|
-
const
|
|
27494
|
-
|
|
27495
|
-
|
|
27812
|
+
const MutationComparisonInner = ({
|
|
27813
|
+
lapisFilters,
|
|
27814
|
+
sequenceType,
|
|
27815
|
+
views,
|
|
27816
|
+
pageSize
|
|
27496
27817
|
}) => {
|
|
27497
|
-
const
|
|
27498
|
-
const
|
|
27818
|
+
const lapis = x$1(LapisUrlContext);
|
|
27819
|
+
const { data, error, isLoading } = useQuery(async () => {
|
|
27820
|
+
return queryMutationData(lapisFilters, sequenceType, lapis);
|
|
27821
|
+
}, [lapisFilters, sequenceType, lapis]);
|
|
27822
|
+
if (isLoading) {
|
|
27823
|
+
return /* @__PURE__ */ u$2(LoadingDisplay, {});
|
|
27824
|
+
}
|
|
27825
|
+
if (error !== null) {
|
|
27826
|
+
return /* @__PURE__ */ u$2(ErrorDisplay, { error });
|
|
27827
|
+
}
|
|
27828
|
+
if (data === null) {
|
|
27829
|
+
return /* @__PURE__ */ u$2(NoDataDisplay, {});
|
|
27830
|
+
}
|
|
27499
27831
|
return /* @__PURE__ */ u$2(
|
|
27500
|
-
|
|
27832
|
+
MutationComparisonTabs,
|
|
27501
27833
|
{
|
|
27502
|
-
|
|
27503
|
-
|
|
27504
|
-
|
|
27505
|
-
|
|
27506
|
-
);
|
|
27507
|
-
};
|
|
27508
|
-
const NoDataDisplay = () => {
|
|
27509
|
-
return /* @__PURE__ */ u$2("div", { className: "h-full w-full rounded-md border-2 border-gray-100 p-2 flex items-center justify-center", children: /* @__PURE__ */ u$2("div", { children: "No data available." }) });
|
|
27510
|
-
};
|
|
27511
|
-
const MinMaxRangeSlider = ({
|
|
27512
|
-
min: min2,
|
|
27513
|
-
max: max2,
|
|
27514
|
-
setMin,
|
|
27515
|
-
setMax,
|
|
27516
|
-
rangeMin = 0,
|
|
27517
|
-
rangeMax = 100,
|
|
27518
|
-
step = 0.1
|
|
27519
|
-
}) => {
|
|
27520
|
-
const sliderColor = "#C6C6C6";
|
|
27521
|
-
const rangeColor = "#387bbe";
|
|
27522
|
-
const [zIndexTo, setZIndexTo] = h$1(0);
|
|
27523
|
-
const onMinChange = (event) => {
|
|
27524
|
-
const input = event.target;
|
|
27525
|
-
const minValue = Number(input.value);
|
|
27526
|
-
if (minValue > max2) {
|
|
27527
|
-
setMax(minValue);
|
|
27528
|
-
setMin(minValue);
|
|
27529
|
-
} else {
|
|
27530
|
-
setMin(minValue);
|
|
27531
|
-
}
|
|
27532
|
-
};
|
|
27533
|
-
const onMaxChange = (event) => {
|
|
27534
|
-
const input = event.target;
|
|
27535
|
-
const maxValue = Number(input.value);
|
|
27536
|
-
if (maxValue <= 0) {
|
|
27537
|
-
setZIndexTo(2);
|
|
27538
|
-
} else {
|
|
27539
|
-
setZIndexTo(0);
|
|
27540
|
-
}
|
|
27541
|
-
if (maxValue < min2) {
|
|
27542
|
-
setMin(maxValue);
|
|
27543
|
-
setMax(maxValue);
|
|
27544
|
-
} else {
|
|
27545
|
-
setMax(maxValue);
|
|
27546
|
-
}
|
|
27547
|
-
};
|
|
27548
|
-
const background = `
|
|
27549
|
-
linear-gradient(
|
|
27550
|
-
to right,
|
|
27551
|
-
${sliderColor} 0%,
|
|
27552
|
-
${sliderColor} ${min2}%,
|
|
27553
|
-
${rangeColor} ${min2}%,
|
|
27554
|
-
${rangeColor} ${max2}%,
|
|
27555
|
-
${sliderColor} ${max2}%,
|
|
27556
|
-
${sliderColor} 100%)
|
|
27557
|
-
`;
|
|
27558
|
-
return /* @__PURE__ */ u$2("div", { class: "my-4 relative w-full h-full", children: [
|
|
27559
|
-
/* @__PURE__ */ u$2(
|
|
27560
|
-
"input",
|
|
27561
|
-
{
|
|
27562
|
-
id: "fromSlider",
|
|
27563
|
-
type: "range",
|
|
27564
|
-
value: min2,
|
|
27565
|
-
onInput: onMinChange,
|
|
27566
|
-
min: rangeMin,
|
|
27567
|
-
max: rangeMax,
|
|
27568
|
-
step,
|
|
27569
|
-
style: { background, zIndex: 1, height: 0 }
|
|
27570
|
-
}
|
|
27571
|
-
),
|
|
27572
|
-
/* @__PURE__ */ u$2(
|
|
27573
|
-
"input",
|
|
27574
|
-
{
|
|
27575
|
-
id: "toSlider",
|
|
27576
|
-
type: "range",
|
|
27577
|
-
value: max2,
|
|
27578
|
-
min: rangeMin,
|
|
27579
|
-
max: rangeMax,
|
|
27580
|
-
step,
|
|
27581
|
-
onInput: onMaxChange,
|
|
27582
|
-
style: { background, zIndex: zIndexTo }
|
|
27583
|
-
}
|
|
27584
|
-
)
|
|
27585
|
-
] });
|
|
27586
|
-
};
|
|
27587
|
-
const percentageInRange = (percentage) => {
|
|
27588
|
-
return percentage <= 100 && percentage >= 0;
|
|
27589
|
-
};
|
|
27590
|
-
const PercentInput = ({ percentage, setPercentage }) => {
|
|
27591
|
-
const [internalPercentage, setInternalPercentage] = h$1(percentage);
|
|
27592
|
-
y$1(() => {
|
|
27593
|
-
setInternalPercentage(percentage);
|
|
27594
|
-
}, [percentage]);
|
|
27595
|
-
const handleInputChange = (event) => {
|
|
27596
|
-
const input = event.target;
|
|
27597
|
-
const value = Number(input.value);
|
|
27598
|
-
const inRange2 = percentageInRange(value);
|
|
27599
|
-
if (inRange2) {
|
|
27600
|
-
setPercentage(value);
|
|
27601
|
-
}
|
|
27602
|
-
setInternalPercentage(value);
|
|
27603
|
-
};
|
|
27604
|
-
const isError = !percentageInRange(internalPercentage);
|
|
27605
|
-
return /* @__PURE__ */ u$2("label", { className: `input input-bordered flex items-center gap-2 w-32 ${isError ? "input-error" : ""}`, children: [
|
|
27606
|
-
/* @__PURE__ */ u$2(
|
|
27607
|
-
"input",
|
|
27608
|
-
{
|
|
27609
|
-
type: "number",
|
|
27610
|
-
step: 0.1,
|
|
27611
|
-
min: 0,
|
|
27612
|
-
max: 100,
|
|
27613
|
-
value: internalPercentage,
|
|
27614
|
-
onInput: handleInputChange,
|
|
27615
|
-
lang: "en",
|
|
27616
|
-
className: `grow w-16`
|
|
27617
|
-
}
|
|
27618
|
-
),
|
|
27619
|
-
"%"
|
|
27620
|
-
] });
|
|
27621
|
-
};
|
|
27622
|
-
const ProportionSelector = ({
|
|
27623
|
-
proportionInterval,
|
|
27624
|
-
setMinProportion,
|
|
27625
|
-
setMaxProportion
|
|
27626
|
-
}) => {
|
|
27627
|
-
const { min: minProportion, max: maxProportion } = proportionInterval;
|
|
27628
|
-
return /* @__PURE__ */ u$2("div", { class: "flex flex-col w-64 mb-2", children: [
|
|
27629
|
-
/* @__PURE__ */ u$2("div", { class: "flex items-center ", children: [
|
|
27630
|
-
/* @__PURE__ */ u$2(
|
|
27631
|
-
PercentInput,
|
|
27632
|
-
{
|
|
27633
|
-
percentage: minProportion * 100,
|
|
27634
|
-
setPercentage: (percentage) => setMinProportion(percentage / 100)
|
|
27635
|
-
}
|
|
27636
|
-
),
|
|
27637
|
-
/* @__PURE__ */ u$2("div", { class: "m-2", children: "-" }),
|
|
27638
|
-
/* @__PURE__ */ u$2(
|
|
27639
|
-
PercentInput,
|
|
27640
|
-
{
|
|
27641
|
-
percentage: maxProportion * 100,
|
|
27642
|
-
setPercentage: (percentage) => setMaxProportion(percentage / 100)
|
|
27643
|
-
}
|
|
27644
|
-
)
|
|
27645
|
-
] }),
|
|
27646
|
-
/* @__PURE__ */ u$2("div", { class: "my-1", children: /* @__PURE__ */ u$2(
|
|
27647
|
-
MinMaxRangeSlider,
|
|
27648
|
-
{
|
|
27649
|
-
min: minProportion * 100,
|
|
27650
|
-
max: maxProportion * 100,
|
|
27651
|
-
setMin: (percentage) => setMinProportion(percentage / 100),
|
|
27652
|
-
setMax: (percentage) => setMaxProportion(percentage / 100)
|
|
27653
|
-
}
|
|
27654
|
-
) })
|
|
27655
|
-
] });
|
|
27656
|
-
};
|
|
27657
|
-
const ProportionSelectorDropdown = ({
|
|
27658
|
-
proportionInterval,
|
|
27659
|
-
setMinProportion,
|
|
27660
|
-
setMaxProportion
|
|
27661
|
-
}) => {
|
|
27662
|
-
const label = `${(proportionInterval.min * 100).toFixed(1)}% - ${(proportionInterval.max * 100).toFixed(1)}%`;
|
|
27663
|
-
return /* @__PURE__ */ u$2(Dropdown, { buttonTitle: `Proportion ${label}`, placement: "bottom-start", children: /* @__PURE__ */ u$2(
|
|
27664
|
-
ProportionSelector,
|
|
27665
|
-
{
|
|
27666
|
-
proportionInterval,
|
|
27667
|
-
setMinProportion,
|
|
27668
|
-
setMaxProportion
|
|
27669
|
-
}
|
|
27670
|
-
) });
|
|
27671
|
-
};
|
|
27672
|
-
const Tabs = ({ tabs, toolbar }) => {
|
|
27673
|
-
const [activeTab, setActiveTab] = h$1(tabs[0].title);
|
|
27674
|
-
const [heightOfTabs, setHeightOfTabs] = h$1("3rem");
|
|
27675
|
-
const tabRef = A$1(null);
|
|
27676
|
-
const updateHeightOfTabs = () => {
|
|
27677
|
-
if (tabRef.current) {
|
|
27678
|
-
const heightOfTabs2 = tabRef.current.getBoundingClientRect().height;
|
|
27679
|
-
setHeightOfTabs(`${heightOfTabs2}px`);
|
|
27680
|
-
}
|
|
27681
|
-
};
|
|
27682
|
-
y$1(() => {
|
|
27683
|
-
updateHeightOfTabs();
|
|
27684
|
-
window.addEventListener("resize", updateHeightOfTabs);
|
|
27685
|
-
return () => {
|
|
27686
|
-
window.removeEventListener("resize", updateHeightOfTabs);
|
|
27687
|
-
};
|
|
27688
|
-
}, []);
|
|
27689
|
-
const tabElements = /* @__PURE__ */ u$2("div", { className: "flex flex-row", children: tabs.map((tab) => {
|
|
27690
|
-
return /* @__PURE__ */ u$2(k$1, { children: /* @__PURE__ */ u$2(
|
|
27691
|
-
"button",
|
|
27692
|
-
{
|
|
27693
|
-
className: `px-4 py-2 text-sm font-medium leading-5 transition-colors duration-150 ${activeTab === tab.title ? "border-b-2 border-gray-400" : "text-gray-600 hover:bg-gray-100 hover:text-gray-700"}`,
|
|
27694
|
-
onClick: () => {
|
|
27695
|
-
setActiveTab(tab.title);
|
|
27696
|
-
},
|
|
27697
|
-
children: tab.title
|
|
27698
|
-
}
|
|
27699
|
-
) }, tab.title);
|
|
27700
|
-
}) });
|
|
27701
|
-
const toolbarElement = typeof toolbar === "function" ? toolbar(activeTab) : toolbar;
|
|
27702
|
-
return /* @__PURE__ */ u$2("div", { className: "h-full w-full", children: [
|
|
27703
|
-
/* @__PURE__ */ u$2("div", { ref: tabRef, className: "flex flex-row justify-between flex-wrap", children: [
|
|
27704
|
-
tabElements,
|
|
27705
|
-
toolbar && /* @__PURE__ */ u$2("div", { className: "py-2 flex flex-wrap gap-y-1", children: toolbarElement })
|
|
27706
|
-
] }),
|
|
27707
|
-
/* @__PURE__ */ u$2(
|
|
27708
|
-
"div",
|
|
27709
|
-
{
|
|
27710
|
-
className: `p-2 border-2 border-gray-100 rounded-b-md rounded-tr-md ${activeTab === tabs[0].title ? "" : "rounded-tl-md"}`,
|
|
27711
|
-
style: { height: `calc(100% - ${heightOfTabs})` },
|
|
27712
|
-
children: tabs.map((tab) => /* @__PURE__ */ u$2("div", { className: "h-full overflow-auto", hidden: activeTab !== tab.title, children: tab.content }, tab.title))
|
|
27713
|
-
}
|
|
27714
|
-
)
|
|
27715
|
-
] });
|
|
27716
|
-
};
|
|
27717
|
-
function useQuery(fetchDataCallback, dependencies = []) {
|
|
27718
|
-
const [data, setData] = h$1(null);
|
|
27719
|
-
const [error, setError] = h$1(null);
|
|
27720
|
-
const [isLoading, setIsLoading] = h$1(true);
|
|
27721
|
-
y$1(() => {
|
|
27722
|
-
const fetchData = async () => {
|
|
27723
|
-
setIsLoading(true);
|
|
27724
|
-
try {
|
|
27725
|
-
const result = await fetchDataCallback();
|
|
27726
|
-
setData(result);
|
|
27727
|
-
setError(null);
|
|
27728
|
-
} catch (error2) {
|
|
27729
|
-
setError(error2);
|
|
27730
|
-
} finally {
|
|
27731
|
-
setIsLoading(false);
|
|
27732
|
-
}
|
|
27733
|
-
};
|
|
27734
|
-
fetchData();
|
|
27735
|
-
}, [JSON.stringify(dependencies)]);
|
|
27736
|
-
return { data, error, isLoading };
|
|
27737
|
-
}
|
|
27738
|
-
const MutationComparison = ({ width, height, ...innerProps }) => {
|
|
27739
|
-
const size = { height, width };
|
|
27740
|
-
return /* @__PURE__ */ u$2(ErrorBoundary, { size, children: /* @__PURE__ */ u$2(ResizeContainer, { size, children: /* @__PURE__ */ u$2(MutationComparisonInner, { ...innerProps }) }) });
|
|
27741
|
-
};
|
|
27742
|
-
const MutationComparisonInner = ({
|
|
27743
|
-
lapisFilters,
|
|
27744
|
-
sequenceType,
|
|
27745
|
-
views,
|
|
27746
|
-
pageSize
|
|
27747
|
-
}) => {
|
|
27748
|
-
const lapis = x$1(LapisUrlContext);
|
|
27749
|
-
const { data, error, isLoading } = useQuery(async () => {
|
|
27750
|
-
return queryMutationData(lapisFilters, sequenceType, lapis);
|
|
27751
|
-
}, [lapisFilters, sequenceType, lapis]);
|
|
27752
|
-
if (isLoading) {
|
|
27753
|
-
return /* @__PURE__ */ u$2(LoadingDisplay, {});
|
|
27754
|
-
}
|
|
27755
|
-
if (error !== null) {
|
|
27756
|
-
return /* @__PURE__ */ u$2(ErrorDisplay, { error });
|
|
27757
|
-
}
|
|
27758
|
-
if (data === null) {
|
|
27759
|
-
return /* @__PURE__ */ u$2(NoDataDisplay, {});
|
|
27760
|
-
}
|
|
27761
|
-
return /* @__PURE__ */ u$2(
|
|
27762
|
-
MutationComparisonTabs,
|
|
27763
|
-
{
|
|
27764
|
-
data: data.mutationData,
|
|
27765
|
-
sequenceType,
|
|
27766
|
-
views,
|
|
27767
|
-
pageSize
|
|
27834
|
+
data: data.mutationData,
|
|
27835
|
+
sequenceType,
|
|
27836
|
+
views,
|
|
27837
|
+
pageSize
|
|
27768
27838
|
}
|
|
27769
27839
|
);
|
|
27770
27840
|
};
|
|
@@ -28479,14 +28549,47 @@ html {
|
|
|
28479
28549
|
--tw-contain-paint: ;
|
|
28480
28550
|
--tw-contain-style: ;
|
|
28481
28551
|
}
|
|
28482
|
-
.
|
|
28483
|
-
display: grid;
|
|
28552
|
+
.container {
|
|
28484
28553
|
width: 100%;
|
|
28485
|
-
|
|
28486
|
-
|
|
28487
|
-
|
|
28488
|
-
|
|
28489
|
-
|
|
28554
|
+
}
|
|
28555
|
+
@media (min-width: 640px) {
|
|
28556
|
+
|
|
28557
|
+
.container {
|
|
28558
|
+
max-width: 640px;
|
|
28559
|
+
}
|
|
28560
|
+
}
|
|
28561
|
+
@media (min-width: 768px) {
|
|
28562
|
+
|
|
28563
|
+
.container {
|
|
28564
|
+
max-width: 768px;
|
|
28565
|
+
}
|
|
28566
|
+
}
|
|
28567
|
+
@media (min-width: 1024px) {
|
|
28568
|
+
|
|
28569
|
+
.container {
|
|
28570
|
+
max-width: 1024px;
|
|
28571
|
+
}
|
|
28572
|
+
}
|
|
28573
|
+
@media (min-width: 1280px) {
|
|
28574
|
+
|
|
28575
|
+
.container {
|
|
28576
|
+
max-width: 1280px;
|
|
28577
|
+
}
|
|
28578
|
+
}
|
|
28579
|
+
@media (min-width: 1536px) {
|
|
28580
|
+
|
|
28581
|
+
.container {
|
|
28582
|
+
max-width: 1536px;
|
|
28583
|
+
}
|
|
28584
|
+
}
|
|
28585
|
+
.alert {
|
|
28586
|
+
display: grid;
|
|
28587
|
+
width: 100%;
|
|
28588
|
+
grid-auto-flow: row;
|
|
28589
|
+
align-content: flex-start;
|
|
28590
|
+
align-items: center;
|
|
28591
|
+
justify-items: center;
|
|
28592
|
+
gap: 1rem;
|
|
28490
28593
|
text-align: center;
|
|
28491
28594
|
border-radius: var(--rounded-box, 1rem);
|
|
28492
28595
|
border-width: 1px;
|
|
@@ -28520,6 +28623,15 @@ html {
|
|
|
28520
28623
|
color: var(--fallback-bc,oklch(var(--bc)/var(--tw-text-opacity)));
|
|
28521
28624
|
}
|
|
28522
28625
|
|
|
28626
|
+
.menu li > *:not(ul, .menu-title, details, .btn):active,
|
|
28627
|
+
.menu li > *:not(ul, .menu-title, details, .btn).active,
|
|
28628
|
+
.menu li > details > summary:active {
|
|
28629
|
+
--tw-bg-opacity: 1;
|
|
28630
|
+
background-color: var(--fallback-n,oklch(var(--n)/var(--tw-bg-opacity)));
|
|
28631
|
+
--tw-text-opacity: 1;
|
|
28632
|
+
color: var(--fallback-nc,oklch(var(--nc)/var(--tw-text-opacity)));
|
|
28633
|
+
}
|
|
28634
|
+
|
|
28523
28635
|
.tab:hover {
|
|
28524
28636
|
--tw-text-opacity: 1;
|
|
28525
28637
|
}
|
|
@@ -28613,6 +28725,25 @@ html {
|
|
|
28613
28725
|
container-type: inline-size;
|
|
28614
28726
|
grid-template-columns: auto 1fr;
|
|
28615
28727
|
}
|
|
28728
|
+
.divider {
|
|
28729
|
+
display: flex;
|
|
28730
|
+
flex-direction: row;
|
|
28731
|
+
align-items: center;
|
|
28732
|
+
align-self: stretch;
|
|
28733
|
+
margin-top: 1rem;
|
|
28734
|
+
margin-bottom: 1rem;
|
|
28735
|
+
height: 1rem;
|
|
28736
|
+
white-space: nowrap;
|
|
28737
|
+
}
|
|
28738
|
+
.divider:before,
|
|
28739
|
+
.divider:after {
|
|
28740
|
+
height: 0.125rem;
|
|
28741
|
+
width: 100%;
|
|
28742
|
+
flex-grow: 1;
|
|
28743
|
+
--tw-content: '';
|
|
28744
|
+
content: var(--tw-content);
|
|
28745
|
+
background-color: var(--fallback-bc,oklch(var(--bc)/0.1));
|
|
28746
|
+
}
|
|
28616
28747
|
.dropdown {
|
|
28617
28748
|
position: relative;
|
|
28618
28749
|
display: inline-block;
|
|
@@ -29129,6 +29260,11 @@ input.tab:checked + .tab-content,
|
|
|
29129
29260
|
--alert-bg: var(--fallback-er,oklch(var(--er)/1));
|
|
29130
29261
|
--alert-bg-mix: var(--fallback-b1,oklch(var(--b1)/1));
|
|
29131
29262
|
}
|
|
29263
|
+
.btm-nav > *:where(.active) {
|
|
29264
|
+
border-top-width: 2px;
|
|
29265
|
+
--tw-bg-opacity: 1;
|
|
29266
|
+
background-color: var(--fallback-b1,oklch(var(--b1)/var(--tw-bg-opacity)));
|
|
29267
|
+
}
|
|
29132
29268
|
.btm-nav > *.disabled,
|
|
29133
29269
|
.btm-nav > *[disabled] {
|
|
29134
29270
|
pointer-events: none;
|
|
@@ -29281,6 +29417,9 @@ input.tab:checked + .tab-content,
|
|
|
29281
29417
|
background-position-y: 0;
|
|
29282
29418
|
}
|
|
29283
29419
|
}
|
|
29420
|
+
.divider:not(:empty) {
|
|
29421
|
+
gap: 1rem;
|
|
29422
|
+
}
|
|
29284
29423
|
.dropdown.dropdown-open .dropdown-content,
|
|
29285
29424
|
.dropdown:focus .dropdown-content,
|
|
29286
29425
|
.dropdown:focus-within .dropdown-content {
|
|
@@ -29396,6 +29535,14 @@ input.tab:checked + .tab-content,
|
|
|
29396
29535
|
outline: 2px solid transparent;
|
|
29397
29536
|
outline-offset: 2px;
|
|
29398
29537
|
}
|
|
29538
|
+
.menu li > *:not(ul, .menu-title, details, .btn):active,
|
|
29539
|
+
.menu li > *:not(ul, .menu-title, details, .btn).active,
|
|
29540
|
+
.menu li > details > summary:active {
|
|
29541
|
+
--tw-bg-opacity: 1;
|
|
29542
|
+
background-color: var(--fallback-n,oklch(var(--n)/var(--tw-bg-opacity)));
|
|
29543
|
+
--tw-text-opacity: 1;
|
|
29544
|
+
color: var(--fallback-nc,oklch(var(--nc)/var(--tw-text-opacity)));
|
|
29545
|
+
}
|
|
29399
29546
|
.mockup-phone .display {
|
|
29400
29547
|
overflow: hidden;
|
|
29401
29548
|
border-radius: 40px;
|
|
@@ -29631,30 +29778,6 @@ input.tab:checked + .tab-content,
|
|
|
29631
29778
|
background-position: calc(0% + 12px) calc(1px + 50%),
|
|
29632
29779
|
calc(0% + 16px) calc(1px + 50%);
|
|
29633
29780
|
}
|
|
29634
|
-
.skeleton {
|
|
29635
|
-
border-radius: var(--rounded-box, 1rem);
|
|
29636
|
-
--tw-bg-opacity: 1;
|
|
29637
|
-
background-color: var(--fallback-b3,oklch(var(--b3)/var(--tw-bg-opacity)));
|
|
29638
|
-
will-change: background-position;
|
|
29639
|
-
animation: skeleton 1.8s ease-in-out infinite;
|
|
29640
|
-
background-image: linear-gradient(
|
|
29641
|
-
105deg,
|
|
29642
|
-
transparent 0%,
|
|
29643
|
-
transparent 40%,
|
|
29644
|
-
var(--fallback-b1,oklch(var(--b1)/1)) 50%,
|
|
29645
|
-
transparent 60%,
|
|
29646
|
-
transparent 100%
|
|
29647
|
-
);
|
|
29648
|
-
background-size: 200% auto;
|
|
29649
|
-
background-repeat: no-repeat;
|
|
29650
|
-
background-position-x: -50%;
|
|
29651
|
-
}
|
|
29652
|
-
@media (prefers-reduced-motion) {
|
|
29653
|
-
|
|
29654
|
-
.skeleton {
|
|
29655
|
-
animation-duration: 15s;
|
|
29656
|
-
}
|
|
29657
|
-
}
|
|
29658
29781
|
@keyframes skeleton {
|
|
29659
29782
|
|
|
29660
29783
|
from {
|
|
@@ -29892,6 +30015,12 @@ input.tab:checked + .tab-content,
|
|
|
29892
30015
|
--tw-bg-opacity: 1;
|
|
29893
30016
|
background-color: var(--fallback-b2,oklch(var(--b2)/var(--tw-bg-opacity)));
|
|
29894
30017
|
}
|
|
30018
|
+
.table-zebra tr.active,
|
|
30019
|
+
.table-zebra tr.active:nth-child(even),
|
|
30020
|
+
.table-zebra-zebra tbody tr:nth-child(even) {
|
|
30021
|
+
--tw-bg-opacity: 1;
|
|
30022
|
+
background-color: var(--fallback-b3,oklch(var(--b3)/var(--tw-bg-opacity)));
|
|
30023
|
+
}
|
|
29895
30024
|
.table :where(thead tr, tbody tr:not(:last-child), tbody tr:first-child:last-child) {
|
|
29896
30025
|
border-bottom-width: 1px;
|
|
29897
30026
|
--tw-border-opacity: 1;
|
|
@@ -29964,6 +30093,18 @@ input.tab:checked + .tab-content,
|
|
|
29964
30093
|
--togglehandleborder: 0 0 0 3px var(--fallback-bc,oklch(var(--bc)/1)) inset,
|
|
29965
30094
|
var(--handleoffsetcalculator) 0 0 3px var(--fallback-bc,oklch(var(--bc)/1)) inset;
|
|
29966
30095
|
}
|
|
30096
|
+
.btm-nav-xs > *:where(.active) {
|
|
30097
|
+
border-top-width: 1px;
|
|
30098
|
+
}
|
|
30099
|
+
.btm-nav-sm > *:where(.active) {
|
|
30100
|
+
border-top-width: 2px;
|
|
30101
|
+
}
|
|
30102
|
+
.btm-nav-md > *:where(.active) {
|
|
30103
|
+
border-top-width: 2px;
|
|
30104
|
+
}
|
|
30105
|
+
.btm-nav-lg > *:where(.active) {
|
|
30106
|
+
border-top-width: 4px;
|
|
30107
|
+
}
|
|
29967
30108
|
.btn-xs {
|
|
29968
30109
|
height: 1.5rem;
|
|
29969
30110
|
min-height: 1.5rem;
|
|
@@ -30383,6 +30524,9 @@ input.tab:checked + .tab-content,
|
|
|
30383
30524
|
margin-top: 1rem;
|
|
30384
30525
|
margin-bottom: 1rem;
|
|
30385
30526
|
}
|
|
30527
|
+
.mb-0 {
|
|
30528
|
+
margin-bottom: 0px;
|
|
30529
|
+
}
|
|
30386
30530
|
.mb-1 {
|
|
30387
30531
|
margin-bottom: 0.25rem;
|
|
30388
30532
|
}
|
|
@@ -30407,6 +30551,9 @@ input.tab:checked + .tab-content,
|
|
|
30407
30551
|
.mr-2 {
|
|
30408
30552
|
margin-right: 0.5rem;
|
|
30409
30553
|
}
|
|
30554
|
+
.mt-0 {
|
|
30555
|
+
margin-top: 0px;
|
|
30556
|
+
}
|
|
30410
30557
|
.mt-0\\.5 {
|
|
30411
30558
|
margin-top: 0.125rem;
|
|
30412
30559
|
}
|
|
@@ -30446,12 +30593,24 @@ input.tab:checked + .tab-content,
|
|
|
30446
30593
|
.w-16 {
|
|
30447
30594
|
width: 4rem;
|
|
30448
30595
|
}
|
|
30596
|
+
.w-20 {
|
|
30597
|
+
width: 5rem;
|
|
30598
|
+
}
|
|
30599
|
+
.w-24 {
|
|
30600
|
+
width: 6rem;
|
|
30601
|
+
}
|
|
30449
30602
|
.w-32 {
|
|
30450
30603
|
width: 8rem;
|
|
30451
30604
|
}
|
|
30605
|
+
.w-44 {
|
|
30606
|
+
width: 11rem;
|
|
30607
|
+
}
|
|
30452
30608
|
.w-64 {
|
|
30453
30609
|
width: 16rem;
|
|
30454
30610
|
}
|
|
30611
|
+
.w-\\[6rem\\] {
|
|
30612
|
+
width: 6rem;
|
|
30613
|
+
}
|
|
30455
30614
|
.w-\\[7\\.5rem\\] {
|
|
30456
30615
|
width: 7.5rem;
|
|
30457
30616
|
}
|
|
@@ -30689,6 +30848,10 @@ input.tab:checked + .tab-content,
|
|
|
30689
30848
|
--tw-text-opacity: 1;
|
|
30690
30849
|
color: rgb(75 85 99 / var(--tw-text-opacity));
|
|
30691
30850
|
}
|
|
30851
|
+
.text-neutral-500 {
|
|
30852
|
+
--tw-text-opacity: 1;
|
|
30853
|
+
color: rgb(115 115 115 / var(--tw-text-opacity));
|
|
30854
|
+
}
|
|
30692
30855
|
.text-red-700 {
|
|
30693
30856
|
--tw-text-opacity: 1;
|
|
30694
30857
|
color: rgb(185 28 28 / var(--tw-text-opacity));
|
|
@@ -31041,7 +31204,10 @@ const MutationsGrid = ({
|
|
|
31041
31204
|
}
|
|
31042
31205
|
return {};
|
|
31043
31206
|
};
|
|
31044
|
-
const tableData =
|
|
31207
|
+
const tableData = T$1(
|
|
31208
|
+
() => getMutationsGridData(data, sequenceType, proportionInterval).map((row) => Object.values(row)),
|
|
31209
|
+
[data, proportionInterval, sequenceType]
|
|
31210
|
+
);
|
|
31045
31211
|
return /* @__PURE__ */ u$2(Table, { data: tableData, columns: getHeaders(), pageSize });
|
|
31046
31212
|
};
|
|
31047
31213
|
const sortInsertions = (a2, b3) => {
|
|
@@ -34650,7 +34816,8 @@ const NumberSequencesOverTimeInner = ({
|
|
|
34650
34816
|
}) => {
|
|
34651
34817
|
const lapis = x$1(LapisUrlContext);
|
|
34652
34818
|
const { data, error, isLoading } = useQuery(
|
|
34653
|
-
() => queryNumberOfSequencesOverTime(lapis, lapisFilter, lapisDateField, granularity, smoothingWindow)
|
|
34819
|
+
() => queryNumberOfSequencesOverTime(lapis, lapisFilter, lapisDateField, granularity, smoothingWindow),
|
|
34820
|
+
[lapis, lapisFilter, lapisDateField, granularity, smoothingWindow]
|
|
34654
34821
|
);
|
|
34655
34822
|
if (isLoading) {
|
|
34656
34823
|
return /* @__PURE__ */ u$2(LoadingDisplay, {});
|
|
@@ -34825,308 +34992,43 @@ __decorateClass$6([
|
|
|
34825
34992
|
NumberSequencesOverTimeComponent = __decorateClass$6([
|
|
34826
34993
|
t$2("gs-number-sequences-over-time")
|
|
34827
34994
|
], NumberSequencesOverTimeComponent);
|
|
34828
|
-
function
|
|
34829
|
-
|
|
34830
|
-
filterDisplayedSegments(displayedSegments, filteredData);
|
|
34831
|
-
filterMutationTypes(displayedMutationTypes, filteredData);
|
|
34832
|
-
filterProportion(filteredData, overallMutationData, proportionInterval);
|
|
34833
|
-
return filteredData;
|
|
34995
|
+
function getDefaultExportFromCjs(x2) {
|
|
34996
|
+
return x2 && x2.__esModule && Object.prototype.hasOwnProperty.call(x2, "default") ? x2["default"] : x2;
|
|
34834
34997
|
}
|
|
34835
|
-
function
|
|
34836
|
-
|
|
34837
|
-
if (!segment.checked) {
|
|
34838
|
-
data.getFirstAxisKeys().forEach((mutation) => {
|
|
34839
|
-
if (mutation.segment === segment.segment) {
|
|
34840
|
-
data.deleteRow(mutation);
|
|
34841
|
-
}
|
|
34842
|
-
});
|
|
34843
|
-
}
|
|
34844
|
-
});
|
|
34998
|
+
function commonjsRequire(path) {
|
|
34999
|
+
throw new Error('Could not dynamically require "' + path + '". Please configure the dynamicRequireTargets or/and ignoreDynamicRequires option of @rollup/plugin-commonjs appropriately for this require call to work.');
|
|
34845
35000
|
}
|
|
34846
|
-
|
|
34847
|
-
|
|
34848
|
-
|
|
34849
|
-
|
|
34850
|
-
|
|
34851
|
-
|
|
35001
|
+
var object_hash = { exports: {} };
|
|
35002
|
+
(function(module, exports) {
|
|
35003
|
+
!function(e3) {
|
|
35004
|
+
module.exports = e3();
|
|
35005
|
+
}(function() {
|
|
35006
|
+
return function r2(o2, i3, u2) {
|
|
35007
|
+
function s6(n3, e4) {
|
|
35008
|
+
if (!i3[n3]) {
|
|
35009
|
+
if (!o2[n3]) {
|
|
35010
|
+
var t2 = "function" == typeof commonjsRequire && commonjsRequire;
|
|
35011
|
+
if (!e4 && t2) return t2(n3, true);
|
|
35012
|
+
if (a2) return a2(n3, true);
|
|
35013
|
+
throw new Error("Cannot find module '" + n3 + "'");
|
|
35014
|
+
}
|
|
35015
|
+
e4 = i3[n3] = { exports: {} };
|
|
35016
|
+
o2[n3][0].call(e4.exports, function(e5) {
|
|
35017
|
+
var t3 = o2[n3][1][e5];
|
|
35018
|
+
return s6(t3 || e5);
|
|
35019
|
+
}, e4, e4.exports, r2, o2, i3, u2);
|
|
34852
35020
|
}
|
|
34853
|
-
|
|
34854
|
-
}
|
|
34855
|
-
});
|
|
34856
|
-
}
|
|
34857
|
-
function filterProportion(data, overallMutationData, proportionInterval) {
|
|
34858
|
-
const overallProportionsByMutation = overallMutationData.content.reduce(
|
|
34859
|
-
(acc, { mutation, proportion }) => ({
|
|
34860
|
-
...acc,
|
|
34861
|
-
[mutation.toString()]: proportion
|
|
34862
|
-
}),
|
|
34863
|
-
{}
|
|
34864
|
-
);
|
|
34865
|
-
data.getFirstAxisKeys().forEach((mutation) => {
|
|
34866
|
-
const overallProportion = overallProportionsByMutation[mutation.toString()] || -1;
|
|
34867
|
-
if (overallProportion < proportionInterval.min || overallProportion > proportionInterval.max) {
|
|
34868
|
-
data.deleteRow(mutation);
|
|
34869
|
-
}
|
|
34870
|
-
});
|
|
34871
|
-
}
|
|
34872
|
-
const ColorScaleSelector = ({ colorScale, setColorScale }) => {
|
|
34873
|
-
const colorDisplayCss = `w-10 h-8 border border-gray-200 mx-2 text-xs flex items-center justify-center`;
|
|
34874
|
-
return /* @__PURE__ */ u$2("div", { className: "flex items-center", children: [
|
|
34875
|
-
/* @__PURE__ */ u$2(
|
|
34876
|
-
"div",
|
|
34877
|
-
{
|
|
34878
|
-
style: {
|
|
34879
|
-
backgroundColor: singleGraphColorRGBByName(colorScale.color, 0),
|
|
34880
|
-
color: "black"
|
|
34881
|
-
},
|
|
34882
|
-
className: colorDisplayCss,
|
|
34883
|
-
children: formatProportion(colorScale.min, 0)
|
|
35021
|
+
return i3[n3].exports;
|
|
34884
35022
|
}
|
|
34885
|
-
|
|
34886
|
-
|
|
34887
|
-
|
|
34888
|
-
{
|
|
34889
|
-
|
|
34890
|
-
|
|
34891
|
-
|
|
34892
|
-
|
|
34893
|
-
|
|
34894
|
-
setMax: (percentage) => {
|
|
34895
|
-
setColorScale({ ...colorScale, max: percentage / 100 });
|
|
34896
|
-
}
|
|
34897
|
-
}
|
|
34898
|
-
) }),
|
|
34899
|
-
/* @__PURE__ */ u$2(
|
|
34900
|
-
"div",
|
|
34901
|
-
{
|
|
34902
|
-
style: {
|
|
34903
|
-
backgroundColor: singleGraphColorRGBByName(colorScale.color, 1),
|
|
34904
|
-
color: "white"
|
|
34905
|
-
},
|
|
34906
|
-
className: colorDisplayCss,
|
|
34907
|
-
children: formatProportion(colorScale.max, 0)
|
|
34908
|
-
}
|
|
34909
|
-
)
|
|
34910
|
-
] });
|
|
34911
|
-
};
|
|
34912
|
-
const getColorWithingScale = (value, colorScale) => {
|
|
34913
|
-
if (colorScale.min === colorScale.max) {
|
|
34914
|
-
return singleGraphColorRGBByName(colorScale.color, 0);
|
|
34915
|
-
}
|
|
34916
|
-
const colorRange = colorScale.max - colorScale.min;
|
|
34917
|
-
const alpha2 = (value - colorScale.min) / colorRange;
|
|
34918
|
-
return singleGraphColorRGBByName(colorScale.color, alpha2);
|
|
34919
|
-
};
|
|
34920
|
-
const getTextColorForScale = (value, colorScale) => {
|
|
34921
|
-
if (colorScale.min === colorScale.max) {
|
|
34922
|
-
return "black";
|
|
34923
|
-
}
|
|
34924
|
-
const colorRange = colorScale.max - colorScale.min;
|
|
34925
|
-
const alpha2 = (value - colorScale.min) / colorRange;
|
|
34926
|
-
return alpha2 <= 0.5 ? "black" : "white";
|
|
34927
|
-
};
|
|
34928
|
-
function getPositionCss(position) {
|
|
34929
|
-
switch (position) {
|
|
34930
|
-
case "top":
|
|
34931
|
-
return "bottom-full translate-x-[-50%] left-1/2 mb-1";
|
|
34932
|
-
case "top-start":
|
|
34933
|
-
return "bottom-full mr-1 mb-1";
|
|
34934
|
-
case "top-end":
|
|
34935
|
-
return "bottom-full right-0 ml-1 mb-1";
|
|
34936
|
-
case "bottom":
|
|
34937
|
-
return "top-full translate-x-[-50%] left-1/2 mt-1";
|
|
34938
|
-
case "bottom-start":
|
|
34939
|
-
return "mr-1 mt-1";
|
|
34940
|
-
case "bottom-end":
|
|
34941
|
-
return "right-0 ml-1 mt-1";
|
|
34942
|
-
case "left":
|
|
34943
|
-
return "right-full translate-y-[-50%] top-1/2 mr-1";
|
|
34944
|
-
case "right":
|
|
34945
|
-
return "left-full translate-y-[-50%] top-1/2 ml-1";
|
|
34946
|
-
case void 0:
|
|
34947
|
-
return "";
|
|
34948
|
-
}
|
|
34949
|
-
}
|
|
34950
|
-
const Tooltip = ({ children, content, position = "bottom" }) => {
|
|
34951
|
-
return /* @__PURE__ */ u$2("div", { className: "relative w-full h-full", children: [
|
|
34952
|
-
/* @__PURE__ */ u$2("div", { className: "peer w-full h-full", children }),
|
|
34953
|
-
/* @__PURE__ */ u$2(
|
|
34954
|
-
"div",
|
|
34955
|
-
{
|
|
34956
|
-
className: `absolute z-10 w-max bg-white p-4 border border-gray-200 rounded-md invisible peer-hover:visible ${getPositionCss(position)}`,
|
|
34957
|
-
children: content
|
|
34958
|
-
}
|
|
34959
|
-
)
|
|
34960
|
-
] });
|
|
34961
|
-
};
|
|
34962
|
-
const MAX_NUMBER_OF_GRID_ROWS = 100;
|
|
34963
|
-
const MUTATION_CELL_WIDTH_REM = 8;
|
|
34964
|
-
const MutationsOverTimeGrid = ({ data, colorScale }) => {
|
|
34965
|
-
const allMutations = data.getFirstAxisKeys().sort(sortSubstitutionsAndDeletions);
|
|
34966
|
-
const shownMutations = allMutations.slice(0, MAX_NUMBER_OF_GRID_ROWS);
|
|
34967
|
-
const dates = data.getSecondAxisKeys().sort((a2, b3) => compareTemporal(a2, b3));
|
|
34968
|
-
const [showProportionText, setShowProportionText] = h$1(false);
|
|
34969
|
-
const gridRef = A$1(null);
|
|
34970
|
-
useShowProportion(gridRef, dates.length, setShowProportionText);
|
|
34971
|
-
return /* @__PURE__ */ u$2(k$1, { children: [
|
|
34972
|
-
allMutations.length > MAX_NUMBER_OF_GRID_ROWS && /* @__PURE__ */ u$2("div", { className: "pl-2", children: [
|
|
34973
|
-
"Showing ",
|
|
34974
|
-
MAX_NUMBER_OF_GRID_ROWS,
|
|
34975
|
-
" of ",
|
|
34976
|
-
allMutations.length,
|
|
34977
|
-
" mutations. You can narrow the filter to reduce the number of mutations."
|
|
34978
|
-
] }),
|
|
34979
|
-
/* @__PURE__ */ u$2(
|
|
34980
|
-
"div",
|
|
34981
|
-
{
|
|
34982
|
-
ref: gridRef,
|
|
34983
|
-
style: {
|
|
34984
|
-
display: "grid",
|
|
34985
|
-
gridTemplateRows: `repeat(${shownMutations.length}, 24px)`,
|
|
34986
|
-
gridTemplateColumns: `${MUTATION_CELL_WIDTH_REM}rem repeat(${dates.length}, minmax(0.05rem, 1fr))`
|
|
34987
|
-
},
|
|
34988
|
-
children: shownMutations.map((mutation, rowIndex) => {
|
|
34989
|
-
return /* @__PURE__ */ u$2(k$1, { children: [
|
|
34990
|
-
/* @__PURE__ */ u$2(
|
|
34991
|
-
"div",
|
|
34992
|
-
{
|
|
34993
|
-
style: { gridRowStart: rowIndex + 1, gridColumnStart: 1 },
|
|
34994
|
-
children: /* @__PURE__ */ u$2(MutationCell, { mutation })
|
|
34995
|
-
},
|
|
34996
|
-
`mutation-${mutation.toString()}`
|
|
34997
|
-
),
|
|
34998
|
-
dates.map((date, columnIndex) => {
|
|
34999
|
-
const value = data.get(mutation, date) ?? { proportion: 0, count: 0 };
|
|
35000
|
-
const tooltipPosition = getTooltipPosition(
|
|
35001
|
-
rowIndex,
|
|
35002
|
-
shownMutations.length,
|
|
35003
|
-
columnIndex,
|
|
35004
|
-
dates.length
|
|
35005
|
-
);
|
|
35006
|
-
return /* @__PURE__ */ u$2(
|
|
35007
|
-
"div",
|
|
35008
|
-
{
|
|
35009
|
-
style: { gridRowStart: rowIndex + 1, gridColumnStart: columnIndex + 2 },
|
|
35010
|
-
children: /* @__PURE__ */ u$2(
|
|
35011
|
-
ProportionCell,
|
|
35012
|
-
{
|
|
35013
|
-
value,
|
|
35014
|
-
date,
|
|
35015
|
-
mutation,
|
|
35016
|
-
tooltipPosition,
|
|
35017
|
-
showProportionText,
|
|
35018
|
-
colorScale
|
|
35019
|
-
}
|
|
35020
|
-
)
|
|
35021
|
-
},
|
|
35022
|
-
`${mutation.toString()}-${date.toString()}`
|
|
35023
|
-
);
|
|
35024
|
-
})
|
|
35025
|
-
] }, `fragment-${mutation.toString()}`);
|
|
35026
|
-
})
|
|
35027
|
-
}
|
|
35028
|
-
)
|
|
35029
|
-
] });
|
|
35030
|
-
};
|
|
35031
|
-
function useShowProportion(gridRef, girdColumns, setShowProportionText) {
|
|
35032
|
-
y$1(() => {
|
|
35033
|
-
const checkWidth = () => {
|
|
35034
|
-
if (gridRef.current) {
|
|
35035
|
-
const width = gridRef.current.getBoundingClientRect().width;
|
|
35036
|
-
const widthPerDate = (width - remToPx(MUTATION_CELL_WIDTH_REM)) / girdColumns;
|
|
35037
|
-
const maxWidthProportionText = 28;
|
|
35038
|
-
setShowProportionText(widthPerDate > maxWidthProportionText);
|
|
35039
|
-
}
|
|
35040
|
-
};
|
|
35041
|
-
checkWidth();
|
|
35042
|
-
window.addEventListener("resize", checkWidth);
|
|
35043
|
-
return () => {
|
|
35044
|
-
window.removeEventListener("resize", checkWidth);
|
|
35045
|
-
};
|
|
35046
|
-
}, [girdColumns, gridRef, setShowProportionText]);
|
|
35047
|
-
}
|
|
35048
|
-
const remToPx = (rem) => rem * parseFloat(getComputedStyle(document.documentElement).fontSize);
|
|
35049
|
-
function getTooltipPosition(rowIndex, rows, columnIndex, columns) {
|
|
35050
|
-
const tooltipX = rowIndex < rows / 2 ? "bottom" : "top";
|
|
35051
|
-
const tooltipY = columnIndex < columns / 2 ? "start" : "end";
|
|
35052
|
-
return `${tooltipX}-${tooltipY}`;
|
|
35053
|
-
}
|
|
35054
|
-
const ProportionCell = ({ value, mutation, date, tooltipPosition, showProportionText, colorScale }) => {
|
|
35055
|
-
const tooltipContent = /* @__PURE__ */ u$2("div", { children: [
|
|
35056
|
-
/* @__PURE__ */ u$2("p", { children: /* @__PURE__ */ u$2("span", { className: "font-bold", children: date.englishName() }) }),
|
|
35057
|
-
/* @__PURE__ */ u$2("p", { children: [
|
|
35058
|
-
"(",
|
|
35059
|
-
timeIntervalDisplay(date),
|
|
35060
|
-
")"
|
|
35061
|
-
] }),
|
|
35062
|
-
/* @__PURE__ */ u$2("p", { children: mutation.code }),
|
|
35063
|
-
/* @__PURE__ */ u$2("p", { children: [
|
|
35064
|
-
"Proportion: ",
|
|
35065
|
-
formatProportion(value.proportion)
|
|
35066
|
-
] }),
|
|
35067
|
-
/* @__PURE__ */ u$2("p", { children: [
|
|
35068
|
-
"Count: ",
|
|
35069
|
-
value.count
|
|
35070
|
-
] })
|
|
35071
|
-
] });
|
|
35072
|
-
return /* @__PURE__ */ u$2("div", { className: "py-1 w-full h-full", children: /* @__PURE__ */ u$2(Tooltip, { content: tooltipContent, position: tooltipPosition, children: /* @__PURE__ */ u$2(
|
|
35073
|
-
"div",
|
|
35074
|
-
{
|
|
35075
|
-
style: {
|
|
35076
|
-
backgroundColor: getColorWithingScale(value.proportion, colorScale),
|
|
35077
|
-
color: getTextColorForScale(value.proportion, colorScale)
|
|
35078
|
-
},
|
|
35079
|
-
className: `w-full h-full text-center hover:font-bold text-xs group`,
|
|
35080
|
-
children: showProportionText ? formatProportion(value.proportion, 0) : void 0
|
|
35081
|
-
}
|
|
35082
|
-
) }) });
|
|
35083
|
-
};
|
|
35084
|
-
const timeIntervalDisplay = (date) => {
|
|
35085
|
-
if (date instanceof YearMonthDay) {
|
|
35086
|
-
return date.toString();
|
|
35087
|
-
}
|
|
35088
|
-
return `${date.firstDay.toString()} - ${date.lastDay.toString()}`;
|
|
35089
|
-
};
|
|
35090
|
-
const MutationCell = ({ mutation }) => {
|
|
35091
|
-
return /* @__PURE__ */ u$2("div", { className: "text-center", children: mutation.toString() });
|
|
35092
|
-
};
|
|
35093
|
-
function getDefaultExportFromCjs(x2) {
|
|
35094
|
-
return x2 && x2.__esModule && Object.prototype.hasOwnProperty.call(x2, "default") ? x2["default"] : x2;
|
|
35095
|
-
}
|
|
35096
|
-
function commonjsRequire(path) {
|
|
35097
|
-
throw new Error('Could not dynamically require "' + path + '". Please configure the dynamicRequireTargets or/and ignoreDynamicRequires option of @rollup/plugin-commonjs appropriately for this require call to work.');
|
|
35098
|
-
}
|
|
35099
|
-
var object_hash = { exports: {} };
|
|
35100
|
-
(function(module, exports) {
|
|
35101
|
-
!function(e3) {
|
|
35102
|
-
module.exports = e3();
|
|
35103
|
-
}(function() {
|
|
35104
|
-
return function r2(o2, i3, u2) {
|
|
35105
|
-
function s6(n3, e4) {
|
|
35106
|
-
if (!i3[n3]) {
|
|
35107
|
-
if (!o2[n3]) {
|
|
35108
|
-
var t2 = "function" == typeof commonjsRequire && commonjsRequire;
|
|
35109
|
-
if (!e4 && t2) return t2(n3, true);
|
|
35110
|
-
if (a2) return a2(n3, true);
|
|
35111
|
-
throw new Error("Cannot find module '" + n3 + "'");
|
|
35112
|
-
}
|
|
35113
|
-
e4 = i3[n3] = { exports: {} };
|
|
35114
|
-
o2[n3][0].call(e4.exports, function(e5) {
|
|
35115
|
-
var t3 = o2[n3][1][e5];
|
|
35116
|
-
return s6(t3 || e5);
|
|
35117
|
-
}, e4, e4.exports, r2, o2, i3, u2);
|
|
35118
|
-
}
|
|
35119
|
-
return i3[n3].exports;
|
|
35120
|
-
}
|
|
35121
|
-
for (var a2 = "function" == typeof commonjsRequire && commonjsRequire, e3 = 0; e3 < u2.length; e3++) s6(u2[e3]);
|
|
35122
|
-
return s6;
|
|
35123
|
-
}({ 1: [function(w2, b3, m2) {
|
|
35124
|
-
!(function(e3, n3, s6, c2, d2, h3, p2, g2, y2) {
|
|
35125
|
-
var r2 = w2("crypto");
|
|
35126
|
-
function t2(e4, t3) {
|
|
35127
|
-
t3 = u2(e4, t3);
|
|
35128
|
-
var n4;
|
|
35129
|
-
return void 0 === (n4 = "passthrough" !== t3.algorithm ? r2.createHash(t3.algorithm) : new l2()).write && (n4.write = n4.update, n4.end = n4.update), f2(t3, n4).dispatch(e4), n4.update || n4.end(""), n4.digest ? n4.digest("buffer" === t3.encoding ? void 0 : t3.encoding) : (e4 = n4.read(), "buffer" !== t3.encoding ? e4.toString(t3.encoding) : e4);
|
|
35023
|
+
for (var a2 = "function" == typeof commonjsRequire && commonjsRequire, e3 = 0; e3 < u2.length; e3++) s6(u2[e3]);
|
|
35024
|
+
return s6;
|
|
35025
|
+
}({ 1: [function(w2, b3, m2) {
|
|
35026
|
+
!(function(e3, n3, s6, c2, d2, h3, p2, g2, y2) {
|
|
35027
|
+
var r2 = w2("crypto");
|
|
35028
|
+
function t2(e4, t3) {
|
|
35029
|
+
t3 = u2(e4, t3);
|
|
35030
|
+
var n4;
|
|
35031
|
+
return void 0 === (n4 = "passthrough" !== t3.algorithm ? r2.createHash(t3.algorithm) : new l2()).write && (n4.write = n4.update, n4.end = n4.update), f2(t3, n4).dispatch(e4), n4.update || n4.end(""), n4.digest ? n4.digest("buffer" === t3.encoding ? void 0 : t3.encoding) : (e4 = n4.read(), "buffer" !== t3.encoding ? e4.toString(t3.encoding) : e4);
|
|
35130
35032
|
}
|
|
35131
35033
|
(m2 = b3.exports = t2).sha1 = function(e4) {
|
|
35132
35034
|
return t2(e4);
|
|
@@ -35881,7 +35783,7 @@ var object_hash = { exports: {} };
|
|
|
35881
35783
|
})(object_hash);
|
|
35882
35784
|
var object_hashExports = object_hash.exports;
|
|
35883
35785
|
const hash = /* @__PURE__ */ getDefaultExportFromCjs(object_hashExports);
|
|
35884
|
-
class
|
|
35786
|
+
class Map2dBase {
|
|
35885
35787
|
constructor(serializeFirstAxis = (key) => typeof key === "string" ? key : hash(key), serializeSecondAxis = (key) => typeof key === "string" ? key : hash(key)) {
|
|
35886
35788
|
this.serializeFirstAxis = serializeFirstAxis;
|
|
35887
35789
|
this.serializeSecondAxis = serializeSecondAxis;
|
|
@@ -35931,18 +35833,322 @@ class Map2d {
|
|
|
35931
35833
|
});
|
|
35932
35834
|
});
|
|
35933
35835
|
}
|
|
35934
|
-
|
|
35935
|
-
|
|
35936
|
-
|
|
35937
|
-
|
|
35938
|
-
|
|
35939
|
-
|
|
35940
|
-
|
|
35836
|
+
}
|
|
35837
|
+
class Map2dView {
|
|
35838
|
+
constructor(map2) {
|
|
35839
|
+
this.keysFirstAxis = new Map(map2.keysFirstAxis);
|
|
35840
|
+
this.keysSecondAxis = new Map(map2.keysSecondAxis);
|
|
35841
|
+
if (map2 instanceof Map2dView) {
|
|
35842
|
+
this.baseMap = map2.baseMap;
|
|
35843
|
+
}
|
|
35844
|
+
this.baseMap = map2;
|
|
35845
|
+
}
|
|
35846
|
+
serializeFirstAxis(key) {
|
|
35847
|
+
return this.baseMap.serializeFirstAxis(key);
|
|
35848
|
+
}
|
|
35849
|
+
serializeSecondAxis(key) {
|
|
35850
|
+
return this.baseMap.serializeSecondAxis(key);
|
|
35851
|
+
}
|
|
35852
|
+
deleteRow(key) {
|
|
35853
|
+
this.keysFirstAxis.delete(this.serializeFirstAxis(key));
|
|
35854
|
+
}
|
|
35855
|
+
get(keyFirstAxis, keySecondAxis) {
|
|
35856
|
+
const firstAxisKey = this.serializeFirstAxis(keyFirstAxis);
|
|
35857
|
+
const secondAxisKey = this.serializeSecondAxis(keySecondAxis);
|
|
35858
|
+
if (!this.keysFirstAxis.has(firstAxisKey) || !this.keysSecondAxis.has(secondAxisKey)) {
|
|
35859
|
+
return void 0;
|
|
35860
|
+
}
|
|
35861
|
+
return this.baseMap.get(keyFirstAxis, keySecondAxis);
|
|
35862
|
+
}
|
|
35863
|
+
set() {
|
|
35864
|
+
throw new Error("Cannot set value on a Map2dView");
|
|
35865
|
+
}
|
|
35866
|
+
getFirstAxisKeys() {
|
|
35867
|
+
return Array.from(this.keysFirstAxis.values());
|
|
35868
|
+
}
|
|
35869
|
+
getSecondAxisKeys() {
|
|
35870
|
+
return Array.from(this.keysSecondAxis.values());
|
|
35871
|
+
}
|
|
35872
|
+
getAsArray(fillEmptyWith) {
|
|
35873
|
+
return this.getFirstAxisKeys().map((firstAxisKey) => {
|
|
35874
|
+
return this.getSecondAxisKeys().map((secondAxisKey) => {
|
|
35875
|
+
return this.baseMap.get(firstAxisKey, secondAxisKey) ?? fillEmptyWith;
|
|
35941
35876
|
});
|
|
35942
35877
|
});
|
|
35943
|
-
|
|
35878
|
+
}
|
|
35879
|
+
getRow(key, fillEmptyWith) {
|
|
35880
|
+
const serializedKeyFirstAxis = this.serializeFirstAxis(key);
|
|
35881
|
+
if (!this.keysFirstAxis.has(serializedKeyFirstAxis)) {
|
|
35882
|
+
return [];
|
|
35883
|
+
}
|
|
35884
|
+
return this.baseMap.getRow(key, fillEmptyWith);
|
|
35885
|
+
}
|
|
35886
|
+
}
|
|
35887
|
+
function getFilteredMutationOverTimeData(data, overallMutationData, displayedSegments, displayedMutationTypes, proportionInterval) {
|
|
35888
|
+
const filteredData = new Map2dView(data);
|
|
35889
|
+
filterDisplayedSegments(displayedSegments, filteredData);
|
|
35890
|
+
filterMutationTypes(displayedMutationTypes, filteredData);
|
|
35891
|
+
filterProportion(filteredData, overallMutationData, proportionInterval);
|
|
35892
|
+
return filteredData;
|
|
35893
|
+
}
|
|
35894
|
+
function filterDisplayedSegments(displayedSegments, data) {
|
|
35895
|
+
displayedSegments.forEach((segment) => {
|
|
35896
|
+
if (!segment.checked) {
|
|
35897
|
+
data.getFirstAxisKeys().forEach((mutation) => {
|
|
35898
|
+
if (mutation.segment === segment.segment) {
|
|
35899
|
+
data.deleteRow(mutation);
|
|
35900
|
+
}
|
|
35901
|
+
});
|
|
35902
|
+
}
|
|
35903
|
+
});
|
|
35904
|
+
}
|
|
35905
|
+
function filterMutationTypes(displayedMutationTypes, data) {
|
|
35906
|
+
displayedMutationTypes.forEach((mutationType) => {
|
|
35907
|
+
if (!mutationType.checked) {
|
|
35908
|
+
data.getFirstAxisKeys().forEach((mutation) => {
|
|
35909
|
+
if (mutationType.type === mutation.type) {
|
|
35910
|
+
data.deleteRow(mutation);
|
|
35911
|
+
}
|
|
35912
|
+
});
|
|
35913
|
+
}
|
|
35914
|
+
});
|
|
35915
|
+
}
|
|
35916
|
+
function filterProportion(data, overallMutationData, proportionInterval) {
|
|
35917
|
+
const overallProportionsByMutation = overallMutationData.content.reduce(
|
|
35918
|
+
(acc, { mutation, proportion }) => ({
|
|
35919
|
+
...acc,
|
|
35920
|
+
[mutation.toString()]: proportion
|
|
35921
|
+
}),
|
|
35922
|
+
{}
|
|
35923
|
+
);
|
|
35924
|
+
data.getFirstAxisKeys().forEach((mutation) => {
|
|
35925
|
+
const overallProportion = overallProportionsByMutation[mutation.toString()] || -1;
|
|
35926
|
+
if (overallProportion < proportionInterval.min || overallProportion > proportionInterval.max) {
|
|
35927
|
+
data.deleteRow(mutation);
|
|
35928
|
+
}
|
|
35929
|
+
});
|
|
35930
|
+
}
|
|
35931
|
+
const ColorScaleSelector = ({ colorScale, setColorScale }) => {
|
|
35932
|
+
const colorDisplayCss = `w-10 h-8 border border-gray-200 mx-2 text-xs flex items-center justify-center`;
|
|
35933
|
+
return /* @__PURE__ */ u$2("div", { className: "flex items-center", children: [
|
|
35934
|
+
/* @__PURE__ */ u$2(
|
|
35935
|
+
"div",
|
|
35936
|
+
{
|
|
35937
|
+
style: {
|
|
35938
|
+
backgroundColor: singleGraphColorRGBByName(colorScale.color, 0),
|
|
35939
|
+
color: "black"
|
|
35940
|
+
},
|
|
35941
|
+
className: colorDisplayCss,
|
|
35942
|
+
children: formatProportion(colorScale.min, 0)
|
|
35943
|
+
}
|
|
35944
|
+
),
|
|
35945
|
+
/* @__PURE__ */ u$2("div", { className: "w-64", children: /* @__PURE__ */ u$2(
|
|
35946
|
+
MinMaxRangeSlider,
|
|
35947
|
+
{
|
|
35948
|
+
min: colorScale.min * 100,
|
|
35949
|
+
max: colorScale.max * 100,
|
|
35950
|
+
setMin: (percentage) => {
|
|
35951
|
+
setColorScale({ ...colorScale, min: percentage / 100 });
|
|
35952
|
+
},
|
|
35953
|
+
setMax: (percentage) => {
|
|
35954
|
+
setColorScale({ ...colorScale, max: percentage / 100 });
|
|
35955
|
+
}
|
|
35956
|
+
}
|
|
35957
|
+
) }),
|
|
35958
|
+
/* @__PURE__ */ u$2(
|
|
35959
|
+
"div",
|
|
35960
|
+
{
|
|
35961
|
+
style: {
|
|
35962
|
+
backgroundColor: singleGraphColorRGBByName(colorScale.color, 1),
|
|
35963
|
+
color: "white"
|
|
35964
|
+
},
|
|
35965
|
+
className: colorDisplayCss,
|
|
35966
|
+
children: formatProportion(colorScale.max, 0)
|
|
35967
|
+
}
|
|
35968
|
+
)
|
|
35969
|
+
] });
|
|
35970
|
+
};
|
|
35971
|
+
const getColorWithingScale = (value, colorScale) => {
|
|
35972
|
+
if (colorScale.min === colorScale.max) {
|
|
35973
|
+
return singleGraphColorRGBByName(colorScale.color, 0);
|
|
35974
|
+
}
|
|
35975
|
+
const colorRange = colorScale.max - colorScale.min;
|
|
35976
|
+
const alpha2 = (value - colorScale.min) / colorRange;
|
|
35977
|
+
return singleGraphColorRGBByName(colorScale.color, alpha2);
|
|
35978
|
+
};
|
|
35979
|
+
const getTextColorForScale = (value, colorScale) => {
|
|
35980
|
+
if (colorScale.min === colorScale.max) {
|
|
35981
|
+
return "black";
|
|
35982
|
+
}
|
|
35983
|
+
const colorRange = colorScale.max - colorScale.min;
|
|
35984
|
+
const alpha2 = (value - colorScale.min) / colorRange;
|
|
35985
|
+
return alpha2 <= 0.5 ? "black" : "white";
|
|
35986
|
+
};
|
|
35987
|
+
function getPositionCss(position) {
|
|
35988
|
+
switch (position) {
|
|
35989
|
+
case "top":
|
|
35990
|
+
return "bottom-full translate-x-[-50%] left-1/2 mb-1";
|
|
35991
|
+
case "top-start":
|
|
35992
|
+
return "bottom-full mr-1 mb-1";
|
|
35993
|
+
case "top-end":
|
|
35994
|
+
return "bottom-full right-0 ml-1 mb-1";
|
|
35995
|
+
case "bottom":
|
|
35996
|
+
return "top-full translate-x-[-50%] left-1/2 mt-1";
|
|
35997
|
+
case "bottom-start":
|
|
35998
|
+
return "mr-1 mt-1";
|
|
35999
|
+
case "bottom-end":
|
|
36000
|
+
return "right-0 ml-1 mt-1";
|
|
36001
|
+
case "left":
|
|
36002
|
+
return "right-full translate-y-[-50%] top-1/2 mr-1";
|
|
36003
|
+
case "right":
|
|
36004
|
+
return "left-full translate-y-[-50%] top-1/2 ml-1";
|
|
36005
|
+
case void 0:
|
|
36006
|
+
return "";
|
|
35944
36007
|
}
|
|
35945
36008
|
}
|
|
36009
|
+
const Tooltip = ({ children, content, position = "bottom" }) => {
|
|
36010
|
+
return /* @__PURE__ */ u$2("div", { className: "relative w-full h-full", children: [
|
|
36011
|
+
/* @__PURE__ */ u$2("div", { className: "peer w-full h-full", children }),
|
|
36012
|
+
/* @__PURE__ */ u$2(
|
|
36013
|
+
"div",
|
|
36014
|
+
{
|
|
36015
|
+
className: `absolute z-10 w-max bg-white p-4 border border-gray-200 rounded-md invisible peer-hover:visible ${getPositionCss(position)}`,
|
|
36016
|
+
children: content
|
|
36017
|
+
}
|
|
36018
|
+
)
|
|
36019
|
+
] });
|
|
36020
|
+
};
|
|
36021
|
+
const MAX_NUMBER_OF_GRID_ROWS = 100;
|
|
36022
|
+
const MUTATION_CELL_WIDTH_REM = 8;
|
|
36023
|
+
const MutationsOverTimeGrid = ({ data, colorScale }) => {
|
|
36024
|
+
const allMutations = data.getFirstAxisKeys().sort(sortSubstitutionsAndDeletions);
|
|
36025
|
+
const shownMutations = allMutations.slice(0, MAX_NUMBER_OF_GRID_ROWS);
|
|
36026
|
+
const dates = data.getSecondAxisKeys().sort((a2, b3) => compareTemporal(a2, b3));
|
|
36027
|
+
const [showProportionText, setShowProportionText] = h$1(false);
|
|
36028
|
+
const gridRef = A$1(null);
|
|
36029
|
+
useShowProportion(gridRef, dates.length, setShowProportionText);
|
|
36030
|
+
return /* @__PURE__ */ u$2(k$1, { children: [
|
|
36031
|
+
allMutations.length > MAX_NUMBER_OF_GRID_ROWS && /* @__PURE__ */ u$2("div", { className: "pl-2", children: [
|
|
36032
|
+
"Showing ",
|
|
36033
|
+
MAX_NUMBER_OF_GRID_ROWS,
|
|
36034
|
+
" of ",
|
|
36035
|
+
allMutations.length,
|
|
36036
|
+
" mutations. You can narrow the filter to reduce the number of mutations."
|
|
36037
|
+
] }),
|
|
36038
|
+
/* @__PURE__ */ u$2(
|
|
36039
|
+
"div",
|
|
36040
|
+
{
|
|
36041
|
+
ref: gridRef,
|
|
36042
|
+
style: {
|
|
36043
|
+
display: "grid",
|
|
36044
|
+
gridTemplateRows: `repeat(${shownMutations.length}, 24px)`,
|
|
36045
|
+
gridTemplateColumns: `${MUTATION_CELL_WIDTH_REM}rem repeat(${dates.length}, minmax(0.05rem, 1fr))`
|
|
36046
|
+
},
|
|
36047
|
+
children: shownMutations.map((mutation, rowIndex) => {
|
|
36048
|
+
return /* @__PURE__ */ u$2(k$1, { children: [
|
|
36049
|
+
/* @__PURE__ */ u$2(
|
|
36050
|
+
"div",
|
|
36051
|
+
{
|
|
36052
|
+
style: { gridRowStart: rowIndex + 1, gridColumnStart: 1 },
|
|
36053
|
+
children: /* @__PURE__ */ u$2(MutationCell, { mutation })
|
|
36054
|
+
},
|
|
36055
|
+
`mutation-${mutation.toString()}`
|
|
36056
|
+
),
|
|
36057
|
+
dates.map((date, columnIndex) => {
|
|
36058
|
+
const value = data.get(mutation, date) ?? { proportion: 0, count: 0 };
|
|
36059
|
+
const tooltipPosition = getTooltipPosition(
|
|
36060
|
+
rowIndex,
|
|
36061
|
+
shownMutations.length,
|
|
36062
|
+
columnIndex,
|
|
36063
|
+
dates.length
|
|
36064
|
+
);
|
|
36065
|
+
return /* @__PURE__ */ u$2(
|
|
36066
|
+
"div",
|
|
36067
|
+
{
|
|
36068
|
+
style: { gridRowStart: rowIndex + 1, gridColumnStart: columnIndex + 2 },
|
|
36069
|
+
children: /* @__PURE__ */ u$2(
|
|
36070
|
+
ProportionCell,
|
|
36071
|
+
{
|
|
36072
|
+
value,
|
|
36073
|
+
date,
|
|
36074
|
+
mutation,
|
|
36075
|
+
tooltipPosition,
|
|
36076
|
+
showProportionText,
|
|
36077
|
+
colorScale
|
|
36078
|
+
}
|
|
36079
|
+
)
|
|
36080
|
+
},
|
|
36081
|
+
`${mutation.toString()}-${date.toString()}`
|
|
36082
|
+
);
|
|
36083
|
+
})
|
|
36084
|
+
] }, `fragment-${mutation.toString()}`);
|
|
36085
|
+
})
|
|
36086
|
+
}
|
|
36087
|
+
)
|
|
36088
|
+
] });
|
|
36089
|
+
};
|
|
36090
|
+
function useShowProportion(gridRef, girdColumns, setShowProportionText) {
|
|
36091
|
+
y$1(() => {
|
|
36092
|
+
const checkWidth = () => {
|
|
36093
|
+
if (gridRef.current) {
|
|
36094
|
+
const width = gridRef.current.getBoundingClientRect().width;
|
|
36095
|
+
const widthPerDate = (width - remToPx(MUTATION_CELL_WIDTH_REM)) / girdColumns;
|
|
36096
|
+
const maxWidthProportionText = 28;
|
|
36097
|
+
setShowProportionText(widthPerDate > maxWidthProportionText);
|
|
36098
|
+
}
|
|
36099
|
+
};
|
|
36100
|
+
checkWidth();
|
|
36101
|
+
window.addEventListener("resize", checkWidth);
|
|
36102
|
+
return () => {
|
|
36103
|
+
window.removeEventListener("resize", checkWidth);
|
|
36104
|
+
};
|
|
36105
|
+
}, [girdColumns, gridRef, setShowProportionText]);
|
|
36106
|
+
}
|
|
36107
|
+
const remToPx = (rem) => rem * parseFloat(getComputedStyle(document.documentElement).fontSize);
|
|
36108
|
+
function getTooltipPosition(rowIndex, rows, columnIndex, columns) {
|
|
36109
|
+
const tooltipX = rowIndex < rows / 2 ? "bottom" : "top";
|
|
36110
|
+
const tooltipY = columnIndex < columns / 2 ? "start" : "end";
|
|
36111
|
+
return `${tooltipX}-${tooltipY}`;
|
|
36112
|
+
}
|
|
36113
|
+
const ProportionCell = ({ value, mutation, date, tooltipPosition, showProportionText, colorScale }) => {
|
|
36114
|
+
const tooltipContent = /* @__PURE__ */ u$2("div", { children: [
|
|
36115
|
+
/* @__PURE__ */ u$2("p", { children: /* @__PURE__ */ u$2("span", { className: "font-bold", children: date.englishName() }) }),
|
|
36116
|
+
/* @__PURE__ */ u$2("p", { children: [
|
|
36117
|
+
"(",
|
|
36118
|
+
timeIntervalDisplay(date),
|
|
36119
|
+
")"
|
|
36120
|
+
] }),
|
|
36121
|
+
/* @__PURE__ */ u$2("p", { children: mutation.code }),
|
|
36122
|
+
/* @__PURE__ */ u$2("p", { children: [
|
|
36123
|
+
"Proportion: ",
|
|
36124
|
+
formatProportion(value.proportion)
|
|
36125
|
+
] }),
|
|
36126
|
+
/* @__PURE__ */ u$2("p", { children: [
|
|
36127
|
+
"Count: ",
|
|
36128
|
+
value.count
|
|
36129
|
+
] })
|
|
36130
|
+
] });
|
|
36131
|
+
return /* @__PURE__ */ u$2("div", { className: "py-1 w-full h-full", children: /* @__PURE__ */ u$2(Tooltip, { content: tooltipContent, position: tooltipPosition, children: /* @__PURE__ */ u$2(
|
|
36132
|
+
"div",
|
|
36133
|
+
{
|
|
36134
|
+
style: {
|
|
36135
|
+
backgroundColor: getColorWithingScale(value.proportion, colorScale),
|
|
36136
|
+
color: getTextColorForScale(value.proportion, colorScale)
|
|
36137
|
+
},
|
|
36138
|
+
className: `w-full h-full text-center hover:font-bold text-xs group`,
|
|
36139
|
+
children: showProportionText ? formatProportion(value.proportion, 0) : void 0
|
|
36140
|
+
}
|
|
36141
|
+
) }) });
|
|
36142
|
+
};
|
|
36143
|
+
const timeIntervalDisplay = (date) => {
|
|
36144
|
+
if (date instanceof YearMonthDay) {
|
|
36145
|
+
return date.toString();
|
|
36146
|
+
}
|
|
36147
|
+
return `${date.firstDay.toString()} - ${date.lastDay.toString()}`;
|
|
36148
|
+
};
|
|
36149
|
+
const MutationCell = ({ mutation }) => {
|
|
36150
|
+
return /* @__PURE__ */ u$2("div", { className: "text-center", children: mutation.toString() });
|
|
36151
|
+
};
|
|
35946
36152
|
const MAX_NUMBER_OF_GRID_COLUMNS = 200;
|
|
35947
36153
|
async function queryOverallMutationData(lapisFilter, sequenceType, lapis, signal) {
|
|
35948
36154
|
return fetchAndPrepareSubstitutionsOrDeletions(lapisFilter, sequenceType).evaluate(lapis, signal);
|
|
@@ -36014,7 +36220,7 @@ function fetchAndPrepareSubstitutionsOrDeletions(filter, sequenceType) {
|
|
|
36014
36220
|
return new FetchSubstitutionsOrDeletionsOperator(filter, sequenceType, 1e-3);
|
|
36015
36221
|
}
|
|
36016
36222
|
function groupByMutation(data) {
|
|
36017
|
-
const dataArray = new
|
|
36223
|
+
const dataArray = new Map2dBase(
|
|
36018
36224
|
(mutation) => mutation.code,
|
|
36019
36225
|
(date) => date.toString()
|
|
36020
36226
|
);
|
|
@@ -36043,7 +36249,7 @@ const ColorScaleSelectorDropdown = ({
|
|
|
36043
36249
|
colorScale,
|
|
36044
36250
|
setColorScale
|
|
36045
36251
|
}) => {
|
|
36046
|
-
return /* @__PURE__ */ u$2(Dropdown, { buttonTitle: `Color scale`, placement: "bottom-start", children: /* @__PURE__ */ u$2(ColorScaleSelector, { colorScale, setColorScale }) });
|
|
36252
|
+
return /* @__PURE__ */ u$2("div", { className: "w-20", children: /* @__PURE__ */ u$2(Dropdown, { buttonTitle: `Color scale`, placement: "bottom-start", children: /* @__PURE__ */ u$2(ColorScaleSelector, { colorScale, setColorScale }) }) });
|
|
36047
36253
|
};
|
|
36048
36254
|
const MutationsOverTime = ({ width, height, ...innerProps }) => {
|
|
36049
36255
|
const size = { height, width };
|