Skip to content

Commit

Permalink
Merge pull request #120 from arthur-schnitzler/main
Browse files Browse the repository at this point in the history
Update
  • Loading branch information
csae8092 authored Jan 7, 2025
2 parents ca589b2 + ad697a3 commit 200f185
Show file tree
Hide file tree
Showing 8 changed files with 312 additions and 38 deletions.
56 changes: 56 additions & 0 deletions apis_core/apis_entities/arc_views.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import pandas as pd
from django.views.generic import TemplateView
from django.http import JsonResponse
from apis_core.apis_entities.models import Person
from apis_core.apis_entities.list_view_person import PersonListFilter

from network.utils import iso_to_lat_long


class ArcsView(TemplateView):
template_name = "apis_entities/arcs.html"


def get_arcs_data(request):
values_list = ["id", "name", "first_name", "start_date", "end_date"]
query_params = request.GET
queryset = (
Person.objects.filter()
.exclude(start_date__isnull=True)
.exclude(end_date__isnull=True)
)
qs = PersonListFilter(query_params, queryset=queryset).qs
items = list(qs.values_list(*values_list))
df = pd.DataFrame(list(items), columns=values_list)
start_date = str(df["start_date"].min())
end_date = str(df["end_date"].max())
df["latitude_start"], df["longitude_start"] = zip(
*df["start_date"].map(
lambda date: iso_to_lat_long(date, start_date=start_date, end_date=end_date, max_width=3)
)
)
df["latitude_end"], df["longitude_end"] = zip(
*df["end_date"].map(
lambda date: iso_to_lat_long(date, start_date=start_date, end_date=end_date, max_width=3)
)
)
df = df.sort_values(by="start_date")
items = df.apply(
lambda row: {
"id": row["id"],
"label": f'{row["name"]}, {row["first_name"]} ({row["start_date"]}{row["end_date"]})',
"from": [row["latitude_start"], row["longitude_start"]],
"to": [row["latitude_end"], row["longitude_end"]],
},
axis=1,
).tolist()
data = {}
data = {"metadata": {}, "items": items}
data["metadata"] = {"number of objects": len(items)}
data["metadata"]["query_params"] = [
{key: value} for key, value in query_params.items()
]
data["metadata"]["start_date"] = str(df["start_date"].min())
data["metadata"]["end_date"] = str(df["start_date"].max())

return JsonResponse(data, safe=False)
57 changes: 57 additions & 0 deletions apis_core/apis_entities/templates/apis_entities/arcs.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
{% extends "base.html" %}
{% load static %}
{% block title %}Zeitspannen{% endblock %}
{% block scriptHeader %}
{% endblock %}
{% block content %}
<style>
#map {
width: 100%;
height: 700px;
}
#loading-spinner {
display: none;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
z-index: 1000;
}
</style>
<script src="https://unpkg.com/deck.gl@latest/dist.min.js"></script>
<div class="container-fluid pt-3">
<h1 class="display-3 text-center">Zeitspannen</h1>
<div id="mapcontainer" class="p-4">
<div id="map"></div>
<div id="legend" class="text-center pt-3">
<h2>gewählte Filterparameter</h2>
</div>
</div>
</div>

<div id="loading-spinner" class="text-center">
<div class="spinner-border" role="status">
<span class="visually-hidden">Loading...</span>
</div>
<div>Daten werden geladen</div>
</div>

<div class="modal fade" id="staticBackdrop" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1"
aria-labelledby="staticBackdropLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5" id="staticBackdropLabel"></h1>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Schließen"></button>
</div>
<div class="modal-body" id="modal-body" />
</div>
</div>
</div>

<span id="url" class="visually-hidden" aria-hidden="true">{% url 'apis_core:apis_entities:arcs_data' %}{% querystring %}</span>
{% endblock %}

