Navigation

v0.0.4
Data display

Heatmap

Many small numbers as a field of cells, each as dark as its value.

On this page

A heatmap shows many small numbers at once as a field of cells, each as dark as its value: activity by day, load by hour. Like the chart, it is a list the stylesheet draws: a cell carries its number as --value, and its tone is ink mixed into the surface behind it. The scale is one material at different depths, with no hue. A row of days that are states, up or down, is uptime.

Heatmap

<div class="card w(280)">  <div class="card-header">    <h3 class="card-title">Deployments</h3>    <p class="card-description">The last sixteen weeks</p>  </div>  <ol class="heatmap" style="--heatmap-max: 6" aria-label="Deployments per day, the last sixteen weeks">    <li class="heatmap-cell" style="--value: 5" title="Mon 24 Aug: 5 deployments">Mon 24 Aug: 5 deployments</li>    <li class="heatmap-cell" style="--value: 6" title="Tue 25 Aug: 6 deployments">Tue 25 Aug: 6 deployments</li>    <li class="heatmap-cell" style="--value: 6" title="Wed 26 Aug: 6 deployments">Wed 26 Aug: 6 deployments</li>    <li class="heatmap-cell" style="--value: 3" title="Thu 27 Aug: 3 deployments">Thu 27 Aug: 3 deployments</li>    <li class="heatmap-cell" style="--value: 2" title="Fri 28 Aug: 2 deployments">Fri 28 Aug: 2 deployments</li>    <li class="heatmap-cell" style="--value: 1" title="Sat 29 Aug: 1 deployment">Sat 29 Aug: 1 deployment</li>    <li class="heatmap-cell" style="--value: 0" title="Sun 30 Aug: 0 deployments">Sun 30 Aug: 0 deployments</li>    <li class="heatmap-cell" style="--value: 2" title="Mon 31 Aug: 2 deployments">Mon 31 Aug: 2 deployments</li>    <li class="heatmap-cell" style="--value: 6" title="Tue 1 Sep: 6 deployments">Tue 1 Sep: 6 deployments</li>    <li class="heatmap-cell" style="--value: 4" title="Wed 2 Sep: 4 deployments">Wed 2 Sep: 4 deployments</li>    <li class="heatmap-cell" style="--value: 2" title="Thu 3 Sep: 2 deployments">Thu 3 Sep: 2 deployments</li>    <li class="heatmap-cell" style="--value: 2" title="Fri 4 Sep: 2 deployments">Fri 4 Sep: 2 deployments</li>    <li class="heatmap-cell" style="--value: 0" title="Sat 5 Sep: 0 deployments">Sat 5 Sep: 0 deployments</li>    <li class="heatmap-cell" style="--value: 1" title="Sun 6 Sep: 1 deployment">Sun 6 Sep: 1 deployment</li>    <li class="heatmap-cell" style="--value: 5" title="Mon 7 Sep: 5 deployments">Mon 7 Sep: 5 deployments</li>    <li class="heatmap-cell" style="--value: 3" title="Tue 8 Sep: 3 deployments">Tue 8 Sep: 3 deployments</li>    <li class="heatmap-cell" style="--value: 2" title="Wed 9 Sep: 2 deployments">Wed 9 Sep: 2 deployments</li>    <li class="heatmap-cell" style="--value: 2" title="Thu 10 Sep: 2 deployments">Thu 10 Sep: 2 deployments</li>    <li class="heatmap-cell" style="--value: 1" title="Fri 11 Sep: 1 deployment">Fri 11 Sep: 1 deployment</li>    <li class="heatmap-cell" style="--value: 0" title="Sat 12 Sep: 0 deployments">Sat 12 Sep: 0 deployments</li>    <li class="heatmap-cell" style="--value: 0" title="Sun 13 Sep: 0 deployments">Sun 13 Sep: 0 deployments</li>    <li class="heatmap-cell" style="--value: 3" title="Mon 14 Sep: 3 deployments">Mon 14 Sep: 3 deployments</li>    <li class="heatmap-cell" style="--value: 2" title="Tue 15 Sep: 2 deployments">Tue 15 Sep: 2 deployments</li>    <li class="heatmap-cell" style="--value: 6" title="Wed 16 Sep: 6 deployments">Wed 16 Sep: 6 deployments</li>    <li class="heatmap-cell" style="--value: 4" title="Thu 17 Sep: 4 deployments">Thu 17 Sep: 4 deployments</li>    <li class="heatmap-cell" style="--value: 5" title="Fri 18 Sep: 5 deployments">Fri 18 Sep: 5 deployments</li>    <li class="heatmap-cell" style="--value: 0" title="Sat 19 Sep: 0 deployments">Sat 19 Sep: 0 deployments</li>    <li class="heatmap-cell" style="--value: 0" title="Sun 20 Sep: 0 deployments">Sun 20 Sep: 0 deployments</li>    <li class="heatmap-cell" style="--value: 3" title="Mon 21 Sep: 3 deployments">Mon 21 Sep: 3 deployments</li>    <li class="heatmap-cell" style="--value: 6" title="Tue 22 Sep: 6 deployments">Tue 22 Sep: 6 deployments</li>    <li class="heatmap-cell" style="--value: 2" title="Wed 23 Sep: 2 deployments">Wed 23 Sep: 2 deployments</li>    <li class="heatmap-cell" style="--value: 2" title="Thu 24 Sep: 2 deployments">Thu 24 Sep: 2 deployments</li>    <li class="heatmap-cell" style="--value: 5" title="Fri 25 Sep: 5 deployments">Fri 25 Sep: 5 deployments</li>    <li class="heatmap-cell" style="--value: 0" title="Sat 26 Sep: 0 deployments">Sat 26 Sep: 0 deployments</li>    <li class="heatmap-cell" style="--value: 1" title="Sun 27 Sep: 1 deployment">Sun 27 Sep: 1 deployment</li>    <li class="heatmap-cell" style="--value: 2" title="Mon 28 Sep: 2 deployments">Mon 28 Sep: 2 deployments</li>    <li class="heatmap-cell" style="--value: 4" title="Tue 29 Sep: 4 deployments">Tue 29 Sep: 4 deployments</li>    <li class="heatmap-cell" style="--value: 5" title="Wed 30 Sep: 5 deployments">Wed 30 Sep: 5 deployments</li>    <li class="heatmap-cell" style="--value: 3" title="Thu 1 Oct: 3 deployments">Thu 1 Oct: 3 deployments</li>    <li class="heatmap-cell" style="--value: 3" title="Fri 2 Oct: 3 deployments">Fri 2 Oct: 3 deployments</li>    <li class="heatmap-cell" style="--value: 0" title="Sat 3 Oct: 0 deployments">Sat 3 Oct: 0 deployments</li>    <li class="heatmap-cell" style="--value: 0" title="Sun 4 Oct: 0 deployments">Sun 4 Oct: 0 deployments</li>    <li class="heatmap-cell" style="--value: 2" title="Mon 5 Oct: 2 deployments">Mon 5 Oct: 2 deployments</li>    <li class="heatmap-cell" style="--value: 5" title="Tue 6 Oct: 5 deployments">Tue 6 Oct: 5 deployments</li>    <li class="heatmap-cell" style="--value: 3" title="Wed 7 Oct: 3 deployments">Wed 7 Oct: 3 deployments</li>    <li class="heatmap-cell" style="--value: 3" title="Thu 8 Oct: 3 deployments">Thu 8 Oct: 3 deployments</li>    <li class="heatmap-cell" style="--value: 4" title="Fri 9 Oct: 4 deployments">Fri 9 Oct: 4 deployments</li>    <li class="heatmap-cell" style="--value: 0" title="Sat 10 Oct: 0 deployments">Sat 10 Oct: 0 deployments</li>    <li class="heatmap-cell" style="--value: 0" title="Sun 11 Oct: 0 deployments">Sun 11 Oct: 0 deployments</li>    <li class="heatmap-cell" style="--value: 1" title="Mon 12 Oct: 1 deployment">Mon 12 Oct: 1 deployment</li>    <li class="heatmap-cell" style="--value: 4" title="Tue 13 Oct: 4 deployments">Tue 13 Oct: 4 deployments</li>    <li class="heatmap-cell" style="--value: 4" title="Wed 14 Oct: 4 deployments">Wed 14 Oct: 4 deployments</li>    <li class="heatmap-cell" style="--value: 1" title="Thu 15 Oct: 1 deployment">Thu 15 Oct: 1 deployment</li>    <li class="heatmap-cell" style="--value: 5" title="Fri 16 Oct: 5 deployments">Fri 16 Oct: 5 deployments</li>    <li class="heatmap-cell" style="--value: 1" title="Sat 17 Oct: 1 deployment">Sat 17 Oct: 1 deployment</li>    <li class="heatmap-cell" style="--value: 1" title="Sun 18 Oct: 1 deployment">Sun 18 Oct: 1 deployment</li>    <li class="heatmap-cell" style="--value: 4" title="Mon 19 Oct: 4 deployments">Mon 19 Oct: 4 deployments</li>    <li class="heatmap-cell" style="--value: 3" title="Tue 20 Oct: 3 deployments">Tue 20 Oct: 3 deployments</li>    <li class="heatmap-cell" style="--value: 4" title="Wed 21 Oct: 4 deployments">Wed 21 Oct: 4 deployments</li>    <li class="heatmap-cell" style="--value: 3" title="Thu 22 Oct: 3 deployments">Thu 22 Oct: 3 deployments</li>    <li class="heatmap-cell" style="--value: 4" title="Fri 23 Oct: 4 deployments">Fri 23 Oct: 4 deployments</li>    <li class="heatmap-cell" style="--value: 0" title="Sat 24 Oct: 0 deployments">Sat 24 Oct: 0 deployments</li>    <li class="heatmap-cell" style="--value: 0" title="Sun 25 Oct: 0 deployments">Sun 25 Oct: 0 deployments</li>    <li class="heatmap-cell" style="--value: 4" title="Mon 26 Oct: 4 deployments">Mon 26 Oct: 4 deployments</li>    <li class="heatmap-cell" style="--value: 2" title="Tue 27 Oct: 2 deployments">Tue 27 Oct: 2 deployments</li>    <li class="heatmap-cell" style="--value: 5" title="Wed 28 Oct: 5 deployments">Wed 28 Oct: 5 deployments</li>    <li class="heatmap-cell" style="--value: 2" title="Thu 29 Oct: 2 deployments">Thu 29 Oct: 2 deployments</li>    <li class="heatmap-cell" style="--value: 2" title="Fri 30 Oct: 2 deployments">Fri 30 Oct: 2 deployments</li>    <li class="heatmap-cell" style="--value: 0" title="Sat 31 Oct: 0 deployments">Sat 31 Oct: 0 deployments</li>    <li class="heatmap-cell" style="--value: 0" title="Sun 1 Nov: 0 deployments">Sun 1 Nov: 0 deployments</li>    <li class="heatmap-cell" style="--value: 1" title="Mon 2 Nov: 1 deployment">Mon 2 Nov: 1 deployment</li>    <li class="heatmap-cell" style="--value: 2" title="Tue 3 Nov: 2 deployments">Tue 3 Nov: 2 deployments</li>    <li class="heatmap-cell" style="--value: 6" title="Wed 4 Nov: 6 deployments">Wed 4 Nov: 6 deployments</li>    <li class="heatmap-cell" style="--value: 5" title="Thu 5 Nov: 5 deployments">Thu 5 Nov: 5 deployments</li>    <li class="heatmap-cell" style="--value: 2" title="Fri 6 Nov: 2 deployments">Fri 6 Nov: 2 deployments</li>    <li class="heatmap-cell" style="--value: 0" title="Sat 7 Nov: 0 deployments">Sat 7 Nov: 0 deployments</li>    <li class="heatmap-cell" style="--value: 1" title="Sun 8 Nov: 1 deployment">Sun 8 Nov: 1 deployment</li>    <li class="heatmap-cell" style="--value: 3" title="Mon 9 Nov: 3 deployments">Mon 9 Nov: 3 deployments</li>    <li class="heatmap-cell" style="--value: 3" title="Tue 10 Nov: 3 deployments">Tue 10 Nov: 3 deployments</li>    <li class="heatmap-cell" style="--value: 5" title="Wed 11 Nov: 5 deployments">Wed 11 Nov: 5 deployments</li>    <li class="heatmap-cell" style="--value: 4" title="Thu 12 Nov: 4 deployments">Thu 12 Nov: 4 deployments</li>    <li class="heatmap-cell" style="--value: 2" title="Fri 13 Nov: 2 deployments">Fri 13 Nov: 2 deployments</li>    <li class="heatmap-cell" style="--value: 1" title="Sat 14 Nov: 1 deployment">Sat 14 Nov: 1 deployment</li>    <li class="heatmap-cell" style="--value: 1" title="Sun 15 Nov: 1 deployment">Sun 15 Nov: 1 deployment</li>    <li class="heatmap-cell" style="--value: 3" title="Mon 16 Nov: 3 deployments">Mon 16 Nov: 3 deployments</li>    <li class="heatmap-cell" style="--value: 2" title="Tue 17 Nov: 2 deployments">Tue 17 Nov: 2 deployments</li>    <li class="heatmap-cell" style="--value: 4" title="Wed 18 Nov: 4 deployments">Wed 18 Nov: 4 deployments</li>    <li class="heatmap-cell" style="--value: 3" title="Thu 19 Nov: 3 deployments">Thu 19 Nov: 3 deployments</li>    <li class="heatmap-cell" style="--value: 1" title="Fri 20 Nov: 1 deployment">Fri 20 Nov: 1 deployment</li>    <li class="heatmap-cell" style="--value: 0" title="Sat 21 Nov: 0 deployments">Sat 21 Nov: 0 deployments</li>    <li class="heatmap-cell" style="--value: 0" title="Sun 22 Nov: 0 deployments">Sun 22 Nov: 0 deployments</li>    <li class="heatmap-cell" style="--value: 4" title="Mon 23 Nov: 4 deployments">Mon 23 Nov: 4 deployments</li>    <li class="heatmap-cell" style="--value: 3" title="Tue 24 Nov: 3 deployments">Tue 24 Nov: 3 deployments</li>    <li class="heatmap-cell" style="--value: 2" title="Wed 25 Nov: 2 deployments">Wed 25 Nov: 2 deployments</li>    <li class="heatmap-cell" style="--value: 2" title="Thu 26 Nov: 2 deployments">Thu 26 Nov: 2 deployments</li>    <li class="heatmap-cell" style="--value: 3" title="Fri 27 Nov: 3 deployments">Fri 27 Nov: 3 deployments</li>    <li class="heatmap-cell" style="--value: 1" title="Sat 28 Nov: 1 deployment">Sat 28 Nov: 1 deployment</li>    <li class="heatmap-cell" style="--value: 0" title="Sun 29 Nov: 0 deployments">Sun 29 Nov: 0 deployments</li>    <li class="heatmap-cell" style="--value: 1" title="Mon 30 Nov: 1 deployment">Mon 30 Nov: 1 deployment</li>    <li class="heatmap-cell" style="--value: 5" title="Tue 1 Dec: 5 deployments">Tue 1 Dec: 5 deployments</li>    <li class="heatmap-cell" style="--value: 4" title="Wed 2 Dec: 4 deployments">Wed 2 Dec: 4 deployments</li>    <li class="heatmap-cell" style="--value: 4" title="Thu 3 Dec: 4 deployments">Thu 3 Dec: 4 deployments</li>    <li class="heatmap-cell" style="--value: 2" title="Fri 4 Dec: 2 deployments">Fri 4 Dec: 2 deployments</li>    <li class="heatmap-cell" style="--value: 0" title="Sat 5 Dec: 0 deployments">Sat 5 Dec: 0 deployments</li>    <li class="heatmap-cell" style="--value: 0" title="Sun 6 Dec: 0 deployments">Sun 6 Dec: 0 deployments</li>    <li class="heatmap-cell" style="--value: 3" title="Mon 7 Dec: 3 deployments">Mon 7 Dec: 3 deployments</li>    <li class="heatmap-cell" style="--value: 4" title="Tue 8 Dec: 4 deployments">Tue 8 Dec: 4 deployments</li>    <li class="heatmap-cell" style="--value: 2" title="Wed 9 Dec: 2 deployments">Wed 9 Dec: 2 deployments</li>    <li class="heatmap-cell" style="--value: 4" title="Thu 10 Dec: 4 deployments">Thu 10 Dec: 4 deployments</li>    <li class="heatmap-cell" style="--value: 4" title="Fri 11 Dec: 4 deployments">Fri 11 Dec: 4 deployments</li>    <li class="heatmap-cell" style="--value: 1" title="Sat 12 Dec: 1 deployment">Sat 12 Dec: 1 deployment</li>    <li class="heatmap-cell" style="--value: 0" title="Sun 13 Dec: 0 deployments">Sun 13 Dec: 0 deployments</li>  </ol>  <div class="flex items-center justify-end gap-xs text-xs fg-text-muted">Fewer    <ol class="heatmap" style="--heatmap-rows: 1; --heatmap-max: 6" aria-hidden="true">      <li class="heatmap-cell" style="--value: 0">0</li>      <li class="heatmap-cell" style="--value: 1">1</li>      <li class="heatmap-cell" style="--value: 2">2</li>      <li class="heatmap-cell" style="--value: 4">4</li>      <li class="heatmap-cell" style="--value: 6">6</li>    </ol>More</div></div>
Rest the pointer on a cell for its day and its count.

