diff --git a/.samples/ci-svg.py b/.samples/ci-svg.py
index 1efb5e1a..321341ac 100644
--- a/.samples/ci-svg.py
+++ b/.samples/ci-svg.py
@@ -11,8 +11,9 @@
of the site cannot be the page itself. The same data (every run of every version in the folder), the same
rules and the same colours as site/samples.js and samples.css of DotNetSolutionKit:
-- a day keeps the result of the branch's last run; a pass fades to ice and a failure rots to dark red over
- 30 days without a run, the colours mixed in OKLab as the site's color-mix does;
+- a day keeps the result of the branch's last run and its colour; a day without a run shows how long ago
+ the run was: a pass a step bluer every 2 days, a failure a little darker every day, ice or dark red from
+ day 30 on, the colours mixed in OKLab as the site's color-mix does;
- 52 weeks back, the weeks to come fading out, Monday at the top and Sunday at the bottom;
- light and dark follow the reader's colour scheme.
@@ -25,6 +26,7 @@
import sys
FADE_DAYS = 30
+PASS_STEP_DAYS = 2
PAST_WEEKS = 52
FUTURE_WEEKS = 8
CELL, GAP = 11, 3
@@ -117,10 +119,16 @@ def fill(cell, theme):
return t["empty"], max(0.15, 1 - cell["future"] / (7 * FUTURE_WEEKS))
if "ok" not in cell:
return t["empty"], 1.0
- fade = min(cell["age"] / FADE_DAYS, 1)
+ fade = fade_of(cell["ok"], cell["age"])
return (mix(t["sleep"], fade, t["ok"]) if cell["ok"] else mix(t["rot"], fade, t["bad"])), 1.0
+def fade_of(ok, age):
+ """How far a day has gone from its result, 0 to 1: a pass in steps of PASS_STEP_DAYS, a failure evenly."""
+ days = age // PASS_STEP_DAYS * PASS_STEP_DAYS if ok else age
+ return min(days / FADE_DAYS, 1)
+
+
# ---- the picture ----------------------------------------------------------------------------------------
def svg(branch, runs, today):
grid = cells(runs, today)
@@ -184,12 +192,16 @@ def svg(branch, runs, today):
def legend():
"""What the colours of a day mean: one picture for every branch, under its days in the README."""
- rows = (("passed", ("ok", "sleep"), f"a pass, fading to ice over {FADE_DAYS} days without a run"),
- ("failed", ("bad", "rot"), f"a failure, rotting to dark red over {FADE_DAYS} days without a run"))
- swatches, label_w = 5, 48
+ ages = (0, PASS_STEP_DAYS, FADE_DAYS // 4, FADE_DAYS // 2, FADE_DAYS)
+ rows = (("passed", True, f"the day of a pass, then a step bluer every {PASS_STEP_DAYS} days without a run"),
+ ("failed", False, "the day of a failure, then a little darker every day without a run"))
+ notes = (f"the squares: {', '.join(map(str, ages[:-1]))} and {ages[-1]} days after the run",
+ "a day keeps its colour; a new run makes its day green or red again")
+ swatches, label_w = len(ages), 48
words_x = LEFT + label_w + swatches * (CELL + GAP) + 8
- width = words_x + 330
- height = 34 + 4 * 20 + 4
+ # 11px text averages under 6px a character: the widest line sets the width
+ width = words_x + 6 * max(len(w) for w in [r[2] for r in rows] + list(notes)) + 16
+ height = 34 + (len(rows) + len(notes) + 2) * 20 + 4
css = ["text{font:11px system-ui,-apple-system,'Segoe UI',sans-serif}", ".t{font-size:13px;font-weight:600}"]
@@ -207,14 +219,19 @@ def cell(cls, k, y, extra=""):
body.append(f'')
y = 34
- for label, (start, end), words in rows:
+ for label, ok, words in rows:
+ start, end = ("ok", "sleep") if ok else ("bad", "rot")
body.append(f'{label}')
- for k in range(swatches):
+ for k, age in enumerate(ages):
cls = f"L{label}{k}"
- themed(lambda t, cls=cls, k=k: f".{cls}{{fill:{mix(t[end], k / (swatches - 1), t[start])}}}")
+ fade = fade_of(ok, age)
+ themed(lambda t, cls=cls, fade=fade, start=start, end=end: f".{cls}{{fill:{mix(t[end], fade, t[start])}}}")
cell(cls, k, y)
body.append(f'{words}')
y += 20
+ for words in notes:
+ body.append(f'{words}')
+ y += 20
cell("e", 0, y)
body.append(f'no run yet')
y += 20
@@ -223,8 +240,9 @@ def cell(cls, k, y, extra=""):
body.append(f'the weeks to come')
return (f'\n")
diff --git a/.samples/generate.sh b/.samples/generate.sh
index c622c9b6..fd3c5b02 100644
--- a/.samples/generate.sh
+++ b/.samples/generate.sh
@@ -43,6 +43,7 @@ about=$(jq -r --arg b "$branch" '.[] | select(.branch == $b) | .about' "$here/va
home=$(jq -r '.[] | select(.default) | .branch' "$here/variants.json")
raw="https://raw.githubusercontent.com/${GITHUB_REPOSITORY:-sawking-tech/DotNetSolutionKit.Samples}"
fade=$(sed -n 's/^FADE_DAYS = //p' "$here/ci-svg.py")
+step=$(sed -n 's/^PASS_STEP_DAYS = //p' "$here/ci-svg.py")
# What the colours of the days mean: one legend for every branch, drawn by ci-svg.py on the default
# branch, and the same in words.
@@ -50,10 +51,11 @@ legend() {
echo ""
echo
echo "Each square is a day in UTC, Monday at the top and Sunday at the bottom. A day shows the result of the"
- echo "last CI run up to it: green for a pass, red for a failure. With no new run the colour changes over $fade"
- echo "days, a pass fading to ice blue and a failure turning dark red, so an old result is told apart from a"
- echo "fresh one. A pale square is a day before the first run; the fading squares on the right are the weeks"
- echo "to come."
+ echo "last CI run up to it: green for a pass, red for a failure. A day without a run shows how long ago the"
+ echo "run was: after a pass it turns a step bluer every $step days, after a failure a little darker every day,"
+ echo "ice blue or dark red from day $fade on. A day keeps its colour; a new run makes its day green or red"
+ echo "again. A pale square is a day before the first run; the fading squares on the right are the weeks to"
+ echo "come."
}
{
echo "# Sample: $branch"