start allowing multiple viewer on single page

This commit is contained in:
Ross
2021-12-04 14:57:42 +00:00
parent f2241ea9d0
commit db46c153f0
2 changed files with 157 additions and 35 deletions
+1 -1
View File
@@ -44,7 +44,7 @@
color: lightblue; color: lightblue;
} }
.single-dicom-viewer { .cornerstone-element {
position: relative; position: relative;
height: 100%; height: 100%;
} }
+156 -34
View File
@@ -9,17 +9,22 @@ cornerstoneBase64ImageLoader.external.cornerstone = cornerstone;
cornerstoneWebImageLoader.external.cornerstone = cornerstone; cornerstoneWebImageLoader.external.cornerstone = cornerstone;
cornerstoneWADOImageLoader.external.cornerstone = cornerstone; cornerstoneWADOImageLoader.external.cornerstone = cornerstone;
cornerstoneTools.init(); cornerstoneTools.init({keyboardEnabled: true});
let tool_state = {}; let tool_state = {};
export function loadCornerstone(main_element, db, images, annotations_to_load, load_as_stack = false) { export function loadCornerstone(main_element, db, images, annotations_to_load, load_as_stack = false) {
// canvas-panel holds the enabled elements and all tools / menus // canvas-panel holds the enabled elements and all tools / menus
main_element.append("<div class='canvas-panel'></div>"); const canvas_panel = $("<div class='canvas-panel'></div>");
main_element.append(canvas_panel);
main_element[0].dataset.collapsed = "none"; main_element[0].dataset.collapsed = "none";
$(".canvas-panel").append($("<div class='single-dicom-viewer'></div>"));
$(".canvas-panel").append($(`<div id='dicom-summary-panel'>
const cornerstone_element = $("<div class='cornerstone-element'></div>");
const element = cornerstone_element.get(0);
canvas_panel.append(cornerstone_element);
canvas_panel.append($(`<div id='dicom-summary-panel'>
<span id="dicom-summary-close" class="close-button"><a href="#">close</a></span> <span id="dicom-summary-close" class="close-button"><a href="#">close</a></span>
<div class="container-fluid"> <div class="container-fluid">
<h1>DICOM Summary</h1> <h1>DICOM Summary</h1>
@@ -309,10 +314,9 @@ export function loadCornerstone(main_element, db, images, annotations_to_load, l
</div> </div>
</div>`)); </div>`));
let single_dicom_viewer = main_element.find(".single-dicom-viewer").get(0); //console.log(cornerstone_element);
//console.log(single_dicom_viewer);
$(".canvas-panel").append($(`<div id='dicom-log-panel'> canvas_panel.append($(`<div id='dicom-log-panel'>
<span id="dicom-log-close" class="close-button"><a href="#">close</a></span> <span id="dicom-log-close" class="close-button"><a href="#">close</a></span>
</div>`)); </div>`));
@@ -398,7 +402,7 @@ export function loadCornerstone(main_element, db, images, annotations_to_load, l
</div>`) </div>`)
); );
$(single_dicom_viewer).append( cornerstone_element.append(
$( $(
"<div id='dicom-overlay'>Image <span id='current_image_number'></span> of <span id='total_image_number'></span><br />wc: <span id='wc'></span> ww: <span id='ww'></span></div>" "<div id='dicom-overlay'>Image <span id='current_image_number'></span> of <span id='total_image_number'></span><br />wc: <span id='wc'></span> ww: <span id='ww'></span></div>"
) )
@@ -422,10 +426,10 @@ export function loadCornerstone(main_element, db, images, annotations_to_load, l
let button_id = e.target.id; let button_id = e.target.id;
let [ww, wc] = window_presets[button_id]; let [ww, wc] = window_presets[button_id];
let viewport = cornerstone.getViewport(single_dicom_viewer); let viewport = cornerstone.getViewport(element);
viewport.voi.windowWidth = parseFloat(ww); viewport.voi.windowWidth = parseFloat(ww);
viewport.voi.windowCenter = parseFloat(wc); viewport.voi.windowCenter = parseFloat(wc);
cornerstone.setViewport(single_dicom_viewer, viewport); cornerstone.setViewport(element, viewport);
e.preventDefault(); e.preventDefault();
e.stopPropagation(); e.stopPropagation();
@@ -486,7 +490,7 @@ export function loadCornerstone(main_element, db, images, annotations_to_load, l
$("#dicom-window-panel").show(); $("#dicom-window-panel").show();
$(e.target).removeClass("dicom-button-highlight"); $(e.target).removeClass("dicom-button-highlight");
} }
resizeHandler(); resizeHandler(element);
//loadCornerstone(main_element, db, images, annotations_to_load, stack) //loadCornerstone(main_element, db, images, annotations_to_load, stack)
}); });
@@ -529,7 +533,7 @@ export function loadCornerstone(main_element, db, images, annotations_to_load, l
} }
async function load(images, annotations) { async function load(images, annotations) {
//console.log("LOAD", images); console.log("LOAD", images);
let imageIds = []; let imageIds = [];
for (let i = 0; i < images.length; i++) { for (let i = 0; i < images.length; i++) {
let data_url = images[i]; let data_url = images[i];
@@ -597,7 +601,7 @@ export function loadCornerstone(main_element, db, images, annotations_to_load, l
cornerstone.loadAndCacheImage(imageIds[0]).then(function (image) { cornerstone.loadAndCacheImage(imageIds[0]).then(function (image) {
//console.log("LOAD and cache, then", image); //console.log("LOAD and cache, then", image);
loadCornerstoneMainImage(single_dicom_viewer, image, stack, db, load_as_stack); loadCornerstoneMainImage(element, image, stack, db, load_as_stack);
}) })
.catch((err, err2) => { .catch((err, err2) => {
console.log(err); console.log(err);
@@ -636,7 +640,7 @@ export function loadCornerstone(main_element, db, images, annotations_to_load, l
"</span></div>" "</span></div>"
); );
$("#image-thumbs").append(thumb); $("#image-thumbs").append(thumb);
$("#thumb-" + id).click(selectThumbClick).mousedown(stopEvent); $("#thumb-" + id).click((evt) => { selectThumbClick(evt, element) }).mousedown(stopEvent);
let image_url = images[id]; let image_url = images[id];
@@ -703,8 +707,124 @@ export function loadCornerstone(main_element, db, images, annotations_to_load, l
} }
load(images, annotations); load(images, annotations);
console.log(main_element)
main_element.keydown((evt) => { keyDownHandler(evt, element)});
main_element.keyup((evt) => { keyUpHandler(evt, element)});
} }
function keyUpHandler(e, element) {
console.log("Key up", e, e.key)
if (e.key == "Control") {
registerPrimaryDicomInterface(element);
window.control_pressed = false;
}
}
function keyDownHandler(e, element) {
//// Ignore our custom keybindings if we are currently in a field that
//// accepts some kind of input
//if ($("*:focus:not(disabled)").is("textarea, input")) {
// // unless a modifier key is pressed (not shift)
// if (e.altKey ? true : false || e.ctrlKey ? true : false) {} else {
// return;
// }
//}
console.log("Key down", e, e.key)
if (e.key == "Control") {
if (window.control_pressed != true) {
window.control_pressed = true;
registerAltDicomInterface(e, element);
}
}
var charCode = typeof e.which == "number" ? e.which : e.keyCode;
function numberKeyPressed(e, x) {
if (e.altKey ? true : false) {
selectThumb(x, element);
e.preventDefault();
} else {}
}
switch (charCode) {
case 13: // Return
if (e.shiftKey ? true : false) {
//$(".next-button:last").click();
} else {
//$(".check-button:last").click();
}
break;
case 32: // Space
if (e.shiftKey ? true : false) {
//$(".previous-button:last").click();
} else {
//$(".next-button:last").click();
}
e.preventDefault(); // Needed to stop the default action (scroll)
break;
case 46: // .
//toggleFlagged();
break;
// Numbers 1-9 select the corresponding answer (if it exists)
// TODO: fix for multi question questions
case 49: // 1
numberKeyPressed(e, 0);
break;
case 50: // 2
numberKeyPressed(e, 1);
break;
case 51: // 3
numberKeyPressed(e, 2);
break;
case 52: // 4
numberKeyPressed(e, 3);
break;
case 53: // 5
numberKeyPressed(e, 4);
break;
case 54: // 6
numberKeyPressed(e, 5);
break;
case 55: // 7
numberKeyPressed(e, 6);
break;
case 56: // 8
numberKeyPressed(e, 7);
break;
case 57: // 9
numberKeyPressed(e, 8);
break;
case 72: // H
previousQuestion();
break;
case 76: // L
//nextQuestion();
break;
case 102: // f
//$("#filter-toggle").click();
break;
case 103: // g
//$("#options").slideDown("slow");
//$("#goto-question-input").focus();
//e.preventDefault();
break;
// Vim like scrolling (incredibly important)
case 106: // j
//window.scrollBy(0, 25);
break;
case 107: // k
//window.scrollBy(0, -25);
break;
}
}
function loadCornerstoneMainImage(element, image, stack, db, load_as_stack) { function loadCornerstoneMainImage(element, image, stack, db, load_as_stack) {
//dumpDataSet(image.data) //dumpDataSet(image.data)
//console.log("loadCornerstoneMainImage") //console.log("loadCornerstoneMainImage")
@@ -725,9 +845,12 @@ function loadCornerstoneMainImage(element, image, stack, db, load_as_stack) {
//console.log("enable element", element); //console.log("enable element", element);
cornerstone.enable(element); cornerstone.enable(element);
element.tabIndex = 0;
cornerstone.displayImage(element, image); cornerstone.displayImage(element, image);
//cornerstoneTools.keyboardInput.enable(element);
cornerstoneTools.addStackStateManager(element, ["stack"]); cornerstoneTools.addStackStateManager(element, ["stack"]);
cornerstoneTools.addToolState(element, "stack", stack); cornerstoneTools.addToolState(element, "stack", stack);
@@ -789,8 +912,8 @@ function loadCornerstoneMainImage(element, image, stack, db, load_as_stack) {
//$("#middle-mouse-dicom").append(option); //$("#middle-mouse-dicom").append(option);
//$("#right-mouse-dicom").append(option); //$("#right-mouse-dicom").append(option);
}); });
$(".mouse-binding-select").on("change", function (e) { $(".mouse-binding-select").on("change", function (evt) {
changeMouseBinding(e, db); changeMouseBinding(evt, db, element);
}); });
// Set default tools // Set default tools
@@ -821,10 +944,11 @@ function loadCornerstoneMainImage(element, image, stack, db, load_as_stack) {
"WwwcRegion" "WwwcRegion"
); );
loadPrimaryDicomInterface(db); loadPrimaryDicomInterface(db, element);
loadAltDicomInterface(db); loadAltDicomInterface(db);
element.addEventListener("cornerstoneimagerendered", onImageRendered); element.addEventListener("cornerstoneimagerendered", onImageRendered);
//element.addEventListener("cornerstonetoolskeydown", keyDownHandler);
//setDicomCanvasNonFullscreen(element); //setDicomCanvasNonFullscreen(element);
cornerstone.reset(element); cornerstone.reset(element);
@@ -846,9 +970,9 @@ function loadCornerstoneMainImage(element, image, stack, db, load_as_stack) {
// .get(0) // .get(0)
// .addEventListener("change", changeControlSelection); // .addEventListener("change", changeControlSelection);
resizeHandler(); resizeHandler(element);
window.addEventListener("resize", resizeHandler); window.addEventListener("resize", () => { resizeHandler(element)});
element.addEventListener( element.addEventListener(
"contextmenu", "contextmenu",
function (e) { function (e) {
@@ -864,14 +988,13 @@ function loadCornerstoneMainImage(element, image, stack, db, load_as_stack) {
}); });
} }
function resizeHandler() { function resizeHandler(element) {
let element = document.getElementsByClassName("single-dicom-viewer")[0];
let h = window.innerHeight - $("#header").height() - 16; let h = window.innerHeight - $("#header").height() - 16;
$(element).height(h); $(element).height(h);
cornerstone.resize(element, true); cornerstone.resize(element, true);
} }
async function loadPrimaryDicomInterface(db) { async function loadPrimaryDicomInterface(db, element) {
const bindings = await dicom_settings_db.mouse_bindings.where({ const bindings = await dicom_settings_db.mouse_bindings.where({
mode: "0" mode: "0"
}).toArray().catch((err) => { }).toArray().catch((err) => {
@@ -884,7 +1007,7 @@ async function loadPrimaryDicomInterface(db) {
sel.value = b.tool; sel.value = b.tool;
//sel.dispatchEvent(new Event("change")); //sel.dispatchEvent(new Event("change"));
}); });
registerPrimaryDicomInterface(); registerPrimaryDicomInterface(element);
} }
async function loadAltDicomInterface(db) { async function loadAltDicomInterface(db) {
@@ -945,16 +1068,16 @@ function stopEvent(evt) {
evt.stopPropagation(); evt.stopPropagation();
} }
function selectThumbClick(evt) { function selectThumbClick(evt, element) {
let new_index = evt.currentTarget.dataset.id; let new_index = evt.currentTarget.dataset.id;
selectThumb(new_index); selectThumb(new_index, element);
evt.preventDefault(); evt.preventDefault();
} }
export function registerPrimaryDicomInterface() { export function registerPrimaryDicomInterface(element) {
console.log("reg primary")
// Set mousetools based upon the selected options // Set mousetools based upon the selected options
let element = document.getElementsByClassName("single-dicom-viewer")[0];
let selections = $("#primary-mouse-binding select"); let selections = $("#primary-mouse-binding select");
selections.each((i, option) => { selections.each((i, option) => {
cornerstoneTools.setToolActiveForElement(element, option.value, { cornerstoneTools.setToolActiveForElement(element, option.value, {
@@ -963,11 +1086,12 @@ export function registerPrimaryDicomInterface() {
}); });
} }
export function registerAltDicomInterface(e) { export function registerAltDicomInterface(e, element) {
// Called when control is pressed // Called when control is pressed
// Set mousetools based upon the selected options // Set mousetools based upon the selected options
let element = document.getElementsByClassName("single-dicom-viewer")[0]; //let element = document.getElementsByClassName("cornerstone-element")[0];
console.log("reg alt", element)
let selections = $("#secondary-mouse-binding select"); let selections = $("#secondary-mouse-binding select");
selections.each((i, option) => { selections.each((i, option) => {
cornerstoneTools.setToolActiveForElement(element, option.value, { cornerstoneTools.setToolActiveForElement(element, option.value, {
@@ -976,8 +1100,8 @@ export function registerAltDicomInterface(e) {
}); });
} }
function changeMouseBinding(e, db) { function changeMouseBinding(evt, db, element) {
let select = e.currentTarget; let select = evt.currentTarget;
let button = select.dataset.button; let button = select.dataset.button;
let mode = select.dataset.mode; let mode = select.dataset.mode;
let tool = select.value; let tool = select.value;
@@ -985,7 +1109,6 @@ function changeMouseBinding(e, db) {
// Directly activate primary tools (secondary will be activated when modifier // Directly activate primary tools (secondary will be activated when modifier
// key is pressed // key is pressed
if (mode == "0") { if (mode == "0") {
let element = document.getElementsByClassName("single-dicom-viewer")[0];
cornerstoneTools.setToolActiveForElement(element, tool, { cornerstoneTools.setToolActiveForElement(element, tool, {
mouseButtonMask: parseInt(button) mouseButtonMask: parseInt(button)
}); });
@@ -999,10 +1122,9 @@ function changeMouseBinding(e, db) {
//db.mouse_bindings.put({button: button, mode: mode, tool: tool}).then(loadPrimaryDicomInterface()); //db.mouse_bindings.put({button: button, mode: mode, tool: tool}).then(loadPrimaryDicomInterface());
} }
export function selectThumb(new_index) { export function selectThumb(new_index, dicom_element) {
//console.log("select thumb new index", new_index); //console.log("select thumb new index", new_index);
// There must be a better way to do this... // There must be a better way to do this...
let dicom_element = document.getElementsByClassName("single-dicom-viewer")[0];
if (dicom_element == null) { if (dicom_element == null) {
return; return;
} }