improve finrding

This commit is contained in:
Ross
2025-05-12 10:18:44 +01:00
parent e119dceaa1
commit 1599e48584
6 changed files with 138 additions and 18 deletions
-1
View File
@@ -210,7 +210,6 @@ function loadDicomViewer(images_to_load, annotations_to_load) {
images = JSON.parse(images);
}
console.log(images);
let annotations = single_dicom.dataset.annotations;
if (annotations_to_load != undefined) {
+17 -4
View File
@@ -2,7 +2,7 @@
{% partialdef case-series %}
{% for series in case.series.all %}
<span class="series-block">
<span class="series-block" id="series-block-{{ series.pk }}">
<span>
<span class="series-block-series-number">Series {{ forloop.counter }}:</span><br>
<a href="{% url 'atlas:series_detail' pk=series.pk %}">
@@ -197,9 +197,14 @@
{% if case.series.all %}
{% for series in case.series.all %}
{% for finding in series.findings.all %}
<div class="finding-box">
<div class="finding-box" id="finding-box-{{ finding.pk }}" data-series="{{ series.pk }}"
_="on mouseenter
toggle .highlight-series
on #series-block-{{ series.pk }}
until mouseleave"
>
<span>
<a href="{{series.get_absolute_url}}">Series {{series.pk}}</a>: {{series.get_examination_full}} |&nbsp;
<a href="{{series.get_absolute_url}}?show_finding={{finding.pk}}"><button class="btn btn-primary btn-sm">View</button></a>
</span>
{% if finding.findings.all %}
<span>
@@ -331,4 +336,12 @@
// Listen for toggle events on the <details> element
detailsElement.addEventListener("toggle", toggleCheckboxes);
});
</script>
</script>
<style>
/* Highlight style for the series-block */
.highlight-series {
background-color: blue;
transition: background-color 0.3s ease, border 0.3s ease;
}
</style>
+65 -6
View File
@@ -3,14 +3,41 @@
<div>{{ series.modality}}, {{ series.examination }}, {{ series.plane }}, {{ series.contrast }}</div>
<div>Description: {{series.description}}</div>
{% if series.case %}
Associated case:
Associated case:
{% for case in series.case.all %}
<span id="case-link-{{ case.pk }}" class="case-item">
<a href="{% url 'atlas:case_detail' pk=case.pk %}">{{case}}</a>
{% endfor %}
{% else %}
{% if can_edit %}
<button hx-post="{% url 'atlas:remove_series_from_case' series.pk case.pk %}"
hx-target="#case-link-{{ case.pk }}"
hx-swap="outerHTML"
hx-confirm="Are you sure you want to remove this series from the case?"
class="btn btn-link btn-sm button-unset remove-button">
Remove
</button>
{% endif %}
</span>
{% empty %}
This series is not associated with any cases.
{% endif %}
{% if can_edit %}
<details>
<summary>Add Series to Case</summary>
<form hx-post="{% url 'atlas:add_series_to_case' series.pk %}"
hx-target="#add-series-to-case-result"
hx-swap="innerHTML">
{% csrf_token %}
<label for="case-select">Select Case:</label>
<select name="case_id" id="case-select" required>
{% for case in available_cases %}
<option value="{{ case.pk }}">{{ case.title }}</option>
{% endfor %}
</select>
<button type="submit" class="btn btn-primary">Add to Case</button>
</form>
<div id="add-series-to-case-result"></div>
</details>
{% endif %}
{% 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=''>
@@ -44,7 +71,7 @@
{% for finding in series.findings.all %}
<div class="finding-box">
<button class="view-finding-button" data-annotationjson={{finding.annotation_json}}
<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>
<span class="view-finding-details">
Finding(s): {% for f in finding.findings.all %}{{f.get_link}}{% endfor %}<br />
@@ -155,6 +182,7 @@
{% endif %}
<script>
$(document).ready(function () {
$("#set-lower-truncation-bound-button").click(() => {
@@ -248,6 +276,7 @@
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);
$(el).addClass("active");
});
@@ -269,6 +298,15 @@
}, 1000)
{% endif %}
{% if request.GET.show_finding %}
function show_finding() {
console.log("show finding")
$("#finding-{{ request.GET.show_finding }}").trigger("click");
}
setTimeout(show_finding, 500);
{% endif %}
});
function loadAnnotationAndViewportOnElement(annotation, viewport, dicom_element, current_image_id_index) {
@@ -351,3 +389,24 @@
});
});
</script>
<style>
.case-item {
transition: background-color 0.3s ease;
}
.case-item:hover {
background-color: darkgray;
}
.remove-button:hover {
color: #dc3545; /* Optional: Make the remove button text red on hover */
}
.active {
font-weight: bold; /* Optional: Make the active button text bold */
border-style: dashed;
}
</style>
+2
View File
@@ -264,6 +264,8 @@ urlpatterns = [
views.series_dicom_json,
name="series_dicom_json",
),
path('series/<int:series_pk>/add-to-case/', views.add_series_to_case, name='add_series_to_case'),
path('series/<int:series_pk>/<int:case_pk>/remove-from-case/', views.remove_series_from_case, name='remove_series_from_case'),
path("uncategorised_dicoms/", views.uncategorised_dicoms, name="uncategorised_dicoms_view"),
path("question_schema/", views.QuestionSchemaView.as_view(), name="question_schema_overview"),
path("question_schema/<int:pk>", views.question_schema_detail, name="question_schema_detail"),
+43 -7
View File
@@ -247,16 +247,21 @@ def series_detail(request, pk, finding_pk=None):
else:
series_finding_form = SeriesFindingForm(series_id=series.id)
# logging.debug(atlas.subspecialty.first().name.all())
return render(
request,
"atlas/series.html",
{
context = {
"series": series,
"series_finding_form": series_finding_form,
"editing_finding": editing_finding,
"can_edit": can_edit,
},
}
if can_edit:
context["available_cases"] = Case.objects.all() # Adjust the queryset as needed
# logging.debug(atlas.subspecialty.first().name.all())
return render(
request,
"atlas/series.html",
context,
)
@@ -3098,4 +3103,35 @@ def linked_cases_overview(request, case_id):
"previous_cases": previous_cases,
"next_cases": next_cases,
},
)
)
@login_required
def add_series_to_case(request, series_pk):
if request.method == "POST":
case_id = request.POST.get("case_id")
case = get_object_or_404(Case, pk=case_id)
if not case.check_user_can_edit(request.user):
raise PermissionDenied("You do not have permission to edit this case.")
series = get_object_or_404(Series, pk=series_pk)
# Associate the series with the case
series.case.add(case)
return HttpResponse(f"Series {series_pk} added to case {case.title} ({case_id}).")
return HttpResponse("Invalid request.")
@login_required
def remove_series_from_case(request, series_pk, case_pk):
if request.method == "POST":
case = get_object_or_404(Case, pk=case_pk)
if not case.check_user_can_edit(request.user):
raise PermissionDenied("You do not have permission to edit this case.")
series = get_object_or_404(Series, pk=series_pk)
# Associate the series with the case
series.case.remove(case)
return HttpResponse(f"Removed")
return HttpResponse("Invalid request.")
+11
View File
@@ -138,6 +138,17 @@ button a {
color: inherit;
}
.button-unset {
background-color: unset;
color: unset;
border: unset;
}
.button-unset:hover {
background-color: unset;
color: unset;
border: unset;
}
.marking-list pre {
display: inline;
white-space: pre-wrap;