Skip to content

Commit

Permalink
refactor: prepare for multiple instances
Browse files Browse the repository at this point in the history
  • Loading branch information
tuner committed Oct 2, 2024
1 parent 7367737 commit 1bbf5fb
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 57 deletions.
34 changes: 18 additions & 16 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -14,22 +14,24 @@

<body>
<h1 id="title">Jellyfish Plotter</h1>
<div id="plot-container">
<div id="plot"></div>
</div>
<div id="patient-nav" style="display: none">
<button id="prev-patient">
<svg viewBox="0 0 8 16" fill="currentColor">
<polygon points="8,0 0,8 8,16" />
</svg>
<span>Previous</span>
</button>
<button id="next-patient">
<span>Next</span>
<svg viewBox="0 0 8 16" fill="currentColor">
<polygon points="0,0 8,8 0,16" />
</svg>
</button>
<div class="jellyfish-gui">
<div class="jellyfish-plot-container">
<div class="jellyfish-plot"></div>
</div>
<div class="jellyfish-patient-nav" style="display: none">
<button class="jellyfish-prev-patient">
<svg viewBox="0 0 8 16" fill="currentColor">
<polygon points="8,0 0,8 8,16" />
</svg>
<span>Previous</span>
</button>
<button class="jellyfish-next-patient">
<span>Next</span>
<svg viewBox="0 0 8 16" fill="currentColor">
<polygon points="0,0 8,8 0,16" />
</svg>
</button>
</div>
</div>
<script type="module" src="/src/gui/index.ts"></script>
</body>
Expand Down
54 changes: 31 additions & 23 deletions src/gui/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 = () =>
Expand All @@ -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;
}

Expand All @@ -60,14 +62,15 @@ export default async function main() {

const onPatientChange = () =>
updatePlot(
jellyfishGui,
patients.length > 1
? filterDataTablesByPatient(tables, generalProps.patient)
: tables,
layoutProps,
costWeights
);

const gui = new GUI();
const gui = new GUI({ container: jellyfishGui });
gui.onChange(saveSettings);

let patientController: Controller;
Expand All @@ -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);

Expand Down Expand Up @@ -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();
Expand All @@ -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);
Expand All @@ -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 = `<div class="error-message">${message}</div>`;
function showError(jellyfishGui: HTMLElement, message: string) {
jellyfishGui.querySelector(
".jellyfish-plot"
).innerHTML = `<div class="jellyfish-error-message">${message}</div>`;
}

const STORAGE_KEY = "jellyfish-plotter-settings";
Expand Down Expand Up @@ -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) => {
Expand Down
46 changes: 28 additions & 18 deletions style.css
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;

Expand All @@ -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;
Expand All @@ -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;
Expand All @@ -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;
}
Expand Down

0 comments on commit 1bbf5fb

Please sign in to comment.