Skip to content

Commit ba2d7c8

Browse files
Start the cumulative-downloads chart at the first non-zero week
Walking history back beyond the `--weeks` window and clamping forward left a long flat run of zero weeks before the first published version on the chart. Drop those leading zero buckets so the line actually starts at week 1 of the package's life. When real history exceeds the trend window, the visible range is still clamped to the most recent `--weeks` buckets so the chart stays readable. Regenerated SVG now spans Apr 20 → May 18 (5 weeks of actual history) instead of the prior 26-week window padded with zeros. Co-authored-by: Open Codex <hff582580@gmail.com>
1 parent fe2961a commit ba2d7c8

2 files changed

Lines changed: 48 additions & 42 deletions

File tree

.github/npm-total-downloads.svg

Lines changed: 10 additions & 31 deletions
Loading

.github/scripts/update_npm_download_chart.py

Lines changed: 38 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -97,10 +97,20 @@ def fetch_daily_downloads_since(package_name, since):
9797

9898
def aggregate_cumulative(daily_rows, window_weeks):
9999
"""Bucket daily rows into 7-day periods of the visible window and emit
100-
the running total at each bucket boundary, including history before
101-
the window so the line starts at the lifetime cumulative count."""
100+
the running total at each bucket boundary.
101+
102+
Walks every bucket back to the earliest known day (no artificial floor at
103+
`window_weeks`), then drops any leading buckets whose cumulative total is
104+
still zero. The visual line therefore starts at the first week the
105+
package saw any downloads — no flat run of zeros before launch — and
106+
grows monotonically from there.
107+
108+
When real history is longer than `window_weeks`, the displayed range is
109+
clamped to the most recent `window_weeks` periods so the dashboard stays
110+
readable; the displayed line still starts at the lifetime baseline
111+
because the running total carries pre-window downloads.
112+
"""
102113
end = latest_complete_period_end()
103-
first_visible = end - timedelta(days=(window_weeks * 7) - 1)
104114

105115
by_day = {}
106116
for row in daily_rows:
@@ -110,15 +120,20 @@ def aggregate_cumulative(daily_rows, window_weeks):
110120
continue
111121
by_day[day] = int(row.get("downloads", 0))
112122

113-
pre_total = 0
114-
for day, count in by_day.items():
115-
if day < first_visible:
116-
pre_total += count
123+
if not by_day:
124+
return []
125+
126+
earliest_day = min(by_day)
127+
# Align to a Monday-anchored 7-day bucket whose end day matches `end` so
128+
# the rightmost label is always the latest complete period.
129+
total_days = (end - earliest_day).days + 1
130+
bucket_count = max(1, math.ceil(total_days / 7.0))
131+
first_bucket_start = end - timedelta(days=bucket_count * 7 - 1)
117132

118133
buckets = []
119-
running = pre_total
120-
for i in range(window_weeks):
121-
start = first_visible + timedelta(days=i * 7)
134+
running = 0
135+
for i in range(bucket_count):
136+
start = first_bucket_start + timedelta(days=i * 7)
122137
bucket_end = start + timedelta(days=6)
123138
bucket_sum = sum(
124139
count
@@ -127,7 +142,19 @@ def aggregate_cumulative(daily_rows, window_weeks):
127142
)
128143
running += bucket_sum
129144
buckets.append((start, running))
130-
return buckets
145+
146+
# Drop leading buckets that are still at zero (pre-launch padding).
147+
first_nonzero = next(
148+
(idx for idx, (_, total) in enumerate(buckets) if total > 0),
149+
len(buckets),
150+
)
151+
visible = buckets[first_nonzero:]
152+
153+
# If real history exceeds the trend window, keep only the most recent
154+
# `window_weeks` buckets to keep the chart readable.
155+
if len(visible) > window_weeks:
156+
visible = visible[-window_weeks:]
157+
return visible
131158

132159

133160
def nice_upper_bound(value):

0 commit comments

Comments
 (0)