What this visual is really for
Most business metrics live on a daily heartbeat — orders, support tickets, website sessions, machine downtime, hospital admissions, gym check-ins. A line chart shows you the trend of that heartbeat, but it hides the rhythm: which weekdays carry the load, whether weekends matter, where the dead weeks are, how December really compares to July.
A calendar heatmap lays a whole year on the table at once, one colored square per day. Patterns you would need five slicers to find in a table simply appear: the Monday surge, the summer lull, the campaign spike, the outage gap. That's the promise of this visual — and every setting below exists to sharpen one of those stories.
The two layouts: a year-at-a-glance vs. a monthly review
Continuous is the “GitHub contributions” view: weeks flow left to right in one long band per year. Use it when the question is about momentum and seasonality — “how did the year develop?”, “are we busier than last quarter?”, “where are the streaks and the gaps?”. Time reads like a sentence, left to right.
Month blocks chops the same days into twelve little calendars, the way people actually plan their lives. Use it when the question is month-shaped — “how did March go?”, “compare the first week of each month”, “was the month-end crunch worse in Q3?”. Nobody schedules anything by ISO week 37; everyone knows what “mid-March” means.
Nothing about your data changes when you switch — only the arrangement. Colors, badges, legend and every other setting apply identically on top of either layout.
- Switching layouts never changes any cell's color — only its position.
- Continuous: one horizontal band per year, months labeled along the top, weekday rail on the left.
- Month blocks: twelve mini-calendars that automatically arrange themselves into however many columns fit best — resize the tile and watch them reflow.
- Multi-year data: continuous stacks one band per year with a bold year tag; month blocks stamps the year onto each January.
Week start: a small toggle with a cultural opinion
Should the week begin on Sunday or Monday? US audiences and classic wall calendars say Sunday; European businesses, retail ops and ISO standards say Monday. It sounds cosmetic, but it changes what “the weekend” looks like: with Monday first, Saturday and Sunday sit together at the bottom of each column as one visual block — which is exactly what you want when weekend behavior is the story (restaurants, gyms, streaming).
- Every day moves to a new row — the whole grid visibly reshuffles.
- Weekday rail labels re-order to match (Sun/Tue/Thu vs Mon/Wed/Fri style).
- With Monday first, the two weekend rows sit adjacent at the bottom of each band.
Aggregating duplicate days: what does “Tuesday” even mean?
Real datasets rarely arrive as one tidy row per day. A sales table has one row per transaction; a ticketing system one row per ticket. When forty rows share the same date, the visual has to collapse them into a single square — and how it collapses them changes the question the calendar answers:
- Sum — “how much business did we do that day?” The default, right for revenue and volume.
- Average — “what was a typical deal that day?” Right for rates, scores, response times.
- Min / Max — “what was the worst / best moment that day?” Right for SLAs and peaks.
- Count — “how many things happened?” Ignores the values entirely; pure activity.
A day that looks dark under Sum can look pale under Average — lots of small transactions. That's not a bug; it's two different business questions about the same Tuesday.
- With one row per day, Sum / Avg / Min / Max all look identical, and Count turns the whole calendar flat (every day = 1). That flat look is correct, not broken.
- With duplicate rows, switching modes visibly recolors days — and the day-detail panel tells you how many rows were combined.
Fiscal years: for companies whose year doesn't start in January
Plenty of organizations live April-to-March or July-to-June. For them, a January-cut calendar quietly lies: “this year vs last year” compares the wrong months, and the year-end crunch appears mid-band instead of at the edge where a finance audience expects it.
Fiscal year starts tells the visual where the business year begins. On its own it only fixes the math behind year-over-year comparisons (used by the insights). Turn on Fiscal year layout and the calendar itself re-bands: each row of the continuous layout becomes one fiscal year, labeled “FY 2026” — the year the period ends in, matching how finance teams talk.
- Fiscal start alone: the grid does NOT move. Only insight math changes. Don't report this as a bug.
- Fiscal layout ON (continuous only): bands re-cut at the start month and labels switch to “FY yyyy”.
- Month-blocks layout ignores fiscal layout entirely — by design.
Small multiples: comparing teams without lying to anyone
Drop a category field — region, team, product line — into Split by and the calendar becomes a grid of small calendars, one per group. This is where a subtle but important honesty question appears: Shared color scale.
Shared ON answers “who is actually bigger?” One color scale covers everyone, so a dark square means the same thing in every panel. The cost: a small region looks washed out next to a big one — because it is smaller. Shared OFF answers “what is each team's own rhythm?” Every panel gets the full color range fit to its own numbers, so patterns pop everywhere — but you can no longer compare colors across panels. Neither is wrong; they answer different questions, and mixing them up is how dashboards mislead.
- Columns 0 = auto: the panel arrangement picks itself to maximize cell size; a fixed 1–8 forces it.
- Shared ON: low-volume facets look pale — correct, not a rendering fault.
- Shared OFF: identical colors across panels no longer mean identical values.
Color: the biggest lever in the whole visual
Color is the data in a heatmap, so this card deserves the most care — and the most testing.
Palette type — what story is the color telling?
- Ramp — six curated multi-stop palettes, each tuned separately for light and dark reports. The safe, pretty default.
- Mono — one brand hue fading into the background. Quietest option; great when the heatmap supports a page rather than starring on it.
- Duotone — your own two colors, low to high. Brand control without designing a full ramp.
- Split (diverging) — three colors: below / middle / above. The right choice when the data has a meaningful midpoint (variance vs plan, temperature vs normal, sentiment).
- Report theme — borrows the report's own theme color, so the visual matches whatever report it lands in without configuration.
Color scaling — the honesty dial
Imagine one Black-Friday day that's 40× a normal day. On a Linear scale — an honest ruler — that one day is dark and the other 364 look nearly identical. Truthful about magnitude, useless for patterns. Quantile grades on a curve instead: colors show each day's rank, so the calendar stays richly textured no matter how wild the outliers — that's why it's the default. Log is the compromise for data spanning orders of magnitude, where 10 → 100 should look like the same step as 100 → 1,000.
Buckets — gradient elegance vs. executive readability
A continuous gradient shows the finest differences, but nobody can tell “62%” from “68%” by eye. Bucketing into 3, 5 or 7 shades turns the calendar into named classes — quiet / normal / busy — that a leadership audience reads instantly and consistently. Rule of thumb: gradients for exploration, buckets for reporting.
- Every ramp changes when you flip the report theme dark/light — the visual picks the variant, not you.
- Quantile + buckets = equal COUNT of days per shade; linear + buckets = equal value ranges. Different boundaries are expected.
- Switching to Continuous (0 buckets) also switches the legend from swatches to a gradient bar.
- No-data days always use the no-data color — they never participate in the scale.
The legend: small strip, big trust
The legend is what lets a viewer trust the colors. “Less → More” with the actual swatches (or the actual gradient) is the contract between the visual and its audience. The no-data swatch matters more than it looks: in sparse datasets it's the difference between “that day was quiet” and “we have no record of that day” — two very different business statements. Custom low/high labels let the strip speak the data's language: “Fewer tickets → More tickets” beats “Less → More”.
- Placement folds show + position into one choice: off / bottom / top.
- Bucketed scale → discrete swatches sized by Swatch size; continuous scale → gradient bar sized by Gradient length. The two size controls swap with the bucket setting.
- Legend is 'chrome': on a very short tile it disappears before the grid does — by design.
KPI header & insights: the visual that reads itself
The KPI header turns the tile into a self-contained report block: a title plus stat chips (total, daily average, peak) so a viewer gets the headline number before decoding any color. The accent rule under the title is the brand signature — recolor or hide it per report.
Insights go a step further: one-line, auto-computed takeaways — peak day, strongest weekday, month-over-month direction. The subtle setting here is polarity: is a higher number good news? For sales, yes — an upward trend colors positively. For support tickets, complaints or downtime, more is bad — flip polarity and the same upward trend colors as a warning. And Neutral exists because some metrics genuinely have no good or bad direction, and coloring them would editorialize.
- Blank title auto-generates from the field names (“<Value> by <Split-by>”).
- Polarity only recolors insight text — the grid never changes.
- On short tiles, insights are the FIRST thing to disappear, then legend, then header chips. Watch the order.
Day badges & rules: turning a picture into a monitor
Everything so far shows patterns. Badges mark events. Mark peak day stamps your emoji on the single best day — the “what was our record?” question answered permanently. The three rule slots are the operational layer: each rule tests every day against a condition and marks the hits with a colored ring, an optional emoji, and — critically — an optional hatch pattern.
Business examples that map straight onto rules: “ring every day we breached 200 tickets” (Value ≥ 200), “flag days we missed plan” (Value − Target < 0), “highlight the healthy band” (between 80 and 120). The hatch pattern is the difference between a pretty chart and a compliant one: rings and colors vanish in grayscale print and for colorblind readers; the hatch survives both.
- Rules stack — one day can match several and wear several rings.
- “Value − Target” rules silently skip days with no target bound — that's correct.
- Emojis hide on very small cells (nothing readable would fit); rings and hatches remain.
- 'between' shows a second value box; other operators hide it.
Annotations: institutional memory, pinned to a date
Six months from now, someone will look at the March spike and ask “what happened there?” Annotations are the answer, written down at the moment anyone still remembers: a note pinned to a specific day — “Campaign launch”, “Price change”, “Outage” — stored in the report itself, not in the data. Markers can be numbered chips, dots, or an emoji; each note can show as just a marker, floating text, or text with a pointer arrow.
- Notes survive data refreshes — they belong to the report, not the dataset.
- Marker style switches chip ↔ dot ↔ emoji; color control hides in emoji mode.
- “New note shows” only sets the default for future notes; existing notes keep their own display mode.
Summary table: the escape hatch for numbers people
Some stakeholders will never trust a color. The summary table is the same data as an honest per-month (or per-group) table — totals, daily averages, peaks — one click away via a floating toggle in the corner. It's also an accessibility feature: a screen-reader-friendly, precise alternative to color perception. The reader's flip is session-local; it never rewrites the report author's choice.
Day detail panel: click a square, get the receipt
Hovering gives a glance; clicking opens the receipt: full date, exact value, target comparison, how many rows were aggregated — and with split data, which group contributed most to that day. Position auto docks it right on wide tiles and bottom on tall ones, so it covers as little of the calendar as possible.
Accessibility: not a checkbox, a parallel channel
Roughly 1 in 12 men can't reliably distinguish the hues most heatmaps rely on. Pattern on threshold gives high values a texture channel alongside the color channel — the calendar stays readable in grayscale print, on bad projectors, and for colorblind readers. The focus ring makes keyboard navigation visible. These aren't optional polish: Microsoft certification reviews them, and the defaults (Okabe-Ito safe colors for the rule slots, a colorblind-safe ramp in the palette list) mean the visual is presentable to any audience without extra work.
- Accessibility patterns and badge-rule patterns are independent layers — both can be active at once; pick different styles.
- Focus ring only appears during keyboard navigation, never on mouse clicks.
Testing-day cheat sheet
The one-table version — what a correct visual does when you flip each thing:
| You change… | A correct visual… | A bug would look like… |
|---|---|---|
| Layout | Rearranges cells; colors identical | Any cell changing color |
| Week start | All rows reshuffle; rail labels re-order | Grid unchanged, or labels stale |
| Aggregation (dup. data) | Cells recolor; detail panel shows row count | No recolor despite duplicate rows |
| Fiscal start alone | Grid unchanged (insight math only) | Grid re-banding without fiscal layout on |
| Fiscal layout on | Continuous bands re-cut at start month, “FY yyyy” labels | Bands still cut at January |
| Shared scale off | Small facets gain contrast; cross-panel comparison lost | No visible change on uneven facets |
| Scale mode (outlier data) | Quantile textured; linear flattens quiet days | Both modes identical |
| Buckets ↔ continuous | Legend swaps swatches ↔ gradient bar | Legend style stuck |
| Tile shrink | Cells shrink → rails drop → insights, legend, header shed in order | Overlapping text, clipped grid |
| Theme dark ↔ light | Ramp variant + no-data color + text all swap | Dark-theme colors on light canvas |
| Rule with no target bound | Value−Target rules mark nothing | Rings on every day |
FAQ — questions real users ask
Click a question to expand it.
How do I add this visual to my report?
.pbiviz file: ⋯ → Import a visual from a file.) It then appears as a new icon in the visualizations pane like any native visual.