diff --git a/index.html b/index.html
index 2ee5707..d6f587e 100644
--- a/index.html
+++ b/index.html
@@ -14,22 +14,24 @@
-
-
+
+
+
+
+
+
diff --git a/src/gui/index.ts b/src/gui/index.ts
index 9b3cd81..d4f89cd 100644
--- a/src/gui/index.ts
+++ b/src/gui/index.ts
@@ -42,6 +42,8 @@ const DEFAULT_LAYOUT_PROPERTIES = {
} as LayoutProperties;
export default async function main() {
+ const jellyfishGui = document.querySelector(".jellyfish-gui") as HTMLElement;
+
const { generalProps, layoutProps, costWeights } =
getSavedOrDefaultSettings();
const saveSettings = () =>
@@ -51,7 +53,7 @@ export default async function main() {
try {
tables = await loadDataTables();
} catch (e) {
- showError((e as Error).message);
+ showError(jellyfishGui, (e as Error).message);
throw e;
}
@@ -60,6 +62,7 @@ export default async function main() {
const onPatientChange = () =>
updatePlot(
+ jellyfishGui,
patients.length > 1
? filterDataTablesByPatient(tables, generalProps.patient)
: tables,
@@ -67,7 +70,7 @@ export default async function main() {
costWeights
);
- const gui = new GUI();
+ const gui = new GUI({ container: jellyfishGui });
gui.onChange(saveSettings);
let patientController: Controller;
@@ -78,7 +81,9 @@ export default async function main() {
}
const onZoomChange = (value: number) =>
- (document.getElementById("plot").style.transform = `scale(${value})`);
+ ((
+ jellyfishGui.querySelector(".jellyfish-plot") as HTMLElement
+ ).style.transform = `scale(${value})`);
gui.add(generalProps, "zoom", 0.2, 2).onChange(onZoomChange);
@@ -112,25 +117,22 @@ export default async function main() {
weightsFolder.onChange(onPatientChange);
weightsFolder.close();
+ const querySvg = () =>
+ jellyfishGui.querySelector(".jellyfish-plot svg") as SVGElement;
+
const toolsFolder = gui.addFolder("Tools");
const tools = {
downloadSvg: () =>
- downloadSvg(
- document.getElementById("plot").querySelector("svg"),
- (generalProps.patient ?? "jellyfish") + ".svg"
- ),
+ downloadSvg(querySvg(), (generalProps.patient ?? "jellyfish") + ".svg"),
downloadPng: () => {
- downloadPng(
- document.getElementById("plot").querySelector("svg"),
- (generalProps.patient ?? "jellyfish") + ".png"
- );
+ downloadPng(querySvg(), (generalProps.patient ?? "jellyfish") + ".png");
},
};
toolsFolder.add(tools, "downloadSvg");
toolsFolder.add(tools, "downloadPng");
if (patientController) {
- setupPatientNavigation(patients, generalProps, () => {
+ setupPatientNavigation(jellyfishGui, patients, generalProps, () => {
patientController.updateDisplay();
onPatientChange();
saveSettings();
@@ -142,11 +144,12 @@ export default async function main() {
}
function updatePlot(
+ jellyfishGui: HTMLElement,
tables: DataTables,
layoutProps: LayoutProperties,
costWeights: CostWeights
) {
- const plot = document.getElementById("plot");
+ const plot = jellyfishGui.querySelector(".jellyfish-plot") as HTMLElement;
try {
const svg = tablesToJellyfish(tables, layoutProps, costWeights);
@@ -155,15 +158,15 @@ function updatePlot(
addInteractions(plot.querySelector("svg"));
} catch (e) {
- showError((e as Error).message);
+ showError(jellyfishGui, (e as Error).message);
throw e;
}
}
-function showError(message: string) {
- document.getElementById(
- "plot"
- ).innerHTML = `
${message}
`;
+function showError(jellyfishGui: HTMLElement, message: string) {
+ jellyfishGui.querySelector(
+ ".jellyfish-plot"
+ ).innerHTML = `
${message}
`;
}
const STORAGE_KEY = "jellyfish-plotter-settings";
@@ -200,20 +203,25 @@ function getSavedOrDefaultSettings() {
}
function setupPatientNavigation(
+ jellyfishGui: HTMLElement,
samples: string[],
generalProps: GeneralProperties,
onUpdate: (sample: string) => void
) {
const navigate = makePatientNavigator(samples, generalProps, onUpdate);
+ const patientNav = jellyfishGui.querySelector(
+ ".jellyfish-patient-nav"
+ ) as HTMLElement;
+
// It's "display: none" by default
- document.getElementById("patient-nav").style.display = null;
+ patientNav.style.display = null;
- document
- .getElementById("prev-patient")
+ patientNav
+ .querySelector(".jellyfish-prev-patient")
.addEventListener("click", () => navigate(-1));
- document
- .getElementById("next-patient")
+ patientNav
+ .querySelector(".jellyfish-next-patient")
.addEventListener("click", () => navigate(1));
document.addEventListener("keydown", (event) => {
diff --git a/style.css b/style.css
index 14cf039..7f6753e 100644
--- a/style.css
+++ b/style.css
@@ -3,17 +3,6 @@ body {
font-family: Arial, Helvetica, sans-serif;
}
-#plot-container {
- display: grid;
- place-items: center;
-
- position: absolute;
- inset: 0;
-
- overflow-x: hidden;
- overflow-y: auto;
-}
-
#title {
font-family: "Nerko One", cursive;
font-weight: 400;
@@ -26,7 +15,23 @@ body {
color: #e0e0e0;
}
-#patient-nav {
+.jellyfish-gui {
+ position: absolute;
+ inset: 0;
+}
+
+.jellyfish-plot-container {
+ display: grid;
+ place-items: center;
+
+ position: absolute;
+ inset: 0;
+
+ overflow-x: hidden;
+ overflow-y: auto;
+}
+
+.jellyfish-patient-nav {
display: flex;
justify-content: space-between;
@@ -39,7 +44,7 @@ body {
right: var(--margin);
}
-#patient-nav > button {
+.jellyfish-patient-nav > button {
font-family: "Nerko One", cursive;
font-weight: 400;
font-style: normal;
@@ -59,15 +64,15 @@ body {
gap: 0.4em;
}
-#patient-nav > button > svg {
+.jellyfish-patient-nav > button > svg {
height: 0.7em;
}
-#patient-nav > button:hover {
+.jellyfish-patient-nav > button:hover {
background-color: #e8e8e8;
}
-.lil-gui {
+.jellyfish-gui .lil-gui {
--background-color: #f3f3f3;
--text-color: #3d3d3d;
--title-background-color: #e0e0e0;
@@ -79,13 +84,18 @@ body {
--string-color: #738500;
}
-.error-message {
+.jellyfish-gui .lil-gui.root {
+ position: absolute;
+ right: 2em;
+}
+
+.jellyfish-error-message {
color: #bb0000;
}
@media print {
.lil-gui.root,
- #patient-nav,
+ .jellyfish-patient-nav,
#title {
display: none;
}