{% block scripts2 %}
<script src="{% static 'network/arcs.js' %}"></script>
{% endblock scripts2 %}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,15 @@ <h2 class="text-center">
</a>
</h2>
{% endif %}{% endif %}
<!-- {% if entity == "person" %}
<div class="row">
<div class="btn-group" role="group" class="text-end">
<a type="button" class="btn btn-outline-primary" href="{% url 'apis_core:apis_entities:arcs_data' %}{% querystring %}">Zeitspannen (Daten)</a>
<a type="button" class="btn btn-outline-primary" href="{% url 'apis_core:apis_entities:arcs' %}{% querystring %}">Zeitspannen (Visualisierung)</a>
</div>
</div>
{% endif %} -->

<div class="row pt-4">
<div class="col-md-4" id="searchpane">
<h2 class="text-center">Suchen & Filtern</h2>
Expand Down
11 changes: 11 additions & 0 deletions apis_core/apis_entities/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,21 @@
from .list_view_person import PersonListView
from .list_view_place import PlaceListView
from .list_view_work import WorkListView
from .arc_views import get_arcs_data, ArcsView

app_name = "apis_entities"

urlpatterns = [
path(
"arcs-data",
get_arcs_data,
name="arcs_data",
),
path(
"arcs",
ArcsView.as_view(),
name="arcs",
),
path(
"entity/<entity>/<int:pk>/edit",
views.GenericEntitiesEditView.as_view(),
Expand Down
91 changes: 91 additions & 0 deletions network/static/network/arcs.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
const url = document.getElementById("url").textContent;

function showModal(object) {
const options = {
focus: true,
keyboard: true,
backdrop: true,
dismiss: true,
};
// const eventLabels = object.points.map((p) => p.source.label);
// const curDate = object.points[0].source.date;
// const listItems = eventLabels.map((label) => `<li>${label}</li>`).join("");
// const urlParams = new URLSearchParams(window.location.search);
// urlParams.set("start_date", curDate);
const newUrl = `/entity/${object.id}`;
const label = object.label;
document.getElementById("staticBackdropLabel").innerHTML = `<a href="${newUrl}">${label}</a>`;
// document.getElementById("modal-body").innerHTML = `<ul>${listItems}</ul>`;
const myModal = new bootstrap.Modal(
document.getElementById("staticBackdrop"),
options
);
myModal.toggle();
}

console.log("fetching data hansi");
document.getElementById("loading-spinner").style.display = "block";
fetch(url)
.then((response) => {
if (!response.ok) {
throw new Error("Timespan data response was not ok");
}
return response.json();
})
.then((data) => {
document.getElementById("loading-spinner").style.display = "none"; // Hide spinner
const legendDiv = document.getElementById("legend");
const dl = document.createElement("dl"); // Create the <dl> element

data.metadata.query_params.forEach((param) => {
for (const [key, value] of Object.entries(param)) {
const dt = document.createElement("dt"); // Create the <dt> element
dt.textContent = key;
const dd = document.createElement("dd"); // Create the <dd> element
dd.textContent = value;

dl.appendChild(dt);
dl.appendChild(dd);
}
});

const items = data.items;

console.log(items[1]);
new deck.DeckGL({
container: "map",
mapStyle:
"https://basemaps.cartocdn.com/gl/dark-matter-nolabels-gl-style/style.json",
initialViewState: {
longitude: 10.4356549,
latitude: 48.9833712,
zoom: 5,
minZoom: 1,
maxZoom: 15,
pitch: 45,
},
onViewStateChange: ({ viewState }) => {
console.log("Current view state:", viewState);
},
controller: true,
layers: [
new deck.ArcLayer({
id: "arc-layer",
data: items,
getSourcePosition: (d) => d.from,
getTargetPosition: (d) => d.to,
getSourceColor: [0, 0, 0],
getTargetColor: [255, 0, 0],
getWidth: 4,
pickable: true,
onClick: (info) => showModal(info.object),
}),
],
});

legendDiv.appendChild(dl);
})
.catch((error) => {
document.getElementById("loading-spinner").style.display = "none"; // Hide spinner on error
console.error("Something went wrong:", error);
});
Loading

0 comments on commit 200f185

Please sign in to comment.