highlight today's bar, calculate daily stats considering irregular expenses and show them interactively
This commit is contained in:
@@ -30,13 +30,16 @@ class ActualTransaction:
|
|||||||
|
|
||||||
|
|
||||||
class DailyStat:
|
class DailyStat:
|
||||||
def __init__(self, date, balance_amount, actual_transactions, resulting_amount):
|
def __init__(self, stat_id, date, balance_amount, actual_transactions, resulting_amount):
|
||||||
|
self.id = stat_id
|
||||||
self.date = date
|
self.date = date
|
||||||
self.balance_amount = balance_amount
|
self.balance_amount = balance_amount
|
||||||
self.actual_transactions = actual_transactions
|
self.actual_transactions = actual_transactions
|
||||||
self.resulting_amount = resulting_amount
|
self.resulting_amount = resulting_amount
|
||||||
self.highlighted = False
|
self.highlighted = False
|
||||||
self.percentage = 40
|
self.percentage = 40
|
||||||
|
self.resulting_amount_irregular = self.resulting_amount
|
||||||
|
self.percentage_irregular = self.percentage
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return f"DailyStat({self.date}, {self.balance_amount}, " \
|
return f"DailyStat({self.date}, {self.balance_amount}, " \
|
||||||
@@ -46,6 +49,11 @@ class DailyStat:
|
|||||||
self.highlighted = self.date == today
|
self.highlighted = self.date == today
|
||||||
if self.resulting_amount is not None:
|
if self.resulting_amount is not None:
|
||||||
self.percentage = int((self.resulting_amount / amount_scale) * 100)
|
self.percentage = int((self.resulting_amount / amount_scale) * 100)
|
||||||
|
self.percentage_irregular = self.percentage
|
||||||
|
|
||||||
|
def generate_irregular_graph_bar_attributes(self, amount_scale):
|
||||||
|
if self.resulting_amount_irregular is not None:
|
||||||
|
self.percentage_irregular = int((self.resulting_amount_irregular / amount_scale) * 100)
|
||||||
|
|
||||||
|
|
||||||
class Statistics:
|
class Statistics:
|
||||||
@@ -78,6 +86,7 @@ class Statistics:
|
|||||||
self._calculate_daily_amount_scale()
|
self._calculate_daily_amount_scale()
|
||||||
self._generate_graph_bar_attributes()
|
self._generate_graph_bar_attributes()
|
||||||
self._calculate_analysis()
|
self._calculate_analysis()
|
||||||
|
self._add_statistics_considering_analysis()
|
||||||
|
|
||||||
def _fetch_relevant_balances(self):
|
def _fetch_relevant_balances(self):
|
||||||
self.balances = []
|
self.balances = []
|
||||||
@@ -136,6 +145,7 @@ class Statistics:
|
|||||||
|
|
||||||
def _calculate_daily_stats(self):
|
def _calculate_daily_stats(self):
|
||||||
self.daily_stats = []
|
self.daily_stats = []
|
||||||
|
iter_id = 0
|
||||||
iter_date = self.real_calc_start
|
iter_date = self.real_calc_start
|
||||||
iter_amount = None
|
iter_amount = None
|
||||||
while iter_date < self.calc_end:
|
while iter_date < self.calc_end:
|
||||||
@@ -156,11 +166,13 @@ class Statistics:
|
|||||||
|
|
||||||
if iter_amount is not None:
|
if iter_amount is not None:
|
||||||
self.daily_stats.append(DailyStat(
|
self.daily_stats.append(DailyStat(
|
||||||
|
stat_id=iter_id,
|
||||||
date=iter_date,
|
date=iter_date,
|
||||||
balance_amount=balance_amount,
|
balance_amount=balance_amount,
|
||||||
actual_transactions=actual_transactions,
|
actual_transactions=actual_transactions,
|
||||||
resulting_amount=iter_amount,
|
resulting_amount=iter_amount,
|
||||||
))
|
))
|
||||||
|
iter_id += 1
|
||||||
iter_date += relativedelta(days=1)
|
iter_date += relativedelta(days=1)
|
||||||
|
|
||||||
def _calculate_daily_amount_scale(self):
|
def _calculate_daily_amount_scale(self):
|
||||||
@@ -213,5 +225,21 @@ class Statistics:
|
|||||||
|
|
||||||
self.avg_monthly_result_complete = self.avg_monthly_result + self.avg_monthly_irregular_expenses
|
self.avg_monthly_result_complete = self.avg_monthly_result + self.avg_monthly_irregular_expenses
|
||||||
|
|
||||||
|
def _add_statistics_considering_analysis(self):
|
||||||
|
previous_original_amount = None
|
||||||
|
iter_amount = None
|
||||||
|
for stat in self.daily_stats:
|
||||||
|
if stat.resulting_amount is not None:
|
||||||
|
relevant_balances = [bal for bal in self.balances if bal.date == stat.date]
|
||||||
|
if relevant_balances or previous_original_amount is None:
|
||||||
|
iter_amount = stat.resulting_amount + self.avg_daily_irregular_expenses
|
||||||
|
else:
|
||||||
|
orig_diff = stat.resulting_amount - previous_original_amount
|
||||||
|
new_diff = orig_diff + self.avg_daily_irregular_expenses
|
||||||
|
iter_amount += new_diff
|
||||||
|
stat.resulting_amount_irregular = iter_amount
|
||||||
|
stat.generate_irregular_graph_bar_attributes(self.daily_amount_scale)
|
||||||
|
previous_original_amount = stat.resulting_amount
|
||||||
|
|
||||||
def get_daily_stats_in_range(self):
|
def get_daily_stats_in_range(self):
|
||||||
return [s for s in self.daily_stats if self.display_start <= s.date <= self.display_end]
|
return [s for s in self.daily_stats if self.display_start <= s.date <= self.display_end]
|
||||||
|
|||||||
@@ -179,10 +179,11 @@ tr:hover {
|
|||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
background-color: #FFCC99;
|
background-color: #FFCC99;
|
||||||
z-index: 10;
|
z-index: 10;
|
||||||
|
transition: height 250ms;
|
||||||
}
|
}
|
||||||
|
|
||||||
.graph-bar.highlighted {
|
.graph-bar.highlighted {
|
||||||
border: 1px solid #FFFCF9;
|
background-color: #CC6622;
|
||||||
}
|
}
|
||||||
|
|
||||||
.graph-bar:hover {
|
.graph-bar:hover {
|
||||||
|
|||||||
@@ -14,17 +14,11 @@
|
|||||||
<div id="date-panel">-</div>
|
<div id="date-panel">-</div>
|
||||||
<div id="graph">
|
<div id="graph">
|
||||||
{% for stat in daily_stats %}
|
{% for stat in daily_stats %}
|
||||||
{% if stat.percentage is None %}
|
<div class="graph-bar{% if stat.highlighted %} highlighted{% endif %}"
|
||||||
<div class="graph-bar"
|
id="graph-bar-{{ stat.id }}"
|
||||||
onmouseover="showGraphBarDate('{{ stat.date|date:"d.m.y" }}')"
|
onmouseover="showGraphBarDate('{{ stat.date|date:"d.m.y" }}')"
|
||||||
onmouseleave="clearGraphBarDate()">
|
onmouseleave="clearGraphBarDate()">
|
||||||
</div>
|
</div>
|
||||||
{% else %}
|
|
||||||
<div class="graph-bar" style="height: {{ stat.percentage }}%;"
|
|
||||||
onmouseover="showGraphBarDate('{{ stat.date|date:"d.m.y" }}')"
|
|
||||||
onmouseleave="clearGraphBarDate()">
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
{% else %}
|
{% else %}
|
||||||
@@ -161,6 +155,12 @@
|
|||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
const graph = document.getElementById('graph');
|
const graph = document.getElementById('graph');
|
||||||
const datePanel = document.getElementById('date-panel');
|
const datePanel = document.getElementById('date-panel');
|
||||||
|
const irrExpCheckbox = document.getElementById('irregular-expenses-checkbox');
|
||||||
|
|
||||||
|
{% for stat in daily_stats %}
|
||||||
|
const graphBar{{ stat.id }} = document.getElementById('graph-bar-{{ stat.id }}');
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
let scrolling = false;
|
let scrolling = false;
|
||||||
let initX;
|
let initX;
|
||||||
let initScrollLeft;
|
let initScrollLeft;
|
||||||
@@ -194,9 +194,23 @@
|
|||||||
datePanel.innerText = '-';
|
datePanel.innerText = '-';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function applyGraphBarHeights() {
|
||||||
|
if (irrExpCheckbox.checked) {
|
||||||
|
{% for stat in daily_stats %}
|
||||||
|
graphBar{{ stat.id }}.style.height = '{{ stat.percentage_irregular }}%';
|
||||||
|
{% endfor %}
|
||||||
|
} else {
|
||||||
|
{% for stat in daily_stats %}
|
||||||
|
graphBar{{ stat.id }}.style.height = '{{ stat.percentage }}%';
|
||||||
|
{% endfor %}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
graph.addEventListener('mousedown', (event) => startDragScroll(event));
|
graph.addEventListener('mousedown', (event) => startDragScroll(event));
|
||||||
graph.addEventListener('mouseleave', () => stopDragScroll());
|
graph.addEventListener('mouseleave', () => stopDragScroll());
|
||||||
graph.addEventListener('mouseup', () => stopDragScroll());
|
graph.addEventListener('mouseup', () => stopDragScroll());
|
||||||
graph.addEventListener('mousemove', (event) => doDragScroll(event));
|
graph.addEventListener('mousemove', (event) => doDragScroll(event));
|
||||||
|
irrExpCheckbox.addEventListener('change', () => applyGraphBarHeights());
|
||||||
|
window.onload = applyGraphBarHeights;
|
||||||
</script>
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
Reference in New Issue
Block a user