|
4 | 4 | class="release-cycle-chart" |
5 | 5 | viewBox="0 0 {{ diagram_width }} {{ diagram_height }}" |
6 | 6 | > |
| 7 | + <style> |
| 8 | + /* Embedded styles for standalone viewing */ |
| 9 | + .release-cycle-chart { |
| 10 | + color-scheme: light; |
| 11 | +
|
| 12 | + {# Copy vars from Furo theme if present #} |
| 13 | + {% for varname, default in { |
| 14 | + 'color-foreground-primary': 'light-dark(#333, #fff)', |
| 15 | + 'color-background-primary': 'light-dark(#fff, #333)', |
| 16 | + 'color-brand-primary': '#4B8BBE', |
| 17 | + 'color-background-item': '#e0e0e0', |
| 18 | + }.items() %} |
| 19 | + --svg-{{varname}}: var(--{{varname}}, {{default}}); |
| 20 | + {% endfor %} |
| 21 | +
|
| 22 | + font-family: var( |
| 23 | + --font-stack, |
| 24 | + -apple-system, BlinkMacSystemFont, Segoe UI, Helvetica, |
| 25 | + Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji); |
| 26 | + width: 100%; |
| 27 | +
|
| 28 | + --blob-border-width: 1.6px; |
| 29 | + } |
| 30 | + .background { |
| 31 | + fill: var(--svg-color-background-primary); |
| 32 | + } |
| 33 | + .release-cycle-year-line { |
| 34 | + stroke: var(--svg-color-foreground-primary); |
| 35 | + stroke-width: 0.8px; |
| 36 | + opacity: 75%; |
| 37 | + } |
| 38 | + .release-cycle-today-line { |
| 39 | + stroke: var(--svg-color-brand-primary); |
| 40 | + stroke-width: var(--blob-border-width); |
| 41 | + } |
| 42 | + .release-cycle-row-shade { |
| 43 | + fill: var(--svg-color-background-item); |
| 44 | + opacity: 50%; |
| 45 | + } |
| 46 | + .release-cycle-blob { |
| 47 | + stroke-width: var(--blob-border-width); |
| 48 | + } |
| 49 | + .text-main { |
| 50 | + fill: var(--svg-color-foreground-primary); |
| 51 | +
|
| 52 | + /* use specific colours on known backgrounds */ |
| 53 | + &.release-cycle-status-security, |
| 54 | + &.release-cycle-status-bugfix { |
| 55 | + fill: black; |
| 56 | + } |
| 57 | + } |
| 58 | + .text-outline { |
| 59 | + /* an outline of the background color, in case it's not set |
| 60 | + correctly */ |
| 61 | + fill: transparent; |
| 62 | + stroke: var(--svg-color-background-primary); |
| 63 | + stroke-width: var(--blob-border-width); |
| 64 | +
|
| 65 | + /* use specific colours on known backgrounds */ |
| 66 | + &.release-cycle-status-security, |
| 67 | + &.release-cycle-status-bugfix { |
| 68 | + stroke: var(--status-bg-color); |
| 69 | + } |
| 70 | + } |
| 71 | + .release-cycle-status-end-of-life { |
| 72 | + --status-bg-color: #DD2200; |
| 73 | + --status-border-color: #FF8888; |
| 74 | + } |
| 75 | + .release-cycle-status-security { |
| 76 | + --status-bg-color: #FFDD44; |
| 77 | + --status-border-color: #FF8800; |
| 78 | + } |
| 79 | + .release-cycle-status-bugfix { |
| 80 | + --status-bg-color: #00DD22; |
| 81 | + --status-border-color: #008844; |
| 82 | + } |
| 83 | + .release-cycle-status-prerelease { |
| 84 | + --status-bg-color: teal; |
| 85 | + --status-border-color: darkgreen; |
| 86 | + } |
| 87 | + .release-cycle-status-feature { |
| 88 | + --status-bg-color: #2222EE; |
| 89 | + --status-border-color: #008888; |
| 90 | + } |
| 91 | + .release-cycle-blob { |
| 92 | + fill: var(--status-bg-color); |
| 93 | + stroke: transparent; |
| 94 | + } |
| 95 | + .release-cycle-blob-full { |
| 96 | + fill: var(--status-bg-color); |
| 97 | + stroke: var(--status-border-color); |
| 98 | + } |
| 99 | + .release-cycle-border { |
| 100 | + fill: transparent; |
| 101 | + stroke: var(--status-border-color); |
| 102 | + stroke-width: var(--blob-border-width); |
| 103 | + } |
| 104 | + </style> |
7 | 105 | <defs> |
8 | 106 | <linearGradient id="release-cycle-mask-gradient-{{ id_key }}"> |
9 | 107 | <stop stop-color="black" offset="0%" /> |
10 | 108 | <stop stop-color="white" offset="100%" /> |
11 | 109 | </linearGradient> |
12 | 110 | </defs> |
13 | 111 |
|
| 112 | + <rect |
| 113 | + class="background" |
| 114 | + x="0" |
| 115 | + y="0" |
| 116 | + width="{{ diagram_width }}" |
| 117 | + height="{{ diagram_height }}" |
| 118 | + /> |
| 119 | + |
14 | 120 | {% for version in versions %} |
15 | 121 | {% set y = version.y * line_height %} |
16 | | - |
17 | 122 | {% if version.y % 2 %} |
18 | 123 | <!-- Row shading --> |
19 | 124 | <rect |
|
28 | 133 |
|
29 | 134 | {% for year in years %} |
30 | 135 | <text |
31 | | - class="release-cycle-year-text" |
| 136 | + class="release-cycle-year-text text-main" |
32 | 137 | x="{{ (year_to_x(year) + year_to_x(year + 1)) / 2 }}" |
33 | 138 | y="{{ diagram_height - line_height }}" |
34 | 139 | font-size="{{ SCALE * 0.75 }}" |
|
74 | 179 | </mask> |
75 | 180 |
|
76 | 181 | {% for version in versions %} |
77 | | - <!-- Colourful blob with a label. --> |
| 182 | + <!-- Colourful blob. --> |
78 | 183 |
|
79 | 184 | {% set top_y = version.y * line_height - 1 * SCALE %} |
80 | 185 | {% set height = 1.25 * SCALE %} |
81 | 186 | {% set start_x = date_to_x(version.first_release_date) %} |
82 | 187 | {% set end_x = date_to_x(version.end_of_life_date) %} |
83 | 188 | {% set radius = 0.25 * SCALE %} |
84 | 189 |
|
85 | | - {% set small_text_y = version.y * line_height - 0.1 * SCALE %} |
86 | | - |
87 | 190 | <!-- bugfix/security blobs need to be split between the two phases. |
88 | 191 | Draw the rectangle with two path elements instead. |
89 | 192 | Thanks Claude.ai for the initial conversion. |
|
151 | 254 | mask="url(#release-cycle-mask-{{ id_key }})" |
152 | 255 | /> |
153 | 256 | {% endif %} |
| 257 | + {% endfor %} |
| 258 | + |
| 259 | + <!-- A line for today --> |
| 260 | + <line |
| 261 | + class="release-cycle-today-line" |
| 262 | + x1="{{ date_to_x(today) }}" |
| 263 | + x2="{{ date_to_x(today) }}" |
| 264 | + y1="0" |
| 265 | + y2="{{ diagram_height - line_height }}" |
| 266 | + font-size="{{ SCALE }}" |
| 267 | + /> |
| 268 | + |
| 269 | + {% for version in versions %} |
| 270 | + <!-- Label for colourful blob --> |
| 271 | + |
| 272 | + {% set start_x = date_to_x(version.first_release_date) %} |
| 273 | + {% set end_x = date_to_x(version.end_of_life_date) %} |
| 274 | + {% set middle_x = ([end_x, date_to_x(version.start_security_date)]|min) %} |
| 275 | + {% set small_text_y = version.y * line_height - 0.1 * SCALE %} |
154 | 276 |
|
155 | 277 | <!-- Add text before/after/inside the blob --> |
156 | | - <text |
157 | | - class="release-cycle-blob-label release-cycle-status-{{ version.status }}" |
158 | | - font-size="{{ SCALE * 0.75 }}" |
159 | | - y="{{ small_text_y }}" |
160 | | - {% if version.status == "bugfix" %} |
161 | | - x="{{ (start_x + middle_x) / 2 }}" |
162 | | - text-anchor="middle" |
163 | | - {% elif version.status == "security" %} |
164 | | - x="{{ (middle_x + end_x) / 2 }}" |
165 | | - text-anchor="middle" |
166 | | - {% elif version.status == "end-of-life" %} |
167 | | - x="{{ end_x + (0.25 * SCALE) }}" |
168 | | - text-anchor="start" |
169 | | - {% else %} |
170 | | - x="{{ start_x - (0.25 * SCALE) }}" |
171 | | - text-anchor="end" |
172 | | - {% endif %} |
173 | | - > |
174 | | - {{ version.status }} |
175 | | - </text> |
| 278 | + {% for cls in ('text-outline', 'text-main') %} |
| 279 | + <text |
| 280 | + class="release-cycle-blob-label {{cls}} release-cycle-status-{{ version.status }}" |
| 281 | + font-size="{{ SCALE * 0.75 }}" |
| 282 | + y="{{ small_text_y }}" |
| 283 | + {% if version.status == "bugfix" %} |
| 284 | + x="{{ (start_x + middle_x) / 2 }}" |
| 285 | + text-anchor="middle" |
| 286 | + {% elif version.status == "security" %} |
| 287 | + x="{{ (middle_x + end_x) / 2 }}" |
| 288 | + text-anchor="middle" |
| 289 | + {% elif version.status == "end-of-life" %} |
| 290 | + x="{{ end_x + (0.25 * SCALE) }}" |
| 291 | + text-anchor="start" |
| 292 | + {% else %} |
| 293 | + x="{{ start_x - (0.25 * SCALE) }}" |
| 294 | + text-anchor="end" |
| 295 | + {% endif %} |
| 296 | + > |
| 297 | + {{ version.status }} |
| 298 | + </text> |
| 299 | + {% endfor %} |
176 | 300 |
|
177 | 301 | <!-- Legend on the left --> |
178 | 302 | <text |
179 | | - class="release-cycle-version-label" |
| 303 | + class="release-cycle-version-label text-main" |
180 | 304 | x="{{ 0.5 * SCALE }}" |
181 | 305 | y="{{ version.y * line_height }}" |
182 | 306 | font-size="{{ SCALE }}" |
183 | 307 | > |
184 | 308 | Python {{ version.key }} |
185 | 309 | </text> |
186 | 310 | {% endfor %} |
187 | | - |
188 | | - <!-- A line for today --> |
189 | | - <line |
190 | | - class="release-cycle-today-line" |
191 | | - x1="{{ date_to_x(today) }}" |
192 | | - x2="{{ date_to_x(today) }}" |
193 | | - y1="0" |
194 | | - y2="{{ diagram_height - line_height }}" |
195 | | - font-size="{{ SCALE }}" |
196 | | - /> |
197 | 311 | </svg> |
0 commit comments