#How a cell gets its tone

Each heatmap-cell sets --value in its style; the heatmap sets the top of the scale with --heatmap-max. A cell's tone is its share of the maximum: full ink at the maximum and above, and a 7% tint for nothing, so an empty day still has its place in the field.

The cell's own text is its value in words: "Mon 2 Nov: 4 deployments". The text is not drawn; a screen reader reads it, and the same words in title are the tooltip under the pointer. The tone is a drawing of that sentence, never the only place the number lives.

#Rows and columns

Cells fill a column from the top and then start the next, the way the weeks of a year are laid out: --heatmap-rows is the length of a column, seven by default. Start the list on the first day of a week, or pad the first column with cells of no value. The heatmap is as wide as its columns; give the card or the cell around it a width.

heatmap-lg makes cells 20px, for a short period where each cell matters more.

Hours of a working week

<div class="card w(280)">  <div class="card-header">    <h3 class="card-title">Load by hour</h3>    <p class="card-description">A row for each day, Monday to Friday; a column for each hour from 8:00</p>  </div>  <ol class="heatmap heatmap-lg" style="--heatmap-rows: 5; --heatmap-max: 100" aria-label="Load by hour, Monday to Friday">    <li class="heatmap-cell" style="--value: 11" title="Mon 08:00: 11% load">Mon 08:00: 11% load</li>    <li class="heatmap-cell" style="--value: 17" title="Tue 08:00: 17% load">Tue 08:00: 17% load</li>    <li class="heatmap-cell" style="--value: 28" title="Wed 08:00: 28% load">Wed 08:00: 28% load</li>    <li class="heatmap-cell" style="--value: 0" title="Thu 08:00: 0% load">Thu 08:00: 0% load</li>    <li class="heatmap-cell" style="--value: 24" title="Fri 08:00: 24% load">Fri 08:00: 24% load</li>    <li class="heatmap-cell" style="--value: 24" title="Mon 09:00: 24% load">Mon 09:00: 24% load</li>    <li class="heatmap-cell" style="--value: 12" title="Tue 09:00: 12% load">Tue 09:00: 12% load</li>    <li class="heatmap-cell" style="--value: 19" title="Wed 09:00: 19% load">Wed 09:00: 19% load</li>    <li class="heatmap-cell" style="--value: 16" title="Thu 09:00: 16% load">Thu 09:00: 16% load</li>    <li class="heatmap-cell" style="--value: 32" title="Fri 09:00: 32% load">Fri 09:00: 32% load</li>    <li class="heatmap-cell" style="--value: 52" title="Mon 10:00: 52% load">Mon 10:00: 52% load</li>    <li class="heatmap-cell" style="--value: 37" title="Tue 10:00: 37% load">Tue 10:00: 37% load</li>    <li class="heatmap-cell" style="--value: 46" title="Wed 10:00: 46% load">Wed 10:00: 46% load</li>    <li class="heatmap-cell" style="--value: 56" title="Thu 10:00: 56% load">Thu 10:00: 56% load</li>    <li class="heatmap-cell" style="--value: 28" title="Fri 10:00: 28% load">Fri 10:00: 28% load</li>    <li class="heatmap-cell" style="--value: 71" title="Mon 11:00: 71% load">Mon 11:00: 71% load</li>    <li class="heatmap-cell" style="--value: 50" title="Tue 11:00: 50% load">Tue 11:00: 50% load</li>    <li class="heatmap-cell" style="--value: 35" title="Wed 11:00: 35% load">Wed 11:00: 35% load</li>    <li class="heatmap-cell" style="--value: 48" title="Thu 11:00: 48% load">Thu 11:00: 48% load</li>    <li class="heatmap-cell" style="--value: 61" title="Fri 11:00: 61% load">Fri 11:00: 61% load</li>    <li class="heatmap-cell" style="--value: 66" title="Mon 12:00: 66% load">Mon 12:00: 66% load</li>    <li class="heatmap-cell" style="--value: 60" title="Tue 12:00: 60% load">Tue 12:00: 60% load</li>    <li class="heatmap-cell" style="--value: 73" title="Wed 12:00: 73% load">Wed 12:00: 73% load</li>    <li class="heatmap-cell" style="--value: 59" title="Thu 12:00: 59% load">Thu 12:00: 59% load</li>    <li class="heatmap-cell" style="--value: 53" title="Fri 12:00: 53% load">Fri 12:00: 53% load</li>    <li class="heatmap-cell" style="--value: 70" title="Mon 13:00: 70% load">Mon 13:00: 70% load</li>    <li class="heatmap-cell" style="--value: 90" title="Tue 13:00: 90% load">Tue 13:00: 90% load</li>    <li class="heatmap-cell" style="--value: 70" title="Wed 13:00: 70% load">Wed 13:00: 70% load</li>    <li class="heatmap-cell" style="--value: 70" title="Thu 13:00: 70% load">Thu 13:00: 70% load</li>    <li class="heatmap-cell" style="--value: 62" title="Fri 13:00: 62% load">Fri 13:00: 62% load</li>    <li class="heatmap-cell" style="--value: 49" title="Mon 14:00: 49% load">Mon 14:00: 49% load</li>    <li class="heatmap-cell" style="--value: 62" title="Tue 14:00: 62% load">Tue 14:00: 62% load</li>    <li class="heatmap-cell" style="--value: 62" title="Wed 14:00: 62% load">Wed 14:00: 62% load</li>    <li class="heatmap-cell" style="--value: 59" title="Thu 14:00: 59% load">Thu 14:00: 59% load</li>    <li class="heatmap-cell" style="--value: 59" title="Fri 14:00: 59% load">Fri 14:00: 59% load</li>    <li class="heatmap-cell" style="--value: 53" title="Mon 15:00: 53% load">Mon 15:00: 53% load</li>    <li class="heatmap-cell" style="--value: 55" title="Tue 15:00: 55% load">Tue 15:00: 55% load</li>    <li class="heatmap-cell" style="--value: 47" title="Wed 15:00: 47% load">Wed 15:00: 47% load</li>    <li class="heatmap-cell" style="--value: 69" title="Thu 15:00: 69% load">Thu 15:00: 69% load</li>    <li class="heatmap-cell" style="--value: 48" title="Fri 15:00: 48% load">Fri 15:00: 48% load</li>    <li class="heatmap-cell" style="--value: 33" title="Mon 16:00: 33% load">Mon 16:00: 33% load</li>    <li class="heatmap-cell" style="--value: 34" title="Tue 16:00: 34% load">Tue 16:00: 34% load</li>    <li class="heatmap-cell" style="--value: 46" title="Wed 16:00: 46% load">Wed 16:00: 46% load</li>    <li class="heatmap-cell" style="--value: 41" title="Thu 16:00: 41% load">Thu 16:00: 41% load</li>    <li class="heatmap-cell" style="--value: 23" title="Fri 16:00: 23% load">Fri 16:00: 23% load</li>    <li class="heatmap-cell" style="--value: 32" title="Mon 17:00: 32% load">Mon 17:00: 32% load</li>    <li class="heatmap-cell" style="--value: 35" title="Tue 17:00: 35% load">Tue 17:00: 35% load</li>    <li class="heatmap-cell" style="--value: 19" title="Wed 17:00: 19% load">Wed 17:00: 19% load</li>    <li class="heatmap-cell" style="--value: 18" title="Thu 17:00: 18% load">Thu 17:00: 18% load</li>    <li class="heatmap-cell" style="--value: 25" title="Fri 17:00: 25% load">Fri 17:00: 25% load</li>  </ol></div>

#A legend

A legend is a second heatmap of one row with a few values of the same scale, between the words for its ends. It repeats what the cells already say, so hide it from assistive technology with aria-hidden.

#Accessibility

  • Label the list with what is measured and over what period.
  • Write each cell's text as a full phrase: the date or the hour, the number and its unit. A bare number means nothing when read on its own.
  • A reader who cannot see the tones gets a long list. When the period is long, offer the same numbers as a table or a summary beside the heatmap.
  • Tone is the only visual channel here, so do not ask the heatmap to carry a precise comparison. Use a chart when two values must be told apart.
  • In forced colors the cells keep their tones, drawn between the system's text and canvas colors.

#Classes

ClassDescription
heatmapThe list: cells fill columns of --heatmap-rows from the top
heatmap-lg20px cells with a 4px gap; the default is 12px with 3px. With heatmap
heatmap-cellOne value; set --value in its style and say it in its text, which is kept for assistive technology and not drawn

#Custom properties

PropertyDefaultDescription
--valueThe cell's number; the stylesheet reads 0 when it is not set. On heatmap-cell
--heatmap-max4The value that is full ink
--heatmap-rows7Cells in a column
--heatmap-size.75remSide of a cell
--heatmap-gap3pxSpace between cells
--heatmap-colorvar(--color-surface-inverse)The ink at the top of the scale

#Source

@master/ui/components/heatmap.css
/* * Heatmap: many small numbers as a field of cells, each as dark as its value: activity by day, load by hour. * It is a list. Every cell carries its number as --value and says it in its own text, which is kept for * assistive technology and not drawn. A cell's tone is ink mixed into the surface behind it, from a faint * tint for nothing to full ink at --heatmap-max, so the scale is one material at different depths and has no * hue. Cells fill columns of --heatmap-rows from the top, the way the weeks of a year are laid out. * The cell under the pointer takes an ink ring; its title is the tooltip the browser already has. */@layer components {  .heatmap {    --heatmap-rows: 7;    --heatmap-size: .75rem;    --heatmap-gap: 3px;    --heatmap-max: 4;    --heatmap-color: var(--color-surface-inverse);    /* The surface the cells stand on, which a card or a sheet publishes. */    --heatmap-surface: var(--surface-color, var(--color-surface-base));    display: inline-grid;    grid-template-rows: repeat(var(--heatmap-rows), var(--heatmap-size));    grid-auto-columns: var(--heatmap-size);    grid-auto-flow: column;    gap: var(--heatmap-gap);    max-width: 100%;    margin: 0;    padding: 0;    list-style: none;    vertical-align: middle;    /* Larger cells, for a week of hours or a short period. */    &.heatmap-lg {      --heatmap-size: 1.25rem;      --heatmap-gap: 4px;    }    @media (forced-colors: active) {      --heatmap-color: CanvasText;      --heatmap-surface: Canvas;    }  }  .heatmap-cell {    /* The cell's share of the scale, between nothing and all of it. */    --heatmap-share: clamp(0, calc(var(--value, 0) / var(--heatmap-max)), 1);    display: block;    margin: 0;    padding: 0;    border-radius: calc(var(--heatmap-size) / 4 * var(--corner-scale));    corner-shape: var(--corner-shape);    overflow: hidden;    /* Nothing is still a cell: 7% of ink, so an empty day has a place. Everything above it climbs to full ink. */    background: color-mix(in oklab, var(--heatmap-color) calc(7% + var(--heatmap-share) * 93%), var(--heatmap-surface));    box-shadow: inset 0 0 0 .5px color-mix(in oklab, var(--heatmap-color) 10%, transparent);    /* The text is the cell's value for a screen reader; the tone is the same value for the eye. */    color: transparent;    font-size: 0;    user-select: none;    -webkit-user-select: none;    @media (hover: hover) {      &:hover {        outline: 1.5px solid var(--color-text-strong);        outline-offset: 1px;      }    }    &:focus-visible {      outline: 2px solid var(--color-focus);      outline-offset: 1px;    }    @media (forced-colors: active) {      forced-color-adjust: none;      outline: 1px solid CanvasText;      outline-offset: -1px;    }  }}