start working towards new viewer
This commit is contained in:
@@ -497,6 +497,20 @@ td {
|
|||||||
box-shadow: 0 0 0 3px #4527A0;
|
box-shadow: 0 0 0 3px #4527A0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* .short-option-answer {
|
||||||
|
width: 100%;
|
||||||
|
display: block;
|
||||||
|
border: 1px solid #4527A0;
|
||||||
|
margin: 0.8rem 1.6rem 1.6rem 1.6rem;
|
||||||
|
overflow: hidden;
|
||||||
|
resize: none;
|
||||||
|
padding: 0.4rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.short-option-answer:focus {
|
||||||
|
box-shadow: 0 0 0 3px #4527A0;
|
||||||
|
} */
|
||||||
|
|
||||||
img {
|
img {
|
||||||
display: block;
|
display: block;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
@@ -1124,4 +1138,33 @@ h2:has(+ #exam-list:empty), h2:has(+ #packet-list:empty){
|
|||||||
#exam-list:empty::after, #packet-list:empty::after{
|
#exam-list:empty::after, #packet-list:empty::after{
|
||||||
content: "None available.";
|
content: "None available.";
|
||||||
opacity: 30%;
|
opacity: 30%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#viewer-title-bar {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
padding: 0.8rem 1.6rem;
|
||||||
|
background-color: gray;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title-bar-button {
|
||||||
|
display: inline-flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
border: none;
|
||||||
|
margin: 0 0 0 2px;
|
||||||
|
background-color: gray;
|
||||||
|
color: white;
|
||||||
|
border-left: 1px solid white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.viewer-icon {
|
||||||
|
margin: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title-bar-button:hover {
|
||||||
|
background-color: darkgray;
|
||||||
}
|
}
|
||||||
+214
-2
@@ -515,6 +515,15 @@ async function loadExamList(data) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Sort different lists
|
// Sort different lists
|
||||||
|
$(".packet-list.short div")
|
||||||
|
.sort(function(a, b) {
|
||||||
|
return a.dataset.eid > b.dataset.eid ?
|
||||||
|
1 :
|
||||||
|
a.dataset.eid < b.dataset.eid ?
|
||||||
|
-1 :
|
||||||
|
0;
|
||||||
|
})
|
||||||
|
.appendTo(".packet-list.short");
|
||||||
$(".packet-list.rapid div")
|
$(".packet-list.rapid div")
|
||||||
.sort(function(a, b) {
|
.sort(function(a, b) {
|
||||||
return a.dataset.eid > b.dataset.eid ?
|
return a.dataset.eid > b.dataset.eid ?
|
||||||
@@ -1040,6 +1049,8 @@ function setUpQuestions(load_previous) {
|
|||||||
if (!load_previous && exam_time == null) {
|
if (!load_previous && exam_time == null) {
|
||||||
if (question_type == "rapid") {
|
if (question_type == "rapid") {
|
||||||
exam_time = 35 * 60;
|
exam_time = 35 * 60;
|
||||||
|
} else if (question_type == "short") {
|
||||||
|
exam_time = 120 * 60;
|
||||||
} else if (question_type == "anatomy") {
|
} else if (question_type == "anatomy") {
|
||||||
exam_time = 90 * 60;
|
exam_time = 90 * 60;
|
||||||
} else if (question_type == "long") {
|
} else if (question_type == "long") {
|
||||||
@@ -1291,6 +1302,138 @@ async function loadQuestion(n, section = 1, force_reload = false) {
|
|||||||
ap.empty();
|
ap.empty();
|
||||||
|
|
||||||
switch (question_data.type) {
|
switch (question_data.type) {
|
||||||
|
case "short": {
|
||||||
|
ap.append(
|
||||||
|
'<div class="answer-item"><div class="answer-label-outer"><p class="answer-label-inner"><span class="answer-label-number">' +
|
||||||
|
display_n +
|
||||||
|
'.1</span><span style="flex:1">Case normal/abnormal</span><button class="flag" data-qid="' +
|
||||||
|
n +
|
||||||
|
'" data-qidn=1 style="margin-right:0">⚐</button></p></div><select class="rapid-option-answer" id="rapid-option" data-answer-section-qidn=1><option selected="selected" disabled="disabled" id="rapid-option-not-answered">--- Not Answered ---</option><option>Abnormal</option><option>Normal</option></select></div>'
|
||||||
|
);
|
||||||
|
ap.append(
|
||||||
|
'<div class="answer-item" id="rapid-text" style="display: none;"><div class="answer-label-outer"><p class="answer-label-inner"><span class="answer-label-number">' +
|
||||||
|
display_n +
|
||||||
|
'.2</span><span style="flex:1">Reason</span><button class="flag" data-qid="' +
|
||||||
|
n +
|
||||||
|
'" data-qidn=2 style="margin-right:0">⚐</button></p></div><textarea class="long-answer" name="Reason" data-answer-section-qidn=2 style="overflow: hidden scroll; overflow-wrap: break-word;"></textarea></div>'
|
||||||
|
);
|
||||||
|
// Handle changing display of optional answer fields and saving of data
|
||||||
|
$("#rapid-option").change(function(evt) {
|
||||||
|
if (evt.target.value == "Abnormal") {
|
||||||
|
$("#rapid-text").css("display", "block");
|
||||||
|
} else {
|
||||||
|
$("#rapid-text").css("display", "none");
|
||||||
|
}
|
||||||
|
|
||||||
|
let answer = {
|
||||||
|
aid: aid,
|
||||||
|
cid: cid,
|
||||||
|
eid: eid,
|
||||||
|
qid: qid,
|
||||||
|
qidn: "1",
|
||||||
|
passcode: passcode,
|
||||||
|
ans: evt.target.value,
|
||||||
|
};
|
||||||
|
|
||||||
|
db.answers.put(answer);
|
||||||
|
console.debug("Save ", answer)
|
||||||
|
saveSession();
|
||||||
|
updateQuestionListPanel(answer);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Save long answers on textchange
|
||||||
|
$(".long-answer").change(function(evt) {
|
||||||
|
// ignore blank text and delete any stored value
|
||||||
|
if (evt.target.value.length < 1) {
|
||||||
|
db.answers.delete([aid, cid, eid, qid, "2"]);
|
||||||
|
$(
|
||||||
|
"#question-list-item-" +
|
||||||
|
exam_details.question_order.indexOf(qid) +
|
||||||
|
"-2"
|
||||||
|
).removeClass("question-saved-localdb");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let answer = {
|
||||||
|
aid: aid,
|
||||||
|
cid: cid,
|
||||||
|
eid: eid,
|
||||||
|
qid: qid,
|
||||||
|
qidn: "2",
|
||||||
|
passcode: passcode,
|
||||||
|
ans: evt.target.value,
|
||||||
|
};
|
||||||
|
// db.answers.put({aid: [cid, eid, qidn], ans: evt.target.value});
|
||||||
|
console.debug("Save ", answer)
|
||||||
|
db.answers.put(answer);
|
||||||
|
|
||||||
|
$(
|
||||||
|
"#question-list-item-" +
|
||||||
|
exam_details.question_order.indexOf(qid) +
|
||||||
|
"-2"
|
||||||
|
).addClass("question-saved-localdb");
|
||||||
|
|
||||||
|
saveSession();
|
||||||
|
updateQuestionListPanel(answer);
|
||||||
|
});
|
||||||
|
|
||||||
|
// We chain our db requests as we can only check answers once
|
||||||
|
// they have been loaded (should probably use then or after)
|
||||||
|
|
||||||
|
console.debug("Load rapid answers")
|
||||||
|
db.answers
|
||||||
|
.get({
|
||||||
|
aid: aid,
|
||||||
|
cid: cid,
|
||||||
|
eid: eid,
|
||||||
|
qid: qid,
|
||||||
|
passcode: passcode,
|
||||||
|
qidn: "1"
|
||||||
|
})
|
||||||
|
.then(function(answer) {
|
||||||
|
if (answer != undefined) {
|
||||||
|
$("#rapid-option option:contains(" + answer.ans + ")").prop(
|
||||||
|
"selected",
|
||||||
|
true
|
||||||
|
);
|
||||||
|
// For some reason a change event is not fired...
|
||||||
|
if (answer.ans == "Abnormal") {
|
||||||
|
$("#rapid-text").css("display", "block");
|
||||||
|
}
|
||||||
|
$("#rapid-option-not-answered").remove();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(function(error) {
|
||||||
|
console.debug("DB", cid, eid, qid);
|
||||||
|
console.debug("error-", error);
|
||||||
|
})
|
||||||
|
//.then(function() {
|
||||||
|
db.answers
|
||||||
|
.get({
|
||||||
|
aid: aid,
|
||||||
|
cid: cid,
|
||||||
|
eid: eid,
|
||||||
|
qid: qid,
|
||||||
|
qidn: "2",
|
||||||
|
passcode: passcode,
|
||||||
|
})
|
||||||
|
.then(function(answer) {
|
||||||
|
if (answer != undefined) {
|
||||||
|
$(".long-answer").text(answer.ans);
|
||||||
|
}
|
||||||
|
markAnswer(qid, question_data, n);
|
||||||
|
})
|
||||||
|
.catch(function(error) {
|
||||||
|
console.debug("error-", error);
|
||||||
|
})
|
||||||
|
//});
|
||||||
|
|
||||||
|
addFlagEvents();
|
||||||
|
loadFlagsFromDb(qid, "1");
|
||||||
|
loadFlagsFromDb(qid, "2");
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
case "rapid": {
|
case "rapid": {
|
||||||
ap.append(
|
ap.append(
|
||||||
'<div class="answer-item"><div class="answer-label-outer"><p class="answer-label-inner"><span class="answer-label-number">' +
|
'<div class="answer-item"><div class="answer-label-outer"><p class="answer-label-inner"><span class="answer-label-number">' +
|
||||||
@@ -1646,7 +1789,7 @@ function updateQuestionListPanel(answer) {
|
|||||||
answer.qidn
|
answer.qidn
|
||||||
).addClass("question-saved-localdb");
|
).addClass("question-saved-localdb");
|
||||||
|
|
||||||
if (question_type == "rapid" && answer.qidn == "1") {
|
if ((question_type == "rapid" || question_type == "short") && answer.qidn == "1") {
|
||||||
if (answer.ans == "Abnormal") {
|
if (answer.ans == "Abnormal") {
|
||||||
$(
|
$(
|
||||||
"#question-list-item-" +
|
"#question-list-item-" +
|
||||||
@@ -1795,6 +1938,12 @@ function createQuestionListPanel() {
|
|||||||
appendQuestionListItem(n, "1");
|
appendQuestionListItem(n, "1");
|
||||||
appendQuestionListItem(n, "2").hide();
|
appendQuestionListItem(n, "2").hide();
|
||||||
}
|
}
|
||||||
|
} else if (question_type == "short") {
|
||||||
|
// Loop through all questions and append list items
|
||||||
|
for (let n = 1; n < exam_details.number_of_questions + 1; n++) {
|
||||||
|
appendQuestionListItem(n, "1");
|
||||||
|
appendQuestionListItem(n, "2").hide();
|
||||||
|
}
|
||||||
} else if (question_type == "anatomy") {
|
} else if (question_type == "anatomy") {
|
||||||
for (let n = 1; n < exam_details.number_of_questions + 1; n++) {
|
for (let n = 1; n < exam_details.number_of_questions + 1; n++) {
|
||||||
appendQuestionListItem(n, "1");
|
appendQuestionListItem(n, "1");
|
||||||
@@ -2194,6 +2343,69 @@ function reviewQuestions() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (question_type == "short") {
|
||||||
|
// First check normal vs abnormal
|
||||||
|
if (question["normal"] == true) {
|
||||||
|
if (section_1_answer == "Normal") {
|
||||||
|
setReviewAnswer(
|
||||||
|
el,
|
||||||
|
"correct",
|
||||||
|
section_1_answer,
|
||||||
|
true,
|
||||||
|
question_answers
|
||||||
|
);
|
||||||
|
correct_count++;
|
||||||
|
questions_correct[qid] = true;
|
||||||
|
} else {
|
||||||
|
if (section_1_answer != "Not Answered") {
|
||||||
|
overcall_number++;
|
||||||
|
}
|
||||||
|
setReviewAnswer(
|
||||||
|
el,
|
||||||
|
"incorrect",
|
||||||
|
section_1_answer,
|
||||||
|
true,
|
||||||
|
question_answers
|
||||||
|
);
|
||||||
|
questions_correct[qid] = false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (answerInArray(question_answers, section_2_answer)) {
|
||||||
|
correct_count++;
|
||||||
|
setReviewAnswer(
|
||||||
|
el,
|
||||||
|
"correct",
|
||||||
|
section_2_answer,
|
||||||
|
false,
|
||||||
|
question_answers
|
||||||
|
);
|
||||||
|
questions_correct[qid] = true;
|
||||||
|
} else {
|
||||||
|
setReviewAnswer(
|
||||||
|
el,
|
||||||
|
"incorrect",
|
||||||
|
section_2_answer,
|
||||||
|
false,
|
||||||
|
question_answers
|
||||||
|
);
|
||||||
|
questions_correct[qid] = false;
|
||||||
|
|
||||||
|
if (section_1_answer == "Not Answered") {} else if (section_1_answer == "Normal") {
|
||||||
|
undercall_number++;
|
||||||
|
} else {
|
||||||
|
// Incorrect calls could be correct if
|
||||||
|
// the answer is not in the database
|
||||||
|
incorrectcall_number++;
|
||||||
|
|
||||||
|
el.append(
|
||||||
|
"<span class='mark-correct'>[Mark correct]</span>"
|
||||||
|
).click(() => {
|
||||||
|
markCorrect(qid, section_2_answer, question_type);
|
||||||
|
reviewQuestions();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
} else if (question_type == "anatomy") {
|
} else if (question_type == "anatomy") {
|
||||||
// Anatomy answers are either correct or incorrect
|
// Anatomy answers are either correct or incorrect
|
||||||
if (answerInArray(question_answers, section_1_answer)) {
|
if (answerInArray(question_answers, section_1_answer)) {
|
||||||
@@ -2278,7 +2490,7 @@ function markAnswer(qid, current_question, n) {
|
|||||||
$(".long-answer").attr("readonly", "true");
|
$(".long-answer").attr("readonly", "true");
|
||||||
$(".long-answer").addClass("long-answer-marked");
|
$(".long-answer").addClass("long-answer-marked");
|
||||||
|
|
||||||
if (type == "rapid") {
|
if (type == "rapid" || type == "short") {
|
||||||
option = document.getElementById("rapid-option");
|
option = document.getElementById("rapid-option");
|
||||||
// If the current question is normal
|
// If the current question is normal
|
||||||
if (current_question.normal == true) {
|
if (current_question.normal == true) {
|
||||||
|
|||||||
+85
-44
@@ -11,6 +11,9 @@ export function loadMainImage(image, stack) {
|
|||||||
const RotateTool = cornerstoneTools.RotateTool;
|
const RotateTool = cornerstoneTools.RotateTool;
|
||||||
const StackScrollTool = cornerstoneTools.StackScrollTool;
|
const StackScrollTool = cornerstoneTools.StackScrollTool;
|
||||||
const ArrowAnnotateTool = cornerstoneTools.ArrowAnnotateTool;
|
const ArrowAnnotateTool = cornerstoneTools.ArrowAnnotateTool;
|
||||||
|
const LengthTool = cornerstoneTools.LengthTool;
|
||||||
|
const RectangleRoiTool = cornerstoneTools.RectangleRoiTool;
|
||||||
|
const EllipseRoiTool = cornerstoneTools.EllipseRoiTool;
|
||||||
const AngleTool = cornerstoneTools.AngleTool;
|
const AngleTool = cornerstoneTools.AngleTool;
|
||||||
const CobbAngleTool = cornerstoneTools.CobbAngleTool;
|
const CobbAngleTool = cornerstoneTools.CobbAngleTool;
|
||||||
const EraserTool = cornerstoneTools.EraserTool;
|
const EraserTool = cornerstoneTools.EraserTool;
|
||||||
@@ -35,6 +38,9 @@ export function loadMainImage(image, stack) {
|
|||||||
cornerstoneTools.addToolForElement(element, CobbAngleTool);
|
cornerstoneTools.addToolForElement(element, CobbAngleTool);
|
||||||
cornerstoneTools.addToolForElement(element, StackScrollTool);
|
cornerstoneTools.addToolForElement(element, StackScrollTool);
|
||||||
cornerstoneTools.addToolForElement(element, EraserTool);
|
cornerstoneTools.addToolForElement(element, EraserTool);
|
||||||
|
cornerstoneTools.addToolForElement(element, LengthTool);
|
||||||
|
cornerstoneTools.addToolForElement(element, RectangleRoiTool);
|
||||||
|
//cornerstoneTools.addToolForElement(element, EllipseRoiTool);
|
||||||
|
|
||||||
cornerstoneTools.addToolForElement(element, ArrowAnnotateTool, {
|
cornerstoneTools.addToolForElement(element, ArrowAnnotateTool, {
|
||||||
configuration: {
|
configuration: {
|
||||||
@@ -58,15 +64,17 @@ export function loadMainImage(image, stack) {
|
|||||||
|
|
||||||
setDicomCanvasNonFullscreen(element);
|
setDicomCanvasNonFullscreen(element);
|
||||||
cornerstone.reset(element);
|
cornerstone.reset(element);
|
||||||
element.scrollIntoView(false);
|
let viewerTitleBar = document.getElementById("viewer-title-bar");
|
||||||
// element.scrollTo(0);
|
viewerTitleBar.scrollIntoView();
|
||||||
|
//element.scrollIntoView(false);
|
||||||
|
//element.scrollTo(0);
|
||||||
|
|
||||||
$(element).dblclick(function () {
|
$(element).dblclick(function () {
|
||||||
if ($(".canvas-panel").length == 0) {
|
if ($(".canvas-panel").length == 0) {
|
||||||
// already fullscreen (disable it)
|
// already fullscreen (disable it)
|
||||||
disableFullscreen(this);
|
disableFullscreen(this);
|
||||||
} else {
|
} else {
|
||||||
$(".content-panel").append($(".canvas-panel"));
|
$(".content-panel").prepend($(".canvas-panel"));
|
||||||
$(".canvas-panel").toggleClass("canvas-panel canvas-panel-fullscreen");
|
$(".canvas-panel").toggleClass("canvas-panel canvas-panel-fullscreen");
|
||||||
$("#dicom-image").attr("height", "100%");
|
$("#dicom-image").attr("height", "100%");
|
||||||
$("#dicom-image").height("100%");
|
$("#dicom-image").height("100%");
|
||||||
@@ -78,28 +86,7 @@ export function loadMainImage(image, stack) {
|
|||||||
|
|
||||||
element.removeEventListener("wheel", element.wheelEventHandler);
|
element.removeEventListener("wheel", element.wheelEventHandler);
|
||||||
|
|
||||||
// Add tool selector
|
$(".dicom-select-control")
|
||||||
$(".canvas-panel").append(
|
|
||||||
'<select class="control-overlay"> \
|
|
||||||
<option value="pan">pan [p]</option> \
|
|
||||||
<option value="zoom">zoom [z]</option> \
|
|
||||||
<option value="rotate">rotate [r]</option> \
|
|
||||||
<option value="angle">angle</option> \
|
|
||||||
<option value="cobbangle">cobb angle</option> \
|
|
||||||
<option value="eraser">eraser</option> \
|
|
||||||
<option value="scroll" hidden="" disabled="">scroll (1/1)</option> \
|
|
||||||
<option value="window">window ()</option> \
|
|
||||||
<option value="abdomen" hidden="" disabled="">window = abdomen [a]</option> \
|
|
||||||
<option value="pulmonary" hidden="" disabled="">window = pulmonary [u]</option> \
|
|
||||||
<option value="brain" hidden="" disabled="">window = brain [b]</option> \
|
|
||||||
<option value="bone" hidden="" disabled="">window = bone [o]</option> \
|
|
||||||
<option value="reset">reset [e]</option> \
|
|
||||||
<option value="close">close [c]</option> \
|
|
||||||
<option disabled="true" value="notes">[modality = CR][size = 9.8]</option> \
|
|
||||||
</select>'
|
|
||||||
);
|
|
||||||
|
|
||||||
$(".control-overlay")
|
|
||||||
.get(0)
|
.get(0)
|
||||||
.addEventListener("change", function () {
|
.addEventListener("change", function () {
|
||||||
changeControlSelection();
|
changeControlSelection();
|
||||||
@@ -117,7 +104,7 @@ function onImageRendered(e) {
|
|||||||
const eventData = e.detail;
|
const eventData = e.detail;
|
||||||
|
|
||||||
// Update ww/wl
|
// Update ww/wl
|
||||||
const sel = $(".control-overlay").get(0);
|
const sel = $(".dicom-select-control").get(0);
|
||||||
sel.options[find_option(sel, "window")].firstChild.textContent =
|
sel.options[find_option(sel, "window")].firstChild.textContent =
|
||||||
"window (" +
|
"window (" +
|
||||||
Math.round(eventData.viewport.voi.windowCenter) +
|
Math.round(eventData.viewport.voi.windowCenter) +
|
||||||
@@ -176,7 +163,7 @@ export function disableFullscreen(dicom_element) {
|
|||||||
$(".canvas-panel-fullscreen").toggleClass(
|
$(".canvas-panel-fullscreen").toggleClass(
|
||||||
"canvas-panel canvas-panel-fullscreen"
|
"canvas-panel canvas-panel-fullscreen"
|
||||||
);
|
);
|
||||||
$(".question").append($(".canvas-panel"));
|
$(".question").prepend($(".canvas-panel"));
|
||||||
$(".canvas-panel").get(0).scrollIntoView();
|
$(".canvas-panel").get(0).scrollIntoView();
|
||||||
|
|
||||||
setDicomCanvasNonFullscreen(dicom_element);
|
setDicomCanvasNonFullscreen(dicom_element);
|
||||||
@@ -284,7 +271,7 @@ export function debugCornerstone() {
|
|||||||
*/
|
*/
|
||||||
export function changeControlSelection() {
|
export function changeControlSelection() {
|
||||||
// We also duplicate the sel that are available
|
// We also duplicate the sel that are available
|
||||||
const sel = $(".control-overlay").get(0);
|
const sel = $(".dicom-select-control").get(0);
|
||||||
|
|
||||||
const old = sel.oldSelectedIndex;
|
const old = sel.oldSelectedIndex;
|
||||||
sel.oldSelectedIndex = sel.selectedIndex;
|
sel.oldSelectedIndex = sel.selectedIndex;
|
||||||
@@ -309,6 +296,25 @@ export function changeControlSelection() {
|
|||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case "measure": {
|
||||||
|
cornerstoneTools.setToolActiveForElement(dicom_element, "Length", {
|
||||||
|
mouseButtonMask: 1,
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "rectangle": {
|
||||||
|
cornerstoneTools.setToolActiveForElement(dicom_element, "RectangleRoi", {
|
||||||
|
mouseButtonMask: 1,
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "ellipse": {
|
||||||
|
cornerstoneTools.setToolActiveForElement(dicom_element, "EllipseRoi", {
|
||||||
|
mouseButtonMask: 1,
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case "angle": {
|
case "angle": {
|
||||||
cornerstoneTools.setToolActiveForElement(dicom_element, "Angle", {
|
cornerstoneTools.setToolActiveForElement(dicom_element, "Angle", {
|
||||||
mouseButtonMask: 1,
|
mouseButtonMask: 1,
|
||||||
@@ -384,18 +390,7 @@ export function changeControlSelection() {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "close": {
|
case "close": {
|
||||||
// disable fullscreen if required
|
closeViewer(dicom_element);
|
||||||
if ($(".canvas-panel").length == 0) {
|
|
||||||
disableFullscreen(dicom_element);
|
|
||||||
}
|
|
||||||
if (dicom_element != undefined) {
|
|
||||||
// See https://github.com/cornerstonejs/cornerstoneTools/issues/1337
|
|
||||||
cornerstone.removeElementData(dicom_element);
|
|
||||||
cornerstone.disable(dicom_element);
|
|
||||||
$(".canvas-panel").remove();
|
|
||||||
$(".figure-open").removeClass("figure-open").addClass("figure");
|
|
||||||
$(dicom_element).remove();
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -424,7 +419,7 @@ export function keydown_handler(event) {
|
|||||||
if (target_element == "INPUT" || target_element == "TEXTAREA") {
|
if (target_element == "INPUT" || target_element == "TEXTAREA") {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const sel = $(".control-overlay").get(0);
|
const sel = $(".dicom-select-control").get(0);
|
||||||
switch (event.code) {
|
switch (event.code) {
|
||||||
case "KeyP":
|
case "KeyP":
|
||||||
sel.selectedIndex = find_option(sel, "pan");
|
sel.selectedIndex = find_option(sel, "pan");
|
||||||
@@ -660,7 +655,7 @@ export function openMainImage(current_question, t, source) {
|
|||||||
// No full size figure / dicom loaded yet
|
// No full size figure / dicom loaded yet
|
||||||
if (figure_to_load == open_figure) {
|
if (figure_to_load == open_figure) {
|
||||||
// Scroll to the image if it is already open
|
// Scroll to the image if it is already open
|
||||||
document.getElementById("dicom-image").scrollIntoView();
|
document.getElementById("viewer-title-bar").scrollIntoView();
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
let el;
|
let el;
|
||||||
@@ -678,8 +673,33 @@ export function openMainImage(current_question, t, source) {
|
|||||||
|
|
||||||
source.className = "figure-open";
|
source.className = "figure-open";
|
||||||
|
|
||||||
$(".question").append(
|
$(".question").prepend(
|
||||||
'<div class= "canvas-panel"><div id="dicom-image" data-figure="' +
|
`<div class= "canvas-panel">
|
||||||
|
<div id="viewer-title-bar">
|
||||||
|
<div><div>Sample Title [REPLACE]</div></div>
|
||||||
|
<select title="SELECT CLICK ACTION" class="dicom-select-control title-bar-button">
|
||||||
|
<option value="pan">pan [p]</option>
|
||||||
|
<option value="zoom">zoom [z]</option>
|
||||||
|
<option value="rotate">rotate [r]</option>
|
||||||
|
<option value="window">window (128 ± 127.5) [w]</option>
|
||||||
|
<option value="measure">measure [m]</option>
|
||||||
|
<option value="ellipse">ellipse [l]</option>
|
||||||
|
<option value="rectangle">rectangle [c]</option>
|
||||||
|
<option value="reset">reset [e]</option>
|
||||||
|
<option value="notes" disabled="true">[modality = SC]</option>
|
||||||
|
</select>
|
||||||
|
<button class="title-bar-button" title="RESET VIEW" class="reset"><span class="viewer-icon"><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-arrow-counterclockwise" viewBox="0 0 16 16">
|
||||||
|
<path fill-rule="evenodd" d="M8 3a5 5 0 1 1-4.546 2.914.5.5 0 0 0-.908-.417A6 6 0 1 0 8 2z"/>
|
||||||
|
<path d="M8 4.466V.534a.25.25 0 0 0-.41-.192L5.23 2.308a.25.25 0 0 0 0 .384l2.36 1.966A.25.25 0 0 0 8 4.466"/>
|
||||||
|
</svg></span></button>
|
||||||
|
<button class="title-bar-button" title="TOGGLE FULLSCREEN" class="expand"><span class="viewer-icon"><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-fullscreen" viewBox="0 0 16 16">
|
||||||
|
<path d="M1.5 1a.5.5 0 0 0-.5.5v4a.5.5 0 0 1-1 0v-4A1.5 1.5 0 0 1 1.5 0h4a.5.5 0 0 1 0 1zM10 .5a.5.5 0 0 1 .5-.5h4A1.5 1.5 0 0 1 16 1.5v4a.5.5 0 0 1-1 0v-4a.5.5 0 0 0-.5-.5h-4a.5.5 0 0 1-.5-.5M.5 10a.5.5 0 0 1 .5.5v4a.5.5 0 0 0 .5.5h4a.5.5 0 0 1 0 1h-4A1.5 1.5 0 0 1 0 14.5v-4a.5.5 0 0 1 .5-.5m15 0a.5.5 0 0 1 .5.5v4a1.5 1.5 0 0 1-1.5 1.5h-4a.5.5 0 0 1 0-1h4a.5.5 0 0 0 .5-.5v-4a.5.5 0 0 1 .5-.5"/>
|
||||||
|
</svg></span></button>
|
||||||
|
<button id="close-viewer-button" class="title-bar-button" title="CLOSE VIEWER"><span class="viewer-icon"><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-x-lg" viewBox="0 0 16 16">
|
||||||
|
<path d="M2.146 2.854a.5.5 0 1 1 .708-.708L8 7.293l5.146-5.147a.5.5 0 0 1 .708.708L8.707 8l5.147 5.146a.5.5 0 0 1-.708.708L8 8.707l-5.146 5.147a.5.5 0 0 1-.708-.708L7.293 8z"/>
|
||||||
|
</svg></span></button></div>
|
||||||
|
|
||||||
|
<div id="dicom-image" data-figure="` +
|
||||||
figure_to_load +
|
figure_to_load +
|
||||||
'"></div></div>'
|
'"></div></div>'
|
||||||
);
|
);
|
||||||
@@ -700,10 +720,31 @@ export function openMainImage(current_question, t, source) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Bind button actions
|
||||||
|
$("#close-viewer-button").click(function () {
|
||||||
|
const dicom_element = document.getElementById("dicom-image");
|
||||||
|
closeViewer(dicom_element);
|
||||||
|
});
|
||||||
|
|
||||||
load(images, annotations);
|
load(images, annotations);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function closeViewer(dicom_element) {
|
||||||
|
// disable fullscreen if required
|
||||||
|
if ($(".canvas-panel").length == 0) {
|
||||||
|
disableFullscreen(dicom_element);
|
||||||
|
}
|
||||||
|
if (dicom_element != undefined) {
|
||||||
|
// See https://github.com/cornerstonejs/cornerstoneTools/issues/1337
|
||||||
|
cornerstone.removeElementData(dicom_element);
|
||||||
|
cornerstone.disable(dicom_element);
|
||||||
|
$(".canvas-panel").remove();
|
||||||
|
$(".figure-open").removeClass("figure-open").addClass("figure");
|
||||||
|
$(dicom_element).remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export function urltoFile(url, filename, mimeType) {
|
export function urltoFile(url, filename, mimeType) {
|
||||||
return fetch(url)
|
return fetch(url)
|
||||||
.then(function (res) {
|
.then(function (res) {
|
||||||
|
|||||||
Reference in New Issue
Block a user