Hábito. includes a per-habit progress visualization that gives users a clear picture of their consistency over the last 30 days. The chart is built entirely on the server using Plotly Express, serialised to a self-contained HTML snippet, and injected into the Jinja2 template without any client-side charting code. The approach keeps the frontend simple — no JavaScript build step, no extra API calls — while still delivering a fully interactive chart that users can hover, zoom, and inspect.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/BrandonCVale/SISTEMA-HABITOS/llms.txt
Use this file to discover all available pages before exploring further.
Accessing the Chart
Route:GET /habitos/visualizar_progreso/<id>
The route first fetches the habit by ID, then enforces ownership before generating anything:
current_user, the route calls EstadisticasService.generar_grafica_ultimos_dias, passing the habit’s full registros relationship list:
How the Chart is Built
EstadisticasService.generar_grafica_ultimos_dias takes the list of RegistroHabito objects for one habit and produces a Plotly line chart. Here is the complete function as it appears in the source:
Build the date window
ultimos_dias is a list of date objects covering the last dias days (default 30), ordered from oldest to most recent. The list comprehension counts down from dias - 1 to 0, subtracting timedelta(days=i) from today each iteration.Extract completed dates
fechas_completadas is a Python set built from the RegistroHabito records where completado == True. Using a set gives O(1) membership testing in the next step.Construct the axes
eje_x— each date formatted as"DD/MM"(e.g."04/07") for a readable x-axis label.eje_y—1if the corresponding date is infechas_completadas,0otherwise. This binary representation maps to the y-axis tick labels'Completado'and'Fallado'.
Create the Plotly figure
px.line draws a line chart with dot markers. The line colour is #235336 (deep forest green), matching the app’s brand palette. markers=True adds a visible dot at each data point so individual days are easy to read.Customise the layout
Several layout properties are applied to integrate the chart cleanly with the app’s CSS:
| Property | Value | Effect |
|---|---|---|
yaxis.tickvals | [0, 1] | Only show two ticks on the y-axis |
yaxis.ticktext | ['Fallado', 'Completado'] | Human-readable labels instead of numbers |
plot_bgcolor | rgba(0,0,0,0) | Transparent plot area |
paper_bgcolor | rgba(0,0,0,0) | Transparent outer background |
margin | l=20, r=20, t=40, b=20 | Compact margins |
Serialise to HTML
fig.to_html(full_html=False, include_plotlyjs='cdn') produces a partial HTML string — just the <div> and the inline <script> for this chart, without a full <!DOCTYPE html> wrapper. Plotly’s JavaScript library is loaded from a CDN rather than bundled inline, keeping the response payload small.Rendering in the Template
Thegrafica_html string is injected directly into the Jinja2 template using the safe filter, which tells Jinja2 to render the raw HTML without escaping it:
<div> provides, blending seamlessly with the page’s CSS without any extra styling.
The chart defaults to the last 30 days, but the
dias parameter in generar_grafica_ultimos_dias can be changed programmatically when calling the service. For example, to show a 7-day or 90-day window, pass the desired value directly:include_plotlyjs='cdn' instructs Plotly to load its JavaScript library from Plotly’s CDN (https://cdn.plot.ly/plotly-*.min.js) rather than embedding the full library (~3 MB) inline in every response. An active internet connection is required to view the interactive chart. In offline or air-gapped environments, switch to include_plotlyjs=True to bundle Plotly’s JS inline, at the cost of a larger HTML payload.