hydroxy

Spiral chart

A time series wound onto a spiral, one turn per period, so the same moment in every period lines up along a spoke. Each value is a short arc shaded by value; recurring patterns show as wedges of colour. The spiral draws out from the centre.

Daily cycling distance

Kilometres a day, one turn per year from the centre out. Summers bloom as darker arcs along the same months.

Daily cycling distance in kilometres, 2023 to 2025 (first 1000 of 1096 values)
Value
1 Jan 202335 km
2 Jan 202312 km
3 Jan 20239 km
4 Jan 20230 km
5 Jan 20230 km
6 Jan 20230 km
7 Jan 20230 km
8 Jan 202335 km
9 Jan 202313 km
10 Jan 20230 km
11 Jan 202313 km
12 Jan 20230 km
13 Jan 202310 km
14 Jan 20230 km
15 Jan 202335 km
16 Jan 20230 km
17 Jan 202314 km
18 Jan 20230 km
19 Jan 202311 km
20 Jan 202311 km
21 Jan 20230 km
22 Jan 20230 km
23 Jan 20230 km
24 Jan 202310 km
25 Jan 20230 km
26 Jan 202312 km
27 Jan 20230 km
28 Jan 20230 km
29 Jan 202335 km
30 Jan 20230 km
31 Jan 20230 km
1 Feb 202312 km
2 Feb 20230 km
3 Feb 202313 km
4 Feb 202339 km
5 Feb 20230 km
6 Feb 20230 km
7 Feb 202312 km
8 Feb 20230 km
9 Feb 20230 km
10 Feb 20230 km
11 Feb 20230 km
12 Feb 20230 km
13 Feb 202314 km
14 Feb 202313 km
15 Feb 202311 km
16 Feb 20230 km
17 Feb 20230 km
18 Feb 20230 km
19 Feb 202340 km
20 Feb 20230 km
21 Feb 20230 km
22 Feb 20230 km
23 Feb 202315 km
24 Feb 20230 km
25 Feb 202346 km
26 Feb 20230 km
27 Feb 20230 km
28 Feb 202314 km
1 Mar 20230 km
2 Mar 202316 km
3 Mar 202318 km
4 Mar 20230 km
5 Mar 20230 km
6 Mar 20230 km
7 Mar 20230 km
8 Mar 202314 km
9 Mar 20230 km
10 Mar 202317 km
11 Mar 202339 km
12 Mar 20230 km
13 Mar 202319 km
14 Mar 202320 km
15 Mar 20230 km
16 Mar 20230 km
17 Mar 202319 km
18 Mar 202352 km
19 Mar 20230 km
20 Mar 20230 km
21 Mar 202320 km
22 Mar 20230 km
23 Mar 202320 km
24 Mar 202317 km
25 Mar 202338 km
26 Mar 202342 km
27 Mar 202319 km
28 Mar 202317 km
29 Mar 202316 km
30 Mar 202319 km
31 Mar 202317 km
1 Apr 202350 km
2 Apr 20230 km
3 Apr 202322 km
4 Apr 20230 km
5 Apr 202319 km
6 Apr 202318 km
7 Apr 202323 km
8 Apr 20230 km
9 Apr 202354 km
10 Apr 202324 km
11 Apr 202320 km
12 Apr 20230 km
13 Apr 20230 km
14 Apr 202319 km
15 Apr 20230 km
16 Apr 202363 km
17 Apr 202323 km
18 Apr 202324 km
19 Apr 202323 km
20 Apr 202325 km
21 Apr 202321 km
22 Apr 20230 km
23 Apr 202353 km
24 Apr 202326 km
25 Apr 202322 km
26 Apr 202322 km
27 Apr 202324 km
28 Apr 20230 km
29 Apr 202346 km
30 Apr 202346 km
1 May 202326 km
2 May 202323 km
3 May 20230 km
4 May 20230 km
5 May 202325 km
6 May 202361 km
7 May 202361 km
8 May 202323 km
9 May 202327 km
10 May 202325 km
11 May 202327 km
12 May 202324 km
13 May 202346 km
14 May 202342 km
15 May 202327 km
16 May 20230 km
17 May 20230 km
18 May 20230 km
19 May 20230 km
20 May 202375 km
21 May 20230 km
22 May 202328 km
23 May 202328 km
24 May 202330 km
25 May 202329 km
26 May 202329 km
27 May 202337 km
28 May 202348 km
29 May 202327 km
30 May 20230 km
31 May 20230 km
1 Jun 202326 km
2 Jun 202328 km
3 Jun 202360 km
4 Jun 202372 km
5 Jun 20230 km
6 Jun 202326 km
7 Jun 202325 km
8 Jun 202326 km
9 Jun 202327 km
10 Jun 202353 km
11 Jun 20230 km
12 Jun 20230 km
13 Jun 202330 km
14 Jun 202327 km
15 Jun 20230 km
16 Jun 202327 km
17 Jun 202359 km
18 Jun 202384 km
19 Jun 202328 km
20 Jun 202329 km
21 Jun 202330 km
22 Jun 20230 km
23 Jun 202329 km
24 Jun 202377 km
25 Jun 20230 km
26 Jun 202329 km
27 Jun 202328 km
28 Jun 202331 km
29 Jun 202329 km
30 Jun 202330 km
1 Jul 202340 km
2 Jul 202367 km
3 Jul 202330 km
4 Jul 202328 km
5 Jul 202331 km
6 Jul 202331 km
7 Jul 202330 km
8 Jul 202345 km
9 Jul 202338 km
10 Jul 202328 km
11 Jul 202330 km
12 Jul 202331 km
13 Jul 202328 km
14 Jul 20230 km
15 Jul 202340 km
16 Jul 202365 km
17 Jul 20230 km
18 Jul 202332 km
19 Jul 202327 km
20 Jul 202330 km
21 Jul 202331 km
22 Jul 202358 km
23 Jul 202343 km
24 Jul 20230 km
25 Jul 202328 km
26 Jul 202326 km
27 Jul 202326 km
28 Jul 202328 km
29 Jul 202348 km
30 Jul 202363 km
31 Jul 202328 km
1 Aug 202326 km
2 Aug 202325 km
3 Aug 202325 km
4 Aug 20230 km
5 Aug 202358 km
6 Aug 20230 km
7 Aug 202326 km
8 Aug 202326 km
9 Aug 20230 km
10 Aug 202329 km
11 Aug 202329 km
12 Aug 202379 km
13 Aug 20230 km
14 Aug 202330 km
15 Aug 202328 km
16 Aug 20230 km
17 Aug 202329 km
18 Aug 202324 km
19 Aug 20230 km
20 Aug 202376 km
21 Aug 202328 km
22 Aug 202328 km
23 Aug 202327 km
24 Aug 202328 km
25 Aug 202325 km
26 Aug 202347 km
27 Aug 202366 km
28 Aug 202323 km
29 Aug 20230 km
30 Aug 202322 km
31 Aug 202323 km
1 Sep 202323 km
2 Sep 202341 km
3 Sep 202357 km
4 Sep 202323 km
5 Sep 202327 km
6 Sep 202326 km
7 Sep 202325 km
8 Sep 202322 km
9 Sep 202353 km
10 Sep 202339 km
11 Sep 202323 km
12 Sep 202322 km
13 Sep 202323 km
14 Sep 202323 km
15 Sep 202322 km
16 Sep 20230 km
17 Sep 202369 km
18 Sep 202321 km
19 Sep 202325 km
20 Sep 202321 km
21 Sep 20230 km
22 Sep 202323 km
23 Sep 202353 km
24 Sep 20230 km
25 Sep 202319 km
26 Sep 20230 km
27 Sep 20230 km
28 Sep 20230 km
29 Sep 202318 km
30 Sep 202361 km
1 Oct 202344 km
2 Oct 202320 km
3 Oct 20230 km
4 Oct 20230 km
5 Oct 20230 km
6 Oct 202321 km
7 Oct 202356 km
8 Oct 202357 km
9 Oct 202317 km
10 Oct 20230 km
11 Oct 20230 km
12 Oct 20230 km
13 Oct 202321 km
14 Oct 20230 km
15 Oct 202349 km
16 Oct 202320 km
17 Oct 202316 km
18 Oct 202317 km
19 Oct 202316 km
20 Oct 202317 km
21 Oct 202341 km
22 Oct 20230 km
23 Oct 202314 km
24 Oct 202314 km
25 Oct 202314 km
26 Oct 202315 km
27 Oct 20230 km
28 Oct 202348 km
29 Oct 202346 km
30 Oct 20230 km
31 Oct 202316 km
1 Nov 20230 km
2 Nov 202318 km
3 Nov 20230 km
4 Nov 20230 km
5 Nov 202339 km
6 Nov 20230 km
7 Nov 20230 km
8 Nov 202313 km
9 Nov 202314 km
10 Nov 20230 km
11 Nov 20230 km
12 Nov 20230 km
13 Nov 202314 km
14 Nov 20230 km
15 Nov 202317 km
16 Nov 20230 km
17 Nov 202312 km
18 Nov 20230 km
19 Nov 202336 km
20 Nov 20230 km
21 Nov 20230 km
22 Nov 202311 km
23 Nov 202314 km
24 Nov 202312 km
25 Nov 20230 km
26 Nov 202337 km
27 Nov 202315 km
28 Nov 202314 km
29 Nov 202310 km
30 Nov 202312 km
1 Dec 20230 km
2 Dec 202337 km
3 Dec 202337 km
4 Dec 20230 km
5 Dec 202314 km
6 Dec 202313 km
7 Dec 20230 km
8 Dec 20230 km
9 Dec 20230 km
10 Dec 20230 km
11 Dec 20230 km
12 Dec 202313 km
13 Dec 20230 km
14 Dec 20230 km
15 Dec 20230 km
16 Dec 202335 km
17 Dec 20230 km
18 Dec 20230 km
19 Dec 202310 km
20 Dec 20230 km
21 Dec 20230 km
22 Dec 20239 km
23 Dec 202335 km
24 Dec 20230 km
25 Dec 20230 km
26 Dec 20230 km
27 Dec 202314 km
28 Dec 20230 km
29 Dec 202313 km
30 Dec 202335 km
31 Dec 202335 km
1 Jan 202411 km
2 Jan 20240 km
3 Jan 20240 km
4 Jan 202414 km
5 Jan 20240 km
6 Jan 20240 km
7 Jan 20240 km
8 Jan 202413 km
9 Jan 20240 km
10 Jan 20240 km
11 Jan 202411 km
12 Jan 20240 km
13 Jan 20240 km
14 Jan 20240 km
15 Jan 20240 km
16 Jan 20240 km
17 Jan 202413 km
18 Jan 20240 km
19 Jan 202410 km
20 Jan 20240 km
21 Jan 202436 km
22 Jan 20240 km
23 Jan 20240 km
24 Jan 20240 km
25 Jan 20240 km
26 Jan 20240 km
27 Jan 20240 km
28 Jan 202438 km
29 Jan 202410 km
30 Jan 20240 km
31 Jan 20240 km
1 Feb 20240 km
2 Feb 202413 km
3 Feb 20240 km
4 Feb 20240 km
5 Feb 202410 km
6 Feb 202415 km
7 Feb 202415 km
8 Feb 202415 km
9 Feb 20240 km
10 Feb 202435 km
11 Feb 202441 km
12 Feb 202415 km
13 Feb 20240 km
14 Feb 202412 km
15 Feb 202414 km
16 Feb 202413 km
17 Feb 20240 km
18 Feb 20240 km
19 Feb 20240 km
20 Feb 202414 km
21 Feb 202413 km
22 Feb 20240 km
23 Feb 202417 km
24 Feb 20240 km
25 Feb 20240 km
26 Feb 202415 km
27 Feb 202417 km
28 Feb 202415 km
29 Feb 202415 km
1 Mar 20240 km
2 Mar 202439 km
3 Mar 20240 km
4 Mar 202418 km
5 Mar 20240 km
6 Mar 20240 km
7 Mar 202414 km
8 Mar 20240 km
9 Mar 20240 km
10 Mar 202449 km
11 Mar 20240 km
12 Mar 20240 km
13 Mar 202416 km
14 Mar 202418 km
15 Mar 202416 km
16 Mar 20240 km
17 Mar 20240 km
18 Mar 20240 km
19 Mar 20240 km
20 Mar 202419 km
21 Mar 202418 km
22 Mar 202419 km
23 Mar 202457 km
24 Mar 20240 km
25 Mar 202421 km
26 Mar 20240 km
27 Mar 202421 km
28 Mar 20240 km
29 Mar 202421 km
30 Mar 202454 km
31 Mar 202436 km
1 Apr 202418 km
2 Apr 202420 km
3 Apr 202418 km
4 Apr 20240 km
5 Apr 20240 km
6 Apr 202447 km
7 Apr 202457 km
8 Apr 20240 km
9 Apr 202419 km
10 Apr 20240 km
11 Apr 202422 km
12 Apr 20240 km
13 Apr 202458 km
14 Apr 20240 km
15 Apr 20240 km
16 Apr 20240 km
17 Apr 202420 km
18 Apr 202420 km
19 Apr 202426 km
20 Apr 202438 km
21 Apr 202454 km
22 Apr 20240 km
23 Apr 202422 km
24 Apr 202426 km
25 Apr 20240 km
26 Apr 202424 km
27 Apr 202444 km
28 Apr 202446 km
29 Apr 202426 km
30 Apr 202423 km
1 May 202423 km
2 May 202424 km
3 May 202427 km
4 May 202452 km
5 May 202454 km
6 May 202427 km
7 May 202428 km
8 May 20240 km
9 May 20240 km
10 May 202427 km
11 May 202479 km
12 May 202461 km
13 May 202425 km
14 May 202429 km
15 May 202425 km
16 May 202427 km
17 May 202429 km
18 May 202451 km
19 May 202446 km
20 May 202426 km
21 May 20240 km
22 May 202426 km
23 May 202426 km
24 May 202426 km
25 May 202441 km
26 May 202445 km
27 May 202425 km
28 May 202425 km
29 May 202430 km
30 May 202430 km
31 May 20240 km
1 Jun 202449 km
2 Jun 20240 km
3 Jun 20240 km
4 Jun 202427 km
5 Jun 202425 km
6 Jun 202427 km
7 Jun 202425 km
8 Jun 202468 km
9 Jun 202467 km
10 Jun 20240 km
11 Jun 202429 km
12 Jun 202428 km
13 Jun 202429 km
14 Jun 202430 km
15 Jun 20240 km
16 Jun 202486 km
17 Jun 202426 km
18 Jun 202429 km
19 Jun 202431 km
20 Jun 20240 km
21 Jun 20240 km
22 Jun 20240 km
23 Jun 20240 km
24 Jun 202427 km
25 Jun 202426 km
26 Jun 20240 km
27 Jun 202428 km
28 Jun 202430 km
29 Jun 202483 km
30 Jun 202462 km
1 Jul 202431 km
2 Jul 202429 km
3 Jul 202426 km
4 Jul 202430 km
5 Jul 202428 km
6 Jul 202478 km
7 Jul 202477 km
8 Jul 202428 km
9 Jul 20240 km
10 Jul 202431 km
11 Jul 202427 km
12 Jul 202428 km
13 Jul 202472 km
14 Jul 202442 km
15 Jul 202428 km
16 Jul 202428 km
17 Jul 202431 km
18 Jul 20240 km
19 Jul 202430 km
20 Jul 202464 km
21 Jul 202478 km
22 Jul 202427 km
23 Jul 202428 km
24 Jul 20240 km
25 Jul 202429 km
26 Jul 202430 km
27 Jul 202448 km
28 Jul 20240 km
29 Jul 202427 km
30 Jul 20240 km
31 Jul 202430 km
1 Aug 202430 km
2 Aug 202426 km
3 Aug 202479 km
4 Aug 20240 km
5 Aug 202427 km
6 Aug 202429 km
7 Aug 20240 km
8 Aug 202425 km
9 Aug 202430 km
10 Aug 202467 km
11 Aug 202449 km
12 Aug 202427 km
13 Aug 202424 km
14 Aug 202428 km
15 Aug 202426 km
16 Aug 202428 km
17 Aug 202450 km
18 Aug 202465 km
19 Aug 202427 km
20 Aug 202429 km
21 Aug 20240 km
22 Aug 202426 km
23 Aug 20240 km
24 Aug 20240 km
25 Aug 202470 km
26 Aug 20240 km
27 Aug 202424 km
28 Aug 202427 km
29 Aug 20240 km
30 Aug 202422 km
31 Aug 202442 km
1 Sep 202475 km
2 Sep 202425 km
3 Sep 202426 km
4 Sep 20240 km
5 Sep 202421 km
6 Sep 202425 km
7 Sep 202472 km
8 Sep 202449 km
9 Sep 202422 km
10 Sep 20240 km
11 Sep 20240 km
12 Sep 20240 km
13 Sep 202423 km
14 Sep 202453 km
15 Sep 202450 km
16 Sep 202420 km
17 Sep 20240 km
18 Sep 202422 km
19 Sep 20240 km
20 Sep 202420 km
21 Sep 202463 km
22 Sep 202460 km
23 Sep 202420 km
24 Sep 202420 km
25 Sep 202423 km
26 Sep 202423 km
27 Sep 202423 km
28 Sep 202440 km
29 Sep 202456 km
30 Sep 202421 km
1 Oct 20240 km
2 Oct 202419 km
3 Oct 20240 km
4 Oct 20240 km
5 Oct 20240 km
6 Oct 202445 km
7 Oct 202417 km
8 Oct 20240 km
9 Oct 20240 km
10 Oct 202416 km
11 Oct 202421 km
12 Oct 20240 km
13 Oct 202451 km
14 Oct 202416 km
15 Oct 202415 km
16 Oct 20240 km
17 Oct 20240 km
18 Oct 20240 km
19 Oct 202448 km
20 Oct 202443 km
21 Oct 202417 km
22 Oct 202414 km
23 Oct 202417 km
24 Oct 20240 km
25 Oct 202418 km
26 Oct 202443 km
27 Oct 202441 km
28 Oct 202418 km
29 Oct 20240 km
30 Oct 20240 km
31 Oct 20240 km
1 Nov 202415 km
2 Nov 202442 km
3 Nov 20240 km
4 Nov 20240 km
5 Nov 202416 km
6 Nov 20240 km
7 Nov 202417 km
8 Nov 20240 km
9 Nov 20240 km
10 Nov 202443 km
11 Nov 202411 km
12 Nov 20240 km
13 Nov 20240 km
14 Nov 20240 km
15 Nov 202413 km
16 Nov 20240 km
17 Nov 20240 km
18 Nov 202411 km
19 Nov 202411 km
20 Nov 202414 km
21 Nov 20240 km
22 Nov 20240 km
23 Nov 202436 km
24 Nov 202435 km
25 Nov 20240 km
26 Nov 202413 km
27 Nov 20240 km
28 Nov 20240 km
29 Nov 20240 km
30 Nov 20240 km
1 Dec 20240 km
2 Dec 202412 km
3 Dec 20240 km
4 Dec 20240 km
5 Dec 202413 km
6 Dec 20240 km
7 Dec 202435 km
8 Dec 20240 km
9 Dec 20240 km
10 Dec 202411 km
11 Dec 202410 km
12 Dec 20240 km
13 Dec 20240 km
14 Dec 20240 km
15 Dec 202436 km
16 Dec 202410 km
17 Dec 20240 km
18 Dec 20240 km
19 Dec 20249 km
20 Dec 20240 km
21 Dec 20240 km
22 Dec 20240 km
23 Dec 20240 km
24 Dec 20249 km
25 Dec 202410 km
26 Dec 202412 km
27 Dec 20249 km
28 Dec 202435 km
29 Dec 202435 km
30 Dec 20240 km
31 Dec 202413 km
1 Jan 202514 km
2 Jan 20258 km
3 Jan 202511 km
4 Jan 202535 km
5 Jan 20250 km
6 Jan 20250 km
7 Jan 20250 km
8 Jan 20250 km
9 Jan 20250 km
10 Jan 20250 km
11 Jan 20250 km
12 Jan 20250 km
13 Jan 20250 km
14 Jan 202513 km
15 Jan 20259 km
16 Jan 20250 km
17 Jan 20250 km
18 Jan 20250 km
19 Jan 202536 km
20 Jan 202513 km
21 Jan 20250 km
22 Jan 20250 km
23 Jan 202512 km
24 Jan 20250 km
25 Jan 20250 km
26 Jan 20250 km
27 Jan 20250 km
28 Jan 20250 km
29 Jan 20250 km
30 Jan 202513 km
31 Jan 202511 km
1 Feb 202539 km
2 Feb 20250 km
3 Feb 202515 km
4 Feb 202515 km
5 Feb 202512 km
6 Feb 20250 km
7 Feb 20250 km
8 Feb 202540 km
9 Feb 202539 km
10 Feb 202512 km
11 Feb 20250 km
12 Feb 202511 km
13 Feb 202514 km
14 Feb 20250 km
15 Feb 20250 km
16 Feb 202539 km
17 Feb 202513 km
18 Feb 20250 km
19 Feb 20250 km
20 Feb 20250 km
21 Feb 202516 km
22 Feb 20250 km
23 Feb 20250 km
24 Feb 202513 km
25 Feb 20250 km
26 Feb 202514 km
27 Feb 20250 km
28 Feb 202517 km
1 Mar 20250 km
2 Mar 202539 km
3 Mar 20250 km
4 Mar 202514 km
5 Mar 202514 km
6 Mar 20250 km
7 Mar 20250 km
8 Mar 202548 km
9 Mar 202540 km
10 Mar 20250 km
11 Mar 20250 km
12 Mar 20250 km
13 Mar 202519 km
14 Mar 202516 km
15 Mar 20250 km
16 Mar 202538 km
17 Mar 20250 km
18 Mar 20250 km
19 Mar 202517 km
20 Mar 202517 km
21 Mar 20250 km
22 Mar 202538 km
23 Mar 202554 km
24 Mar 20250 km
25 Mar 202516 km
26 Mar 202516 km
27 Mar 20250 km
28 Mar 20250 km
29 Mar 20250 km
30 Mar 20250 km
31 Mar 202520 km
1 Apr 202523 km
2 Apr 202521 km
3 Apr 202520 km
4 Apr 202517 km
5 Apr 20250 km
6 Apr 202555 km
7 Apr 202521 km
8 Apr 202523 km
9 Apr 20250 km
10 Apr 202521 km
11 Apr 20250 km
12 Apr 202554 km
13 Apr 202549 km
14 Apr 202520 km
15 Apr 202520 km
16 Apr 20250 km
17 Apr 202525 km
18 Apr 202521 km
19 Apr 202570 km
20 Apr 202558 km
21 Apr 202522 km
22 Apr 202525 km
23 Apr 20250 km
24 Apr 202523 km
25 Apr 20250 km
26 Apr 202552 km
27 Apr 202566 km
28 Apr 202526 km
29 Apr 202527 km
30 Apr 202525 km
1 May 20250 km
2 May 202524 km
3 May 202574 km
4 May 20250 km
5 May 202526 km
6 May 202528 km
7 May 202528 km
8 May 202527 km
9 May 202527 km
10 May 202566 km
11 May 202559 km
12 May 202527 km
13 May 202526 km
14 May 202529 km
15 May 20250 km
16 May 202526 km
17 May 202549 km
18 May 20250 km
19 May 202524 km
20 May 202527 km
21 May 202529 km
22 May 202526 km
23 May 202527 km
24 May 202535 km
25 May 202583 km
26 May 20250 km
27 May 202525 km
28 May 202528 km
29 May 20250 km
30 May 202525 km
31 May 202584 km
1 Jun 20250 km
2 Jun 202526 km
3 Jun 20250 km
4 Jun 20250 km
5 Jun 202526 km
6 Jun 202528 km
7 Jun 202559 km
8 Jun 202568 km
9 Jun 202527 km
10 Jun 202527 km
11 Jun 202531 km
12 Jun 20250 km
13 Jun 202527 km
14 Jun 202583 km
15 Jun 20250 km
16 Jun 202526 km
17 Jun 202528 km
18 Jun 202531 km
19 Jun 202527 km
20 Jun 20250 km
21 Jun 202570 km
22 Jun 202552 km
23 Jun 202527 km
24 Jun 202529 km
25 Jun 202532 km
26 Jun 202531 km
27 Jun 202531 km
28 Jun 202559 km
29 Jun 202540 km
30 Jun 202530 km
1 Jul 202531 km
2 Jul 202527 km
3 Jul 20250 km
4 Jul 202531 km
5 Jul 202556 km
6 Jul 202545 km
7 Jul 20250 km
8 Jul 20250 km
9 Jul 20250 km
10 Jul 20250 km
11 Jul 202527 km
12 Jul 202549 km
13 Jul 202548 km
14 Jul 202529 km
15 Jul 202530 km
16 Jul 202532 km
17 Jul 202532 km
18 Jul 202529 km
19 Jul 202566 km
20 Jul 202573 km
21 Jul 202529 km
22 Jul 202527 km
23 Jul 202528 km
24 Jul 202527 km
25 Jul 202528 km
26 Jul 202557 km
27 Jul 202585 km
28 Jul 20250 km
29 Jul 202527 km
30 Jul 202529 km
31 Jul 202529 km
1 Aug 202531 km
2 Aug 20250 km
3 Aug 202584 km
4 Aug 202528 km
5 Aug 202526 km
6 Aug 202526 km
7 Aug 202528 km
8 Aug 20250 km
9 Aug 20250 km
10 Aug 202546 km
11 Aug 202526 km
12 Aug 202526 km
13 Aug 20250 km
14 Aug 202529 km
15 Aug 20250 km
16 Aug 202548 km
17 Aug 202571 km
18 Aug 202525 km
19 Aug 202523 km
20 Aug 20250 km
21 Aug 202526 km
22 Aug 202524 km
23 Aug 202558 km
24 Aug 20250 km
25 Aug 202527 km
26 Aug 20250 km
27 Aug 202525 km
28 Aug 202526 km
29 Aug 202525 km
30 Aug 20250 km
31 Aug 202574 km
1 Sep 202526 km
2 Sep 202525 km
3 Sep 202522 km
4 Sep 20250 km
5 Sep 202524 km
6 Sep 202567 km
7 Sep 202564 km
8 Sep 202521 km
9 Sep 202522 km
10 Sep 20250 km
11 Sep 202526 km
12 Sep 20250 km
13 Sep 202537 km
14 Sep 202550 km
15 Sep 202525 km
16 Sep 202523 km
17 Sep 20250 km
18 Sep 202525 km
19 Sep 202522 km
20 Sep 202536 km
21 Sep 202566 km
22 Sep 202520 km
23 Sep 202523 km
24 Sep 202519 km
25 Sep 202518 km
26 Sep 202522 km

Usage

use hydroxy_leptos::chart_frame::ChartFrame;
use hydroxy_leptos::spiral_chart::SpiralChart;
use leptos::prelude::*;

const MONTHS: [&str; 12] = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];

pub fn demo() -> AnyView {
    // Three years of daily cycling, one turn per year: long weekend rides in summer,
    // more rest days in winter. 2023 starts on a Sunday.
    let mut dates = Vec::new();
    for year in 2023..=2025 {
        let leap = year % 4 == 0;
        for (m, days) in
            [31, if leap { 29 } else { 28 }, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31].into_iter().enumerate()
        {
            dates.extend((1..=days).map(|d| format!("{d} {} {year}", MONTHS[m])));
        }
    }
    let mut next = noise(41);
    let distance: Vec<f64> = (0..dates.len())
        .map(|d| {
            #[allow(clippy::cast_precision_loss, reason = "day counts are small")]
            let summer = 0.5 - 0.5 * (d as f64 / 365.25 * std::f64::consts::TAU).cos();
            let weekend = matches!(d % 7, 0 | 6);
            if next() > 0.45 + 0.4 * summer {
                0.0
            } else if weekend {
                (35.0 + 55.0 * summer * next()).round()
            } else {
                (8.0 + 18.0 * summer + 6.0 * next()).round()
            }
        })
        .collect();
    let spokes: Vec<String> = MONTHS.map(String::from).to_vec();
    let turns: Vec<String> = ["2023", "2024", "2025"].map(String::from).to_vec();

    view! {
        <ChartFrame
            title="Daily cycling distance"
            description="Kilometres a day, one turn per year from the centre out. Summers bloom as darker arcs along the same months."
            export=true
        >
            <SpiralChart
                values=distance
                labels=dates
                period=365.25
                spokes
                turns
                label="Daily cycling distance in kilometres, 2023 to 2025"
                format=|v: f64| format!("{v:.0} km")
            />
        </ChartFrame>
    }
    .into_any()
}

/// A small deterministic random source (xorshift), so server and browser draw the same data.
#[allow(clippy::cast_precision_loss, reason = "a 53-bit fraction is exact")]
fn noise(seed: u64) -> impl FnMut() -> f64 {
    let mut state = seed;
    move || {
        state ^= state << 13;
        state ^= state >> 7;
        state ^= state << 17;
        (state >> 11) as f64 / (1u64 << 53) as f64
    }
}

Anatomy

Componentdata-partRenders
SpiralChartrootfigure with a screen-reader table of every value
segmentOne arc per value, shaded from the lowest to the highest
spokeA faint line through every turn at each dial name
spoke-labelDial names around the outside, such as months
turn-labelEach turn's name at 12 o'clock, such as the year
highlightThe arc under the pointer or keyboard focus
tooltipThe value's name and value
scaleThe colour ramp with its lowest and highest values

Keyboard

KeyDoes
ArrowLeft / ArrowRightPrevious or next value along the spiral
ArrowUp / ArrowDownOne turn out or in
Home / EndFirst or last value
EscapeHide the tooltip

Props

PropTypeNotes
valuesVec<f64>Required. Values in time order; NaN leaves a gap
labelsVec<String>Required. A name per value, such as its date
periodf64Required. Values per turn: 365.25 for daily values over years
spokesVec<String>Names spaced evenly around the dial from 12 o'clock
turnsVec<String>A name per turn, from the centre out
labelStringRequired. What the chart shows; the accessible name
sizeu16Diameter in px. Default 360
formatFn(f64) -> StringFormats the tooltip, scale and table

Events

PropTypeNotes
on_hoverCallback<Option<Datum>>The mark under the pointer or keyboard focus changes, or is left. Fires only on a change
on_selectCallback<Datum>Click, tap or Enter on a mark
Actions
Button
Icon button
Toolbar
Theme menu
Display
Avatar
Badge
Card
Chip
Code block
Markdown
Doc card
Due pill
Kbd
Priority mark
Source chip
Space icon
Status diamond
Tag
Value diff
Carousel
Reveal
Media timeline
QR code
Transcript viewer
Audio waveform
Audio player
Forms
Calendar
Checkbox
Combobox
Date picker
Color picker
Cron builder
Theme editor
Mention input
Signature pad
Image cropper
Date field
Date range picker
Duration field
Quantity stepper
Filter chip
Input
Markdown editor
Radio group
Search field
Segmented control
Select
Slider
Range slider
Rating
Toggle button
File dropzone
Upload queue
Attachment
Switch
Tags input
Number field
Money field
Phone field
Time field
OTP input
Password field
Questionnaire
Availability picker
Voice input
Recording control
Inline edit
Async validated input
Shortcut recorder
Data
Spreadsheet grid
Week scheduler
Virtual list
Stat card
Step track
Kanban board
Sortable list
Filter builder
Data table
Grid
Access editor
File manager
Gantt chart
Log stream
Diff viewer
JSON inspector
Terminal
Node editor
Whiteboard
Navigation
Table of contents
Breadcrumb
Tabs
Wizard
Nav item
Nav section
Tree view
Pagination
Menubar
Navigation menu
Saved views
Layout
Master detail
App shell
Sidebar layout
Resizable panels
Dashboard layout
Dock layout
Feedback
Callout
Check list
Empty state
Progress bar
Toast
Approval card
Skeleton
Notification center
Bars
Bar chart
Diverging bar chart
Span chart
Pictogram chart
Stacked bar chart
Funnel chart
Bullet chart
Waffle chart
Marimekko chart
Dot plot chart
Error bar chart
Pareto chart
Waterfall chart
Lollipop chart
Grouped bar chart
Bar race chart
KPIs and frames
Chart frame
Metric card
Sparkline
Points
Scatter chart
Smith chart
Strip plot
Beeswarm chart
Parallel coordinates
Ternary chart
Bland-Altman chart
Quiver chart
Connected scatter chart
Grids and tables
Heatmap chart
Chart table
Cohort chart
Radial
Radial charts
Radar chart
Polar area chart
Stat ring
Clock chart
Spiral chart
Lines and areas
Bump chart
Slope chart
Line chart
Composed chart
Small multiples
Cycle plot chart
Horizon chart
Stacked area chart
Threshold chart
Split line chart
Linked charts
Confidence band chart
Forecast fan chart
Step chart
Range area chart
Distributions
Contour chart
Histogram
Box plot
Density chart
Ridgeline chart
Violin chart
Q-Q chart
Survival chart
ECDF chart
Raincloud plot
Forest plot
Maps
Geo map
Bubble map
Hexbin map
Cartogram
Flow map
Parts of a whole
Donut chart
Voronoi treemap
Nested donut chart
Treemap chart
Sunburst chart
Bubble pack chart
Icicle chart
Flame graph chart
Pie chart
Word cloud
Relationships
Sankey chart
Network chart
Chord chart
UpSet chart
Venn chart
Alluvial chart
Adjacency matrix chart
Dependency graph chart
Tree chart
Arc diagram
Hive plot
Edge bundling
Finance
Candlestick chart
OHLC chart
Depth chart
Renko chart
Time
Timeline chart
Calendar heatmap chart
Spectrogram chart
Marey chart
Overlays
Tour
Lightbox
Alert dialog
Command palette
Dialog
Menu
Popover
Tooltip
Sheet
Hover card
Context menu
Utilities
Pacer
Hotkeys
Disclosure
Accordion
Collapsible
Chat
Chat bubble
Voice session
Composer
Thread
Thread list
Assistant composer
Assistant MCP
Assistant modal
Assistant thread
Assistant thread list
Message scroller
Insight note
Emoji picker
Tool trace
Model picker
Citation popover
Activity
Activity feed
Comment thread
Timeline
Presence bar
Live cursors
Reaction bar
Guides
Getting started
All components
All charts