update viewer for atlas series
This commit is contained in:
@@ -413,14 +413,6 @@
|
||||
.then(response => response.text())
|
||||
.then(html => {
|
||||
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;
|
||||
viewer_element_3d = document.getElementById('root');
|
||||
if (viewer_element_3d.dataset.viewerstate3d != undefined) {
|
||||
@@ -430,11 +422,9 @@
|
||||
} else {
|
||||
viewer_element_3d = null;
|
||||
}
|
||||
dicom_element = $(".cornerstone-element").get(0);
|
||||
// We have a slight delay to allow the viewer to load
|
||||
setTimeout(function () {
|
||||
// Then we load the annotation and viewport
|
||||
loadAnnotationAndViewportOnElement(annotationjson, viewport, dicom_element, current_image_id_index);
|
||||
window.mountDicomViewers();
|
||||
if (load_3d) {
|
||||
console.log("loading 3d")
|
||||
@@ -450,7 +440,6 @@
|
||||
}, 200);
|
||||
|
||||
document.getElementById("reload-finding").addEventListener("click", function () {
|
||||
loadAnnotationAndViewportOnElement(annotationjson, viewport, dicom_element, current_image_id_index);
|
||||
importAnnotations_root(annotationjson3d)
|
||||
importViewerState_root(viewerState);
|
||||
});
|
||||
|
||||
@@ -20,9 +20,6 @@
|
||||
<button class="btn btn-primary" id="reload-finding">Reload</button>
|
||||
|
||||
{% 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 }}"
|
||||
style="height: 600px; box-sizing: border-box; background: #222;"
|
||||
data-annotationjson='{{ finding.annotation_json_3d }}' data-viewerstate='{{ finding.viewer_state_3d }}'
|
||||
|
||||
@@ -40,8 +40,8 @@ Associated case:
|
||||
{% endfor %}
|
||||
|
||||
{% 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=''>
|
||||
</div>
|
||||
{% comment %} <div id="single-dicom-viewer" class="dicom-viewer" data-images="{{ image_url_array_and_count.0 }}" data-annotations=''>
|
||||
</div> {% endcomment %}
|
||||
|
||||
<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;"
|
||||
@@ -52,13 +52,13 @@ Associated case:
|
||||
{% if can_edit %}
|
||||
{% if editing_finding < 1 %}
|
||||
<button id="add-finding-button">Add finding</button>
|
||||
<button id="clone-finding-button" title="Click to copy the details of a finding that is already associated with the series/case"
|
||||
hx-get="{% url 'atlas:series_finding_related' series.pk %}"
|
||||
hx-target="#clone-findings-modal"
|
||||
hx-trigger="click"
|
||||
data-bs-toggle="modal"
|
||||
data-bs-target="#clone-findings-modal"
|
||||
>Clone existing finding</button>
|
||||
<button id="clone-finding-button" title="Click to copy the details of a finding that is already associated with the series/case"
|
||||
hx-get="{% url 'atlas:series_finding_related' series.pk %}"
|
||||
hx-target="#clone-findings-modal"
|
||||
hx-trigger="click"
|
||||
data-bs-toggle="modal"
|
||||
data-bs-target="#clone-findings-modal"
|
||||
>Clone existing finding</button>
|
||||
{% endif %}
|
||||
<button id="reset-viewport-button" class="btn btn-secondary">Reset viewport</button>
|
||||
<div id="finding-form">
|
||||
@@ -91,12 +91,7 @@ Associated case:
|
||||
|
||||
{% for finding in series.findings.all %}
|
||||
<div class="finding-box">
|
||||
<button id="finding-{{finding.pk}}" class="view-finding-button" data-annotationjson={{finding.annotation_json}}
|
||||
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 %}
|
||||
<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>
|
||||
|
||||
<span class="view-finding-details">
|
||||
Finding(s): {% for f in finding.findings.all %}{{f.get_link}}{% endfor %}<br />
|
||||
@@ -135,6 +130,10 @@ Associated case:
|
||||
<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.
|
||||
</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/>
|
||||
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>
|
||||
@@ -225,44 +224,22 @@ Associated case:
|
||||
|
||||
<script>
|
||||
$(document).ready(function () {
|
||||
const apiKey = "root"
|
||||
|
||||
$("#set-lower-truncation-bound-button").click(() => {
|
||||
dicom_element = $(".cornerstone-element").get(0);
|
||||
index = cornerstone.getEnabledElement(dicom_element).toolStateManager.toolState.stack.data[0].currentImageIdIndex
|
||||
$("#lower-truncation-bound-input").val(index+1);
|
||||
$("#lower-truncation-bound-input").val(getCurrentStackPosition_root(0) + 1);
|
||||
});
|
||||
$("#set-upper-truncation-bound-button").click(() => {
|
||||
dicom_element = $(".cornerstone-element").get(0);
|
||||
index = cornerstone.getEnabledElement(dicom_element).toolStateManager.toolState.stack.data[0].currentImageIdIndex
|
||||
$("#upper-truncation-bound-input").val(index+1);
|
||||
$("#upper-truncation-bound-input").val(getCurrentStackPosition_root(0) + 1);
|
||||
});
|
||||
|
||||
$("#truncate-test-button").click(() => {
|
||||
lower_bound = parseInt($("#lower-truncation-bound-input").val()) - 1;
|
||||
upper_bound = parseInt($("#upper-truncation-bound-input").val()) - 1;
|
||||
|
||||
$("#lower-truncation-bound-input").prop("disabled", true);
|
||||
$("#upper-truncation-bound-input").prop("disabled", true);
|
||||
$("#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;
|
||||
const lower = parseInt($("#lower-truncation-bound-input").val()) - 1;
|
||||
const upper = parseInt($("#upper-truncation-bound-input").val()) - 1;
|
||||
const ok = window[`truncateStack_${apiKey}`](lower, upper);
|
||||
if (ok) {
|
||||
$("#truncate-output").text("The truncated images are shown above.");
|
||||
}
|
||||
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(() => {
|
||||
lower_bound = parseInt($("#lower-truncation-bound-input").val()) - 1;
|
||||
upper_bound = parseInt($("#upper-truncation-bound-input").val()) - 1;
|
||||
@@ -282,7 +259,7 @@ Associated case:
|
||||
|
||||
$("#add-finding-button").click(() => {
|
||||
$("#hidden-form").show()
|
||||
dicom_element = $(".cornerstone-element").get(0);
|
||||
//dicom_element = $(".cornerstone-element").get(0);
|
||||
//cornerstoneTools.globalImageIdSpecificToolStateManager.clear(dicom_element);
|
||||
//cornerstone.reset(dicom_element);
|
||||
////cornerstone.resize(dicom_element, true);
|
||||
@@ -302,11 +279,7 @@ Associated case:
|
||||
|
||||
|
||||
$("#reset-viewport-button").click(() => {
|
||||
dicom_element = $(".cornerstone-element").get(0);
|
||||
//annotationjson = JSON.parse(e.currentTarget.dataset.annotationjson);
|
||||
cornerstoneTools.globalImageIdSpecificToolStateManager.clear(dicom_element);
|
||||
cornerstone.reset(dicom_element);
|
||||
cornerstone.resize(dicom_element, true);
|
||||
resetViewer_root();
|
||||
|
||||
});
|
||||
$(".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 %}
|
||||
$("#hidden-form").show()
|
||||
setTimeout(function() {
|
||||
$(".view-finding-button[data-findingid={{editing_finding}}]").trigger("click");
|
||||
$(".view-finding-button-3d[data-findingid={{editing_finding}}]").trigger("click");
|
||||
}, 1000)
|
||||
|
||||
{% endif %}
|
||||
@@ -367,31 +313,7 @@ Associated case:
|
||||
{% 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) {
|
||||
dicom_element = $(".cornerstone-element").get(0);
|
||||
c = cornerstone.getEnabledElement(dicom_element);
|
||||
e.preventDefault();
|
||||
|
||||
$.ajax({
|
||||
@@ -401,14 +323,6 @@ Associated case:
|
||||
series_finding_id: {{ editing_finding }},
|
||||
description: $('#id_description').val(),
|
||||
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(),
|
||||
viewer_state_3d: window.exportViewerState_root(),
|
||||
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"))
|
||||
condition_ids = json.loads(request.POST.get("conditions"))
|
||||
description = request.POST.get("description")
|
||||
annotation_json = request.POST.get("annotation_json")
|
||||
viewport_json = request.POST.get("viewport_json")
|
||||
current_image_id_index = request.POST.get("current_image_id_index")
|
||||
#annotation_json = request.POST.get("annotation_json")
|
||||
#viewport_json = request.POST.get("viewport_json")
|
||||
#current_image_id_index = request.POST.get("current_image_id_index")
|
||||
annotation_json_3d = request.POST.get("annotation_json_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.series = series
|
||||
sf.description = description
|
||||
sf.annotation_json = annotation_json
|
||||
sf.viewport_json = viewport_json
|
||||
#sf.annotation_json = annotation_json
|
||||
#sf.viewport_json = viewport_json
|
||||
else:
|
||||
sf = SeriesFinding.objects.create(
|
||||
series=series,
|
||||
description=description,
|
||||
annotation_json=annotation_json,
|
||||
viewport_json=viewport_json,
|
||||
#annotation_json=annotation_json,
|
||||
#viewport_json=viewport_json,
|
||||
)
|
||||
|
||||
sf.findings.set(findings)
|
||||
sf.structures.set(structures)
|
||||
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.viewer_state_3d = viewer_state_3d
|
||||
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/cornerstone-base64-image-loader.umd.js' %}"></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 %}
|
||||
{% endblock %}
|
||||
|
||||
Reference in New Issue
Block a user