diff --git a/dicomViewer.js b/dicomViewer.js index 26e6e56..15323c4 100644 --- a/dicomViewer.js +++ b/dicomViewer.js @@ -9,7 +9,7 @@ cornerstoneBase64ImageLoader.external.cornerstone = cornerstone; cornerstoneWebImageLoader.external.cornerstone = cornerstone; cornerstoneWADOImageLoader.external.cornerstone = cornerstone; -cornerstoneTools.init({keyboardEnabled: true}); +cornerstoneTools.init({ keyboardEnabled: true }); let tool_state = {}; @@ -314,7 +314,6 @@ export function loadCornerstone(main_element, db, images, annotations_to_load, l `)); - //console.log(cornerstone_element); canvas_panel.append($(`
close @@ -322,7 +321,7 @@ export function loadCornerstone(main_element, db, images, annotations_to_load, l // Add generic settings menus to canvas-panel $(".canvas-panel").append( - $(`
+ $(`
close view log

Image viewer settings:

@@ -384,7 +383,7 @@ export function loadCornerstone(main_element, db, images, annotations_to_load, l
`) - ) + ) .append($("")) .append($("")) .append($("")) @@ -421,8 +420,6 @@ export function loadCornerstone(main_element, db, images, annotations_to_load, l $("#dicom-window-panel button").each((n, el) => { $(el).click((e) => { - //console.log(e); - //console.log(e.target); let button_id = e.target.id; let [ww, wc] = window_presets[button_id]; @@ -458,6 +455,13 @@ export function loadCornerstone(main_element, db, images, annotations_to_load, l $("#dicom-settings-panel").toggle(); }); $("#dicom-info-button").click(e => { + try { + // todo improve + dumpDataSet(cornerstone.getEnabledElement(element).image.data); + } catch { + console.log("unable to extract dicom data") + + } $("#dicom-summary-panel").toggle(); }); $("#dicom-fullscreen-button").click(e => { @@ -501,7 +505,6 @@ export function loadCornerstone(main_element, db, images, annotations_to_load, l images = [images]; } - //console.log("Images", images) //let annotations = []; //if (annotations_to_load) { @@ -514,11 +517,9 @@ export function loadCornerstone(main_element, db, images, annotations_to_load, l if (!Array.isArray(annotations)) { annotations = [annotations]; } - //console.log("annon", annotations); function loadAnnotation(imageId, annotation) { - //console.log("loadAnnotations", imageId, annotation); const toolStateManager = cornerstoneTools.globalImageIdSpecificToolStateManager; if (annotation == undefined || annotation.length < 1 || annotation == [undefined]) { @@ -533,7 +534,6 @@ export function loadCornerstone(main_element, db, images, annotations_to_load, l } async function load(images, annotations) { - console.log("LOAD", images); let imageIds = []; for (let i = 0; i < images.length; i++) { let data_url = images[i]; @@ -597,12 +597,16 @@ export function loadCornerstone(main_element, db, images, annotations_to_load, l imageIds }; //cornerstone.loadAndCacheImage(imageIds[0]).then(function(image) { - //console.log("load and cache", imageIds[0]) cornerstone.loadAndCacheImage(imageIds[0]).then(function (image) { - //console.log("LOAD and cache, then", image); - loadCornerstoneMainImage(element, image, stack, db, load_as_stack); - }) + //console.log("LOAD and cache, then", image); + loadCornerstoneMainImage(element, image, stack, db, load_as_stack); + + let load_annotation_image = true; + if (load_annotation_image) { + getNextAnnotationImage(element) + } + }) .catch((err, err2) => { console.log(err); $("#dicom-log-panel").append("
").append(err.stack); @@ -646,7 +650,6 @@ export function loadCornerstone(main_element, db, images, annotations_to_load, l let img; - //console.log("load thumb", image_url); if (image_url.startsWith("data")) { // based (image) data url, just load the image directly @@ -674,7 +677,7 @@ export function loadCornerstone(main_element, db, images, annotations_to_load, l ); cornerstone.loadAndCacheImage(imageId).then(function (image) { loadCornerstoneThumb(image, id); - }); + }); }); } } else { @@ -708,127 +711,123 @@ export function loadCornerstone(main_element, db, images, annotations_to_load, l load(images, annotations); - console.log(main_element) + main_element.keydown((evt) => { keyDownHandler(evt, element) }); + main_element.keyup((evt) => { keyUpHandler(evt, 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; - } + 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) + //// 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; + // } + //} - if (e.key == "Control") { - if (window.control_pressed != true) { - window.control_pressed = true; - registerAltDicomInterface(e, element); + 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; + 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 {} - } + function numberKeyPressed(e, x) { + if (e.altKey ? true : false) { + loadStackIndex(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; + switch (charCode) { + case 13: // Return + getNextAnnotationImage(element); + 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; + // 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; + 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; - } + // 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) { - //dumpDataSet(image.data) - //console.log("loadCornerstoneMainImage") - //console.log("load as stack:", load_as_stack) // It is probably silly to do this each time we load a question const PanTool = cornerstoneTools.PanTool; const ZoomTool = cornerstoneTools.ZoomTool; @@ -843,7 +842,6 @@ function loadCornerstoneMainImage(element, image, stack, db, load_as_stack) { const RectangleRoiTool = cornerstoneTools.RectangleRoiTool; const LengthTool = cornerstoneTools.LengthTool; - //console.log("enable element", element); cornerstone.enable(element); element.tabIndex = 0; @@ -869,8 +867,8 @@ function loadCornerstoneMainImage(element, image, stack, db, load_as_stack) { cornerstoneTools.addToolForElement(element, ArrowAnnotateTool, { configuration: { - getTextCallback: () => {}, - changeTextCallback: () => {}, + getTextCallback: () => { }, + changeTextCallback: () => { }, allowEmptyLabel: true, renderDashed: false, drawHandles: false, @@ -888,7 +886,8 @@ function loadCornerstoneMainImage(element, image, stack, db, load_as_stack) { }, }); - cornerstoneTools.setToolEnabledForElement(element, "ArrowAnnotate"); + //cornerstoneTools.setToolEnabledForElement(element, "ArrowAnnotate"); + //cornerstoneTools.setToolEnabledForElement(element, ArrowAnnotateTool); let available_tools = [ @@ -922,7 +921,6 @@ function loadCornerstoneMainImage(element, image, stack, db, load_as_stack) { $("#primary-mouse-binding .mouse-binding-select[data-button=4]").val("Zoom"); //cornerstoneTools.setToolActive("Pan", { mouseButtonMask: 1 }); - //console.log(load_as_stack); if (load_as_stack) { cornerstoneTools.setToolActiveForElement(element, "StackScrollMouseWheel", { mouseButtonMask: 3 @@ -972,7 +970,7 @@ function loadCornerstoneMainImage(element, image, stack, db, load_as_stack) { resizeHandler(element); - window.addEventListener("resize", () => { resizeHandler(element)}); + window.addEventListener("resize", () => { resizeHandler(element) }); element.addEventListener( "contextmenu", function (e) { @@ -1027,14 +1025,6 @@ async function loadAltDicomInterface(db) { // Called when the dicom image is loaded / rendered function onImageRendered(e) { const eventData = e.detail; - //console.log(e); - try { - // todo improve - dumpDataSet(eventData.image.data); - } catch { - console.log("unable to extract dicom data") - - } // Update ww/wl $("#wc").text(Math.round(eventData.viewport.voi.windowCenter)); @@ -1070,7 +1060,7 @@ function stopEvent(evt) { function selectThumbClick(evt, element) { let new_index = evt.currentTarget.dataset.id; - selectThumb(new_index, element); + loadStackIndex(new_index, element); evt.preventDefault(); } @@ -1122,8 +1112,8 @@ function changeMouseBinding(evt, db, element) { //db.mouse_bindings.put({button: button, mode: mode, tool: tool}).then(loadPrimaryDicomInterface()); } -export function selectThumb(new_index, dicom_element) { - //console.log("select thumb new index", new_index); +export function loadStackIndex(new_index, dicom_element) { + console.log("select new stack index", new_index); // There must be a better way to do this... if (dicom_element == null) { return; @@ -1183,4 +1173,27 @@ function dumpDataSet(dataSet) { $(value).text(text); }); +} + +export function getNextAnnotationImage(element) { + const enabled_element = cornerstone.getEnabledElement(element) + const image_ids = enabled_element.toolStateManager.toolState.stack.data[0].imageIds; + const current_image = enabled_element.toolStateManager.toolState.stack.data[0].currentImageIdIndex; + const annotated_images = Object.getOwnPropertyNames(cornerstoneTools.globalImageIdSpecificToolStateManager.toolState); + console.log("getNextAnnotationImage", image_ids, current_image, annotated_images); + + if (annotated_images.length > 0) { + let offset = current_image; + for( let i=0; i < image_ids.length; i++) { + console.log("i", i) + let pointer = (i + offset) % image_ids.length; + console.log("pointer", pointer, image_ids[pointer]); + console.log(annotated_images); + if (annotated_images.includes(image_ids[pointer])) { + console.log("load") + loadStackIndex(pointer, element); + + } + } + } } \ No newline at end of file