update viewer for atlas series
This commit is contained in:
@@ -413,14 +413,6 @@
|
|||||||
.then(response => response.text())
|
.then(response => response.text())
|
||||||
.then(html => {
|
.then(html => {
|
||||||
modalBody.innerHTML = html; // Load the fetched HTML into the modal body
|
modalBody.innerHTML = html; // Load the fetched HTML into the modal body
|
||||||
const viewer_element = document.getElementById('single-dicom-viewer');
|
|
||||||
const images = JSON.parse(viewer_element.getAttribute('data-images'));
|
|
||||||
window.loadDicomViewer(images);
|
|
||||||
annotationjson = JSON.parse(viewer_element.dataset.annotationjson);
|
|
||||||
viewport = JSON.parse(viewer_element.dataset.viewportjson);
|
|
||||||
current_image_id_index = viewer_element.dataset.currentimageid;
|
|
||||||
console.log(viewer_element.dataset.annotationjson3d)
|
|
||||||
console.log(viewer_element.dataset.viewerstate3d)
|
|
||||||
load_3d = false;
|
load_3d = false;
|
||||||
viewer_element_3d = document.getElementById('root');
|
viewer_element_3d = document.getElementById('root');
|
||||||
if (viewer_element_3d.dataset.viewerstate3d != undefined) {
|
if (viewer_element_3d.dataset.viewerstate3d != undefined) {
|
||||||
@@ -430,11 +422,9 @@
|
|||||||
} else {
|
} else {
|
||||||
viewer_element_3d = null;
|
viewer_element_3d = null;
|
||||||
}
|
}
|
||||||
dicom_element = $(".cornerstone-element").get(0);
|
|
||||||
// We have a slight delay to allow the viewer to load
|
// We have a slight delay to allow the viewer to load
|
||||||
setTimeout(function () {
|
setTimeout(function () {
|
||||||
// Then we load the annotation and viewport
|
// Then we load the annotation and viewport
|
||||||
loadAnnotationAndViewportOnElement(annotationjson, viewport, dicom_element, current_image_id_index);
|
|
||||||
window.mountDicomViewers();
|
window.mountDicomViewers();
|
||||||
if (load_3d) {
|
if (load_3d) {
|
||||||
console.log("loading 3d")
|
console.log("loading 3d")
|
||||||
@@ -450,7 +440,6 @@
|
|||||||
}, 200);
|
}, 200);
|
||||||
|
|
||||||
document.getElementById("reload-finding").addEventListener("click", function () {
|
document.getElementById("reload-finding").addEventListener("click", function () {
|
||||||
loadAnnotationAndViewportOnElement(annotationjson, viewport, dicom_element, current_image_id_index);
|
|
||||||
importAnnotations_root(annotationjson3d)
|
importAnnotations_root(annotationjson3d)
|
||||||
importViewerState_root(viewerState);
|
importViewerState_root(viewerState);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -20,9 +20,6 @@
|
|||||||
<button class="btn btn-primary" id="reload-finding">Reload</button>
|
<button class="btn btn-primary" id="reload-finding">Reload</button>
|
||||||
|
|
||||||
{% with image_url_array_and_count=finding.series.get_image_url_array_and_count %}
|
{% with image_url_array_and_count=finding.series.get_image_url_array_and_count %}
|
||||||
<div id="single-dicom-viewer" class="dicom-viewer" data-images='{{ image_url_array_and_count.0 }}' data-annotations='' data-annotationjson={{finding.annotation_json}}
|
|
||||||
data-viewportjson={{finding.viewport_json}} data-findingid={{finding.id}} data-currentimageid={{finding.current_image_id_index}}>
|
|
||||||
</div>
|
|
||||||
<div id="root" class="dicom-viewer-root" data-images="{{ image_url_array_and_count.0 }}"
|
<div id="root" class="dicom-viewer-root" data-images="{{ image_url_array_and_count.0 }}"
|
||||||
style="height: 600px; box-sizing: border-box; background: #222;"
|
style="height: 600px; box-sizing: border-box; background: #222;"
|
||||||
data-annotationjson='{{ finding.annotation_json_3d }}' data-viewerstate='{{ finding.viewer_state_3d }}'
|
data-annotationjson='{{ finding.annotation_json_3d }}' data-viewerstate='{{ finding.viewer_state_3d }}'
|
||||||
|
|||||||
@@ -40,8 +40,8 @@ Associated case:
|
|||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
{% with image_url_array_and_count=series.get_image_url_array_and_count %}
|
{% with image_url_array_and_count=series.get_image_url_array_and_count %}
|
||||||
<div id="single-dicom-viewer" class="dicom-viewer" data-images="{{ image_url_array_and_count.0 }}" data-annotations=''>
|
{% comment %} <div id="single-dicom-viewer" class="dicom-viewer" data-images="{{ image_url_array_and_count.0 }}" data-annotations=''>
|
||||||
</div>
|
</div> {% endcomment %}
|
||||||
|
|
||||||
<div id="root" class="dicom-viewer-root" data-images="{{ image_url_array_and_count.0 }}"
|
<div id="root" class="dicom-viewer-root" data-images="{{ image_url_array_and_count.0 }}"
|
||||||
style="width: 1000px; height: 600px; box-sizing: border-box; background: #222;"
|
style="width: 1000px; height: 600px; box-sizing: border-box; background: #222;"
|
||||||
@@ -91,12 +91,7 @@ Associated case:
|
|||||||
|
|
||||||
{% for finding in series.findings.all %}
|
{% for finding in series.findings.all %}
|
||||||
<div class="finding-box">
|
<div class="finding-box">
|
||||||
<button id="finding-{{finding.pk}}" class="view-finding-button" data-annotationjson={{finding.annotation_json}}
|
<button id="finding-{{finding.pk}}-3d" class="view-finding-button-3d" data-annotationjson3d='{{finding.annotation_json_3d}}' data-viewerstatejson='{{finding.viewer_state_3d}}' data-findingid='{{finding.pk}}'>Click to view</button>
|
||||||
data-viewportjson={{finding.viewport_json}} data-findingid={{finding.id}} data-currentimageid={{finding.current_image_id_index}}>Click to view</button>
|
|
||||||
|
|
||||||
{% if finding.viewer_state_3d %}
|
|
||||||
<button id="finding-{{finding.pk}}-3d" class="view-finding-button-3d" data-annotationjson3d='{{finding.annotation_json_3d}}' data-viewerstatejson='{{finding.viewer_state_3d}}'>Click to view 3D</button>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
<span class="view-finding-details">
|
<span class="view-finding-details">
|
||||||
Finding(s): {% for f in finding.findings.all %}{{f.get_link}}{% endfor %}<br />
|
Finding(s): {% for f in finding.findings.all %}{{f.get_link}}{% endfor %}<br />
|
||||||
@@ -135,6 +130,10 @@ Associated case:
|
|||||||
<p>
|
<p>
|
||||||
This will limit the series to the selected bounds (the rest of the images will be deleted). This is useful when you have a large volume of which only a small area is relevant to the case. NOTE: once deleted the images cannot be recovered on the site (they would have to be reuploaded if required). Make sure your images are shown in the correct order above and use test the test truncate button first.
|
This will limit the series to the selected bounds (the rest of the images will be deleted). This is useful when you have a large volume of which only a small area is relevant to the case. NOTE: once deleted the images cannot be recovered on the site (they would have to be reuploaded if required). Make sure your images are shown in the correct order above and use test the test truncate button first.
|
||||||
</p>
|
</p>
|
||||||
|
<div role="alert" class="alert alert-warning">
|
||||||
|
<strong>Warning:</strong> Please note: if you have reordered the series this may result in the incorrect images being deleted.
|
||||||
|
</div>
|
||||||
|
|
||||||
Start <input id="lower-truncation-bound-input" type="number" value="1"> <button id="set-lower-truncation-bound-button">Set</button><br/>
|
Start <input id="lower-truncation-bound-input" type="number" value="1"> <button id="set-lower-truncation-bound-button">Set</button><br/>
|
||||||
End <input id="upper-truncation-bound-input"type="number" value="{{image_url_array_and_count.1}}"> <button id="set-upper-truncation-bound-button">Set</button><br/>
|
End <input id="upper-truncation-bound-input"type="number" value="{{image_url_array_and_count.1}}"> <button id="set-upper-truncation-bound-button">Set</button><br/>
|
||||||
<button id="truncate-test-button">Test truncate</button>
|
<button id="truncate-test-button">Test truncate</button>
|
||||||
@@ -225,44 +224,22 @@ Associated case:
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
$(document).ready(function () {
|
$(document).ready(function () {
|
||||||
|
const apiKey = "root"
|
||||||
|
|
||||||
$("#set-lower-truncation-bound-button").click(() => {
|
$("#set-lower-truncation-bound-button").click(() => {
|
||||||
dicom_element = $(".cornerstone-element").get(0);
|
$("#lower-truncation-bound-input").val(getCurrentStackPosition_root(0) + 1);
|
||||||
index = cornerstone.getEnabledElement(dicom_element).toolStateManager.toolState.stack.data[0].currentImageIdIndex
|
|
||||||
$("#lower-truncation-bound-input").val(index+1);
|
|
||||||
});
|
});
|
||||||
$("#set-upper-truncation-bound-button").click(() => {
|
$("#set-upper-truncation-bound-button").click(() => {
|
||||||
dicom_element = $(".cornerstone-element").get(0);
|
$("#upper-truncation-bound-input").val(getCurrentStackPosition_root(0) + 1);
|
||||||
index = cornerstone.getEnabledElement(dicom_element).toolStateManager.toolState.stack.data[0].currentImageIdIndex
|
|
||||||
$("#upper-truncation-bound-input").val(index+1);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
$("#truncate-test-button").click(() => {
|
$("#truncate-test-button").click(() => {
|
||||||
lower_bound = parseInt($("#lower-truncation-bound-input").val()) - 1;
|
const lower = parseInt($("#lower-truncation-bound-input").val()) - 1;
|
||||||
upper_bound = parseInt($("#upper-truncation-bound-input").val()) - 1;
|
const upper = parseInt($("#upper-truncation-bound-input").val()) - 1;
|
||||||
|
const ok = window[`truncateStack_${apiKey}`](lower, upper);
|
||||||
$("#lower-truncation-bound-input").prop("disabled", true);
|
if (ok) {
|
||||||
$("#upper-truncation-bound-input").prop("disabled", true);
|
$("#truncate-output").text("The truncated images are shown above.");
|
||||||
$("#set-lower-truncation-bound-button").remove();
|
|
||||||
$("#set-upper-truncation-bound-button").remove();
|
|
||||||
$("#truncate-test-button").remove();
|
|
||||||
if (lower_bound >= upper_bound) {
|
|
||||||
alert("The lower bound must be less than the upper bound.");
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
dicom_element = $(".cornerstone-element").get(0);
|
});
|
||||||
stack = cornerstone.getEnabledElement(dicom_element).toolStateManager.toolState.stack.data[0]
|
|
||||||
stack.imageIds = stack.imageIds.slice(lower_bound, upper_bound+1) // inclusive
|
|
||||||
|
|
||||||
stack.currentImageIdIndex = 0
|
|
||||||
//let id = stack.imageIds[0];
|
|
||||||
//cornerstone.loadImage(id).then((b) => {
|
|
||||||
// cornerstone.displayImage(dicom_element, b);
|
|
||||||
//});
|
|
||||||
cornerstone.reset(dicom_element);
|
|
||||||
|
|
||||||
$("#truncate-output").text("The truncated images are shown above. If you wish to make changes refresh the page. To continue click the trucated series button.")
|
|
||||||
|
|
||||||
})
|
|
||||||
$("#truncate-button").click(() => {
|
$("#truncate-button").click(() => {
|
||||||
lower_bound = parseInt($("#lower-truncation-bound-input").val()) - 1;
|
lower_bound = parseInt($("#lower-truncation-bound-input").val()) - 1;
|
||||||
upper_bound = parseInt($("#upper-truncation-bound-input").val()) - 1;
|
upper_bound = parseInt($("#upper-truncation-bound-input").val()) - 1;
|
||||||
@@ -282,7 +259,7 @@ Associated case:
|
|||||||
|
|
||||||
$("#add-finding-button").click(() => {
|
$("#add-finding-button").click(() => {
|
||||||
$("#hidden-form").show()
|
$("#hidden-form").show()
|
||||||
dicom_element = $(".cornerstone-element").get(0);
|
//dicom_element = $(".cornerstone-element").get(0);
|
||||||
//cornerstoneTools.globalImageIdSpecificToolStateManager.clear(dicom_element);
|
//cornerstoneTools.globalImageIdSpecificToolStateManager.clear(dicom_element);
|
||||||
//cornerstone.reset(dicom_element);
|
//cornerstone.reset(dicom_element);
|
||||||
////cornerstone.resize(dicom_element, true);
|
////cornerstone.resize(dicom_element, true);
|
||||||
@@ -302,11 +279,7 @@ Associated case:
|
|||||||
|
|
||||||
|
|
||||||
$("#reset-viewport-button").click(() => {
|
$("#reset-viewport-button").click(() => {
|
||||||
dicom_element = $(".cornerstone-element").get(0);
|
resetViewer_root();
|
||||||
//annotationjson = JSON.parse(e.currentTarget.dataset.annotationjson);
|
|
||||||
cornerstoneTools.globalImageIdSpecificToolStateManager.clear(dicom_element);
|
|
||||||
cornerstone.reset(dicom_element);
|
|
||||||
cornerstone.resize(dicom_element, true);
|
|
||||||
|
|
||||||
});
|
});
|
||||||
$(".view-finding-button-3d").each((n, el) => {
|
$(".view-finding-button-3d").each((n, el) => {
|
||||||
@@ -321,38 +294,11 @@ Associated case:
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
$(".view-finding-button").each((n, el) => {
|
|
||||||
$(el).click((e) => {
|
|
||||||
dicom_element = $(".cornerstone-element").get(0);
|
|
||||||
annotationjson = JSON.parse(e.currentTarget.dataset.annotationjson);
|
|
||||||
viewport = JSON.parse(e.currentTarget.dataset.viewportjson);
|
|
||||||
current_image_id_index = e.currentTarget.dataset.currentimageid;
|
|
||||||
console.log(e.currentTarget, current_image_id_index)
|
|
||||||
loadAnnotationAndViewportOnElement(annotationjson, viewport, dicom_element, current_image_id_index);
|
|
||||||
|
|
||||||
importLegacyViewport_root(viewport)
|
|
||||||
importLegacyAnnotations_root(annotationjson);
|
|
||||||
jumpToSliceByImageId_root(0, current_image_id_index);
|
|
||||||
console.log("Loaded annotation and viewport on element", dicom_element, annotationjson, viewport, current_image_id_index);
|
|
||||||
$(el).addClass("active");
|
|
||||||
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
$("#diff-show-all").click(() => {
|
|
||||||
console.log("Helol");
|
|
||||||
})
|
|
||||||
$("#diff-show-diff").click(() => {
|
|
||||||
console.log("diff");
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
{% if editing_finding > 0 %}
|
{% if editing_finding > 0 %}
|
||||||
$("#hidden-form").show()
|
$("#hidden-form").show()
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
$(".view-finding-button[data-findingid={{editing_finding}}]").trigger("click");
|
$(".view-finding-button-3d[data-findingid={{editing_finding}}]").trigger("click");
|
||||||
}, 1000)
|
}, 1000)
|
||||||
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
@@ -367,31 +313,7 @@ Associated case:
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
});
|
});
|
||||||
|
|
||||||
function loadAnnotationAndViewportOnElement(annotation, viewport, dicom_element, current_image_id_index) {
|
|
||||||
cornerstoneTools.globalImageIdSpecificToolStateManager.clear(dicom_element);
|
|
||||||
cornerstone.getEnabledElement(dicom_element).viewport = viewport
|
|
||||||
cornerstoneTools.globalImageIdSpecificToolStateManager.restoreToolState(
|
|
||||||
annotation);
|
|
||||||
|
|
||||||
//cornerstone.getEnabledElement(dicom_element).toolStateManager.restoreToolState(annotationjson)
|
|
||||||
cornerstone.resize(dicom_element);
|
|
||||||
//current_image_id_index = parseInt(current_image_id_index);
|
|
||||||
|
|
||||||
if (Number.isInteger(current_image_id_index)) {
|
|
||||||
dicomViewer.loadStackIndex(current_image_id_index, dicom_element);
|
|
||||||
} else {
|
|
||||||
try {
|
|
||||||
dicomViewer.loadImageById(current_image_id_index, dicom_element);
|
|
||||||
} catch (e) {
|
|
||||||
dicomViewer.getNextAnnotationImage(dicom_element);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
$(document).on('submit', '#series_finding_form', function (e) {
|
$(document).on('submit', '#series_finding_form', function (e) {
|
||||||
dicom_element = $(".cornerstone-element").get(0);
|
|
||||||
c = cornerstone.getEnabledElement(dicom_element);
|
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
$.ajax({
|
$.ajax({
|
||||||
@@ -401,14 +323,6 @@ Associated case:
|
|||||||
series_finding_id: {{ editing_finding }},
|
series_finding_id: {{ editing_finding }},
|
||||||
description: $('#id_description').val(),
|
description: $('#id_description').val(),
|
||||||
series: {{ series.pk }},
|
series: {{ series.pk }},
|
||||||
//annotation_json: JSON.stringify(c.toolStateManager.saveToolState()),
|
|
||||||
// This is the stack number
|
|
||||||
//current_image_id_index: c.toolStateManager.toolState.stack.data[0].currentImageIdIndex,
|
|
||||||
// but we want to use the current image id (so if the stack is reordered it still attaches to the correct image)
|
|
||||||
current_image_id_index: c.toolStateManager.toolState.stack.data[0].imageIds[c.toolStateManager.toolState.stack.data[0].currentImageIdIndex],
|
|
||||||
annotation_json: JSON.stringify(cornerstoneTools.globalImageIdSpecificToolStateManager
|
|
||||||
.saveToolState()),
|
|
||||||
viewport_json: JSON.stringify(c.viewport),
|
|
||||||
annotation_json_3d: window.exportAnnotations_root(),
|
annotation_json_3d: window.exportAnnotations_root(),
|
||||||
viewer_state_3d: window.exportViewerState_root(),
|
viewer_state_3d: window.exportViewerState_root(),
|
||||||
findings: JSON.stringify($('#finding-form select[name="findings"]').find(":selected")
|
findings: JSON.stringify($('#finding-form select[name="findings"]').find(":selected")
|
||||||
|
|||||||
+8
-8
@@ -1450,9 +1450,9 @@ def create_series_findings(request):
|
|||||||
structure_ids = json.loads(request.POST.get("structures"))
|
structure_ids = json.loads(request.POST.get("structures"))
|
||||||
condition_ids = json.loads(request.POST.get("conditions"))
|
condition_ids = json.loads(request.POST.get("conditions"))
|
||||||
description = request.POST.get("description")
|
description = request.POST.get("description")
|
||||||
annotation_json = request.POST.get("annotation_json")
|
#annotation_json = request.POST.get("annotation_json")
|
||||||
viewport_json = request.POST.get("viewport_json")
|
#viewport_json = request.POST.get("viewport_json")
|
||||||
current_image_id_index = request.POST.get("current_image_id_index")
|
#current_image_id_index = request.POST.get("current_image_id_index")
|
||||||
annotation_json_3d = request.POST.get("annotation_json_3d")
|
annotation_json_3d = request.POST.get("annotation_json_3d")
|
||||||
viewer_state_3d = request.POST.get("viewer_state_3d")
|
viewer_state_3d = request.POST.get("viewer_state_3d")
|
||||||
|
|
||||||
@@ -1465,20 +1465,20 @@ def create_series_findings(request):
|
|||||||
sf = get_object_or_404(SeriesFinding, pk=series_finding_id)
|
sf = get_object_or_404(SeriesFinding, pk=series_finding_id)
|
||||||
sf.series = series
|
sf.series = series
|
||||||
sf.description = description
|
sf.description = description
|
||||||
sf.annotation_json = annotation_json
|
#sf.annotation_json = annotation_json
|
||||||
sf.viewport_json = viewport_json
|
#sf.viewport_json = viewport_json
|
||||||
else:
|
else:
|
||||||
sf = SeriesFinding.objects.create(
|
sf = SeriesFinding.objects.create(
|
||||||
series=series,
|
series=series,
|
||||||
description=description,
|
description=description,
|
||||||
annotation_json=annotation_json,
|
#annotation_json=annotation_json,
|
||||||
viewport_json=viewport_json,
|
#viewport_json=viewport_json,
|
||||||
)
|
)
|
||||||
|
|
||||||
sf.findings.set(findings)
|
sf.findings.set(findings)
|
||||||
sf.structures.set(structures)
|
sf.structures.set(structures)
|
||||||
sf.conditions.set(conditions)
|
sf.conditions.set(conditions)
|
||||||
sf.current_image_id_index = current_image_id_index
|
#sf.current_image_id_index = current_image_id_index
|
||||||
sf.annotation_json_3d = annotation_json_3d
|
sf.annotation_json_3d = annotation_json_3d
|
||||||
sf.viewer_state_3d = viewer_state_3d
|
sf.viewer_state_3d = viewer_state_3d
|
||||||
sf.save()
|
sf.save()
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1
-1
@@ -70,7 +70,7 @@
|
|||||||
<script src="{% static 'js/cornerstone/cornerstoneWADOImageLoader.min.js' %}"></script>
|
<script src="{% static 'js/cornerstone/cornerstoneWADOImageLoader.min.js' %}"></script>
|
||||||
<script src="{% static 'js/cornerstone/cornerstone-base64-image-loader.umd.js' %}"></script>
|
<script src="{% static 'js/cornerstone/cornerstone-base64-image-loader.umd.js' %}"></script>
|
||||||
<script src="{% static 'js/anatomy.js' %}" defer="defer" type="module"></script>
|
<script src="{% static 'js/anatomy.js' %}" defer="defer" type="module"></script>
|
||||||
<script src="{% static 'dv3d/index-DBrYmXwn.js' %}" type="module" defer="defer" type="module"></script>
|
<script src="{% static 'dv3d/index.js' %}" type="module" defer="defer" type="module"></script>
|
||||||
|
|
||||||
{% block js %}
|
{% block js %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
Reference in New Issue
Block a user