mirror of
https://github.com/eitchtee/WYGIWYH.git
synced 2026-07-09 14:25:25 +02:00
fix(insights): sankey diagrams nodes too far from destination
This commit is contained in:
@@ -52,13 +52,29 @@ def generate_sankey_data_by_account(transactions_queryset):
|
|||||||
total_volume_by_currency.get(currency, Decimal("0")) + amount
|
total_volume_by_currency.get(currency, Decimal("0")) + amount
|
||||||
)
|
)
|
||||||
|
|
||||||
|
unique_accounts = {
|
||||||
|
account_id: idx
|
||||||
|
for idx, account_id in enumerate(
|
||||||
|
transactions_queryset.values_list("account", flat=True).distinct()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
def get_node_priority(node_id: str) -> int:
|
||||||
|
"""Get priority based on the account ID embedded in the node ID."""
|
||||||
|
account_id = int(node_id.split("_")[-1])
|
||||||
|
return unique_accounts[account_id]
|
||||||
|
|
||||||
def get_node_id(node_type: str, name: str, account_id: int) -> str:
|
def get_node_id(node_type: str, name: str, account_id: int) -> str:
|
||||||
"""Generate unique node ID."""
|
"""Generate unique node ID."""
|
||||||
return f"{node_type}_{name}_{account_id}".lower().replace(" ", "_")
|
return f"{node_type}_{name}_{account_id}".lower().replace(" ", "_")
|
||||||
|
|
||||||
def add_node(node_id: str, display_name: str) -> None:
|
def add_node(node_id: str, display_name: str) -> None:
|
||||||
"""Add node with both ID and display name."""
|
"""Add node with ID, display name and priority."""
|
||||||
nodes[node_id] = {"id": node_id, "name": display_name}
|
nodes[node_id] = {
|
||||||
|
"id": node_id,
|
||||||
|
"name": display_name,
|
||||||
|
"priority": get_node_priority(node_id),
|
||||||
|
}
|
||||||
|
|
||||||
def add_flow(
|
def add_flow(
|
||||||
from_node_id: str, to_node_id: str, amount: Decimal, currency, is_income: bool
|
from_node_id: str, to_node_id: str, amount: Decimal, currency, is_income: bool
|
||||||
@@ -167,13 +183,29 @@ def generate_sankey_data_by_currency(transactions_queryset):
|
|||||||
total_volume_by_currency.get(currency, Decimal("0")) + amount
|
total_volume_by_currency.get(currency, Decimal("0")) + amount
|
||||||
)
|
)
|
||||||
|
|
||||||
|
unique_currencies = {
|
||||||
|
currency_id: idx
|
||||||
|
for idx, currency_id in enumerate(
|
||||||
|
transactions_queryset.values_list("account__currency", flat=True).distinct()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
def get_node_priority(node_id: str) -> int:
|
||||||
|
"""Get priority based on the currency ID embedded in the node ID."""
|
||||||
|
currency_id = int(node_id.split("_")[-1])
|
||||||
|
return unique_currencies[currency_id]
|
||||||
|
|
||||||
def get_node_id(node_type: str, name: str, currency_id: int) -> str:
|
def get_node_id(node_type: str, name: str, currency_id: int) -> str:
|
||||||
"""Generate unique node ID including currency information."""
|
"""Generate unique node ID including currency information."""
|
||||||
return f"{node_type}_{name}_{currency_id}".lower().replace(" ", "_")
|
return f"{node_type}_{name}_{currency_id}".lower().replace(" ", "_")
|
||||||
|
|
||||||
def add_node(node_id: str, display_name: str) -> None:
|
def add_node(node_id: str, display_name: str) -> None:
|
||||||
"""Add node with both ID and display name."""
|
"""Add node with ID, display name and priority."""
|
||||||
nodes[node_id] = {"id": node_id, "name": display_name}
|
nodes[node_id] = {
|
||||||
|
"id": node_id,
|
||||||
|
"name": display_name,
|
||||||
|
"priority": get_node_priority(node_id),
|
||||||
|
}
|
||||||
|
|
||||||
def add_flow(
|
def add_flow(
|
||||||
from_node_id: str, to_node_id: str, amount: Decimal, currency, is_income: bool
|
from_node_id: str, to_node_id: str, amount: Decimal, currency, is_income: bool
|
||||||
|
|||||||
@@ -1,15 +1,17 @@
|
|||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
|
|
||||||
{% if type == 'account' %}
|
{% if type == 'account' %}
|
||||||
<div class="show-loading" hx-get="{% url 'insights_sankey_by_account' %}" hx-trigger="updated from:window" hx-swap="outerHTML" hx-include="#picker-form, #picker-type">
|
<div class="show-loading" hx-get="{% url 'insights_sankey_by_account' %}" hx-trigger="updated from:window"
|
||||||
|
hx-swap="outerHTML" hx-include="#picker-form, #picker-type">
|
||||||
{% else %}
|
{% else %}
|
||||||
<div class="show-loading" hx-get="{% url 'insights_sankey_by_currency' %}" hx-trigger="updated from:window" hx-swap="outerHTML" hx-include="#picker-form, #picker-type">
|
<div class="show-loading" hx-get="{% url 'insights_sankey_by_currency' %}" hx-trigger="updated from:window"
|
||||||
|
hx-swap="outerHTML" hx-include="#picker-form, #picker-type">
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<div class="chart-container position-relative tw-min-h-[60vh] tw-max-h-[60vh] tw-h-full tw-w-full"
|
<div class="chart-container position-relative tw-min-h-[60vh] tw-max-h-[60vh] tw-h-full tw-w-full"
|
||||||
id="sankeyContainer"
|
id="sankeyContainer"
|
||||||
_="init call setupSankeyChart() end">
|
_="init call setupSankeyChart() end">
|
||||||
<canvas id="sankeyChart"></canvas>
|
<canvas id="sankeyChart"></canvas>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
@@ -61,7 +63,11 @@
|
|||||||
colorMode: 'gradient',
|
colorMode: 'gradient',
|
||||||
alpha: 0.5,
|
alpha: 0.5,
|
||||||
size: 'max',
|
size: 'max',
|
||||||
color: "white"
|
color: "white",
|
||||||
|
priority: data.nodes.reduce((acc, node) => {
|
||||||
|
acc[node.id] = node.priority;
|
||||||
|
return acc;
|
||||||
|
}, {}),
|
||||||
}]
|
}]
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user