diff --git a/nummi/main/static/main/css/chart.css b/nummi/main/static/main/css/chart.css
new file mode 100644
index 0000000..e6f7d19
--- /dev/null
+++ b/nummi/main/static/main/css/chart.css
@@ -0,0 +1,40 @@
+.chart {
+ display: grid;
+ grid-template-columns: auto auto 1fr 1fr auto;
+ grid-gap: var(--gap) 0;
+}
+
+.chart > div {
+ position: relative;
+ height: 2rem;
+ line-height: 2rem;
+}
+
+.chart .left {
+ text-align: right;
+}
+.chart .bar,
+.chart .value {
+ display: inline-block;
+ height: 2rem;
+ line-height: 2rem;
+}
+.chart .value {
+ padding: 0 var(--gap);
+}
+.chart .bar {
+ width: 0;
+ box-sizing: border-box;
+ z-index: 1;
+}
+.chart .bar.tot {
+ position: absolute;
+ z-index: 10;
+ border-top: .5rem solid black;
+}
+
+.chart .left .bar.tot {right: 0}
+.chart .right .bar.tot {left: 0}
+
+.chart .bar_m {background: var(--red)}
+.chart .bar_p {background: var(--green)}
diff --git a/nummi/main/templates/main/snapshot.html b/nummi/main/templates/main/snapshot.html
index e015765..d2588da 100644
--- a/nummi/main/templates/main/snapshot.html
+++ b/nummi/main/templates/main/snapshot.html
@@ -6,6 +6,7 @@
{{ block.super }}
+
{% endblock %}
{% block body %}
@@ -32,7 +33,54 @@
Plot
-
+
+ {% for cat in categories %}
+
+
+ {% pmvalue cat.sum_m %}
+
+
+
+
+ {% if cat.sum < 0 %}
+
+
+ {% endif %}
+
+
+
+
+ {% if cat.sum >= 0 %}
+
+
+ {% endif %}
+
+
+ {% pmvalue cat.sum_p %}
+
+ {% endfor %}
+
{% if snapshot.transactions %}
Transactions ({% pmvalue sum %} / {% pmvalue snapshot.diff %})
diff --git a/nummi/main/urls.py b/nummi/main/urls.py
index 4c23cb3..272fc29 100644
--- a/nummi/main/urls.py
+++ b/nummi/main/urls.py
@@ -17,6 +17,5 @@ urlpatterns = [
path("category//del", views.del_category, name="del_category"),
path("snapshot", views.snapshot, name="snapshot"),
path("snapshot/", views.snapshot, name="snapshot"),
- path("snapshot//graph.svg", views.snapshot_graph, name="snapshot_graph"),
path("snapshot//del", views.del_snapshot, name="del_snapshot"),
]
diff --git a/nummi/main/views.py b/nummi/main/views.py
index 05278e3..e8ca412 100644
--- a/nummi/main/views.py
+++ b/nummi/main/views.py
@@ -6,8 +6,6 @@ from django.contrib.auth.mixins import LoginRequiredMixin
from django.views.generic import ListView
from django.core.paginator import Paginator
from django.db import models
-import matplotlib.pyplot as plt
-import tempfile
from .models import (
Transaction,
@@ -165,6 +163,27 @@ def snapshot(request, uuid=None):
"form": _form,
}
+ context["categories"] = (
+ _snapshot.transactions.values("category", "category__name", "category__icon")
+ .annotate(
+ sum=models.Sum("value"),
+ sum_m=models.Sum("value", filter=models.Q(value__lt=0)),
+ sum_p=models.Sum("value", filter=models.Q(value__gt=0)),
+ )
+ .order_by("-sum")
+ )
+ context["cat_lim"] = max(
+ map(
+ abs,
+ context["categories"]
+ .aggregate(
+ max=models.Max("sum_p"),
+ min=models.Min("sum_m"),
+ )
+ .values(),
+ )
+ )
+ context["cat_lim_m"] = -context["cat_lim"]
return render(
request,
"main/snapshot.html",
@@ -172,65 +191,6 @@ def snapshot(request, uuid=None):
)
-@login_required
-def snapshot_graph(request, uuid):
- _snapshot = get_object_or_404(Snapshot, id=uuid)
- _categories_p = (
- _snapshot.transactions.filter(value__gt=0)
- .values("category")
- .annotate(sum=models.Sum("value"))
- )
- _categories_m = (
- _snapshot.transactions.filter(value__lt=0)
- .values("category")
- .annotate(sum=models.Sum("value"))
- )
- _categories = (
- _snapshot.transactions.values("category")
- .annotate(sum=models.Sum("value"))
- .order_by("-sum")
- )
-
- print(_categories_p)
- print(_categories_m)
- fig, ax = plt.subplots(constrained_layout=True)
- ax.barh(
- [
- "*" if (c := _cat["category"]) is None else Category.objects.get(id=c).name
- for _cat in _categories
- ],
- [_cat["sum"] for _cat in _categories],
- hatch="/",
- fill=False,
- zorder=10,
- )
- ax.barh(
- [
- "*" if (c := _cat["category"]) is None else Category.objects.get(id=c).name
- for _cat in _categories_p
- ],
- [_cat["sum"] for _cat in _categories_p],
- color="#007339",
- zorder=9,
- )
- ax.barh(
- [
- "*" if (c := _cat["category"]) is None else Category.objects.get(id=c).name
- for _cat in _categories_m
- ],
- [_cat["sum"] for _cat in _categories_m],
- color="#bf1500",
- zorder=9,
- )
- ax.grid(color="k", alpha=0.2)
- ax.set(xlabel="Value (€)")
- # fig.tight_layout()
- with tempfile.NamedTemporaryFile(suffix=".svg") as f:
- fig.savefig(f.name)
- f.seek(0)
- return HttpResponse(f.read(), content_type="image/svg+xml")
-
-
@login_required
def del_snapshot(request, uuid):
_snapshot = get_object_or_404(Snapshot, id=uuid)