{% extends 'base.html' %} {% load static %} {% comment %} Cost History — Phase 13. Three line charts: monthly burn rate, 90-day renewal forecast, active contract count. One line per currency, hue from currency_hues map. Why three separate charts rather than one with multiple y-axes: Different units mean different y-scales — combining them on one plot either lies (about magnitudes) or invites confusion. One chart per metric keeps interpretation honest. Why inline SVG rather than a chart library: Zero JS dependency, prints natively, plays well with dark mode via currentColor. A 12-week × 2-currency series is small enough that hand-rolled paths are fine. Context (from views/cost_history.py): empty — bool; if True, render an empty state weeks — query window length snapshot_count — total snapshot rows in the window today — date.today() for "as of" label charts — list of {label, unit, series, value_max, date_min, date_max} each series item: {currency, hue, path_d, points, latest_value} currencies — sorted list of currencies present currency_hues — dict[currency → HSL hue 0-360] chart_w, chart_h — SVG viewBox dimensions {% endcomment %} {% block title %}Cost History{% endblock %} {% block extra_styles %} {% endblock %} {% block content %}

Cost History

Trend of monthly burn, 90-day renewal forecast, and active contract count over the past {{ weeks }} weeks. {% if not empty %} {{ snapshot_count }} snapshot{{ snapshot_count|pluralize }} captured. {% endif %}

{% if empty %}

No snapshots yet.

Run the Capture cost history snapshot Job (under Jobs → Contracts) to start collecting data, or schedule it weekly so the trend builds itself.

{% else %} {% if currency_legend %} {% endif %} {% for chart in charts %}

{{ chart.label }}

{% if chart.empty %}

No data for this metric yet.

{% else %} {% for s in chart.series %} {% for x, y in s.points %} {{ s.currency }}: {{ s.latest_value }} {% endfor %} {% endfor %}
{{ chart.date_min|date:"M j" }} max ≈ {{ chart.value_max|floatformat:0 }}{{ chart.unit }} {{ chart.date_max|date:"M j" }}
{% endif %}
{% endfor %} {% endif %}
{% endblock %}