From 20c1d02b40bcb9abb5882d0503e596c82e9819bb Mon Sep 17 00:00:00 2001 From: Tyler Hoang Date: Fri, 15 May 2026 01:50:15 -0700 Subject: Refine Lumi stats and detail UX --- templates/stats.html | 231 +++++++++++++++++++++++++++++++++------------------ 1 file changed, 152 insertions(+), 79 deletions(-) (limited to 'templates/stats.html') diff --git a/templates/stats.html b/templates/stats.html index 6e3a987..efb952c 100644 --- a/templates/stats.html +++ b/templates/stats.html @@ -3,113 +3,146 @@ {% block title %}Stats · Lumière{% endblock %} {% block content %} -
-
-
-

Stats

-

Watching patterns

-
+
+
+

Stats

+

Watching patterns

+

A research spread for your diary: the geography of what you watch, the people and genres that recur, and the rhythms that define a year of logging.

+
+
-
-
-
-
- Films watched - -
-
- Total runtime - -
-
-
+
+
+ Films watched + +
+
+ Total runtime + +
+
+ Average stars + +
+
+ Rewatch rate + +
+
-
+
+
+ Top director + +

No repeat viewings yet.

+
+
+ Most active month + +

No monthly cluster yet.

+
+
+ Countries logged + +

Based on films with country metadata.

+
+
+ +
+
-

World Map

-

Films per country

+

World map

+

Films by country

+

The map functions as a reading aid. Hover to inspect where your diary clusters geographically.

-
-
- Hover a country - Film count will appear here. +
+
+
+ Hover a country + Film count will appear here. +
-
+
-

Heatmap

+

Calendar

Past 365 days

+

A density view of your diary cadence over the trailing year.

-
-
-
-

Directors

-

Most watched

+
+
+
+
+

Directors

+

Most watched

+
-
-
    -
    - -
    -
    -
    -

    Stars

    -

    Distribution

    +
      +
      + +
      +
      +
      +

      Genres

      +

      Most watched

      +
      -
      -
      -
      - -
      -
      -
      -

      Films

      -

      Rewatches

      +
        +
        + +
        +
        +
        +

        Companions

        +

        Watched with

        +
        - -
        +
          +
          -
          -
          -
          -

          Companions

          -

          Watched with

          +
          +
          +
          +
          +

          Stars

          +

          Distribution

          +
          -
          -
            -
            - -
            -
            -
            -

            Genres

            -

            Most watched

            +
            +
            + +
            +
            +
            +

            Films

            +

            Rewatches

            +
            - -
              -
              - -
              -
              -
              -

              Decades

              -

              By era

              +
              +
              + +
              +
              +
              +

              Decades

              +

              By era

              +
              - -
                +
                  +
                  {% endblock %} @@ -133,6 +166,13 @@ return new Date(`${dateString}T00:00:00`).toLocaleDateString(undefined, { month: "short" }); } + function formatStatsMonth(monthKey) { + if (!monthKey) return "—"; + const [year, month] = monthKey.split("-"); + const date = new Date(Number(year), Number(month) - 1, 1); + return date.toLocaleDateString(undefined, { month: "long", year: "numeric" }); + } + function formatCountryCode(value) { return String(value).padStart(3, "0"); } @@ -156,6 +196,25 @@ const totalRuntime = document.getElementById("stats-total-runtime"); if (totalRuntime) totalRuntime.textContent = formatRuntime(data.total_runtime_minutes); + const averageStars = document.getElementById("stats-average-stars"); + if (averageStars) averageStars.textContent = data.average_stars ? data.average_stars.toFixed(1) : "—"; + + const rewatchRate = document.getElementById("stats-rewatch-rate"); + if (rewatchRate) rewatchRate.textContent = data.rewatch_rate ? `${Math.round(data.rewatch_rate.rate * 100)}%` : "—"; + + const topDirector = document.getElementById("stats-top-director"); + const topDirectorMeta = document.getElementById("stats-top-director-meta"); + if (topDirector) topDirector.textContent = data.top_director ? data.top_director.director : "—"; + if (topDirectorMeta) topDirectorMeta.textContent = data.top_director ? `${data.top_director.count} films logged` : "No repeat viewings yet."; + + const topMonth = document.getElementById("stats-top-month"); + const topMonthMeta = document.getElementById("stats-top-month-meta"); + if (topMonth) topMonth.textContent = data.top_month ? formatStatsMonth(data.top_month.month) : "—"; + if (topMonthMeta) topMonthMeta.textContent = data.top_month ? `${data.top_month.count} diary entries` : "No monthly cluster yet."; + + const countryCount = document.getElementById("stats-country-count"); + if (countryCount) countryCount.textContent = data.films_per_country.length; + const topDirectors = document.getElementById("top-directors"); topDirectors.innerHTML = data.most_watched_directors.slice(0, 8).map((item) => `
                1. ${item.director}${item.count}
                2. @@ -200,7 +259,7 @@ const gap = item.days_between != null ? `${item.days_between}d apart` : ""; - return `
                  + return `
                  ${item.title} ${gap}${drift}${item.watches}×
                  `; @@ -218,6 +277,19 @@ return { ...item, dateObj: date }; }); + const containerWidth = container.clientWidth || 720; + const maxCell = 13; + const minCell = 8; + const weekdayWidth = containerWidth < 640 ? 20 : 34; + const gap = containerWidth < 640 ? 2 : 4; + const availableWidth = Math.max(53 * minCell, containerWidth - weekdayWidth - 8); + const computedCell = Math.floor((availableWidth - (52 * gap)) / 53); + const cellSize = Math.max(minCell, Math.min(maxCell, computedCell)); + + container.style.setProperty("--heatmap-cell", `${cellSize}px`); + container.style.setProperty("--heatmap-gap", `${gap}px`); + container.style.setProperty("--heatmap-weekday-width", `${weekdayWidth}px`); + const firstWeekStart = new Date(parsedDays[0].dateObj); const mondayOffset = (firstWeekStart.getDay() + 6) % 7; firstWeekStart.setDate(firstWeekStart.getDate() - mondayOffset); @@ -343,6 +415,7 @@ renderLists(data); renderHeatmap(data.films_per_day_365); await renderMap(data); + window.addEventListener("resize", () => renderHeatmap(data.films_per_day_365)); } bootStats(); -- cgit v1.3-2-g0d8e