Heatmap colour ramp is invariant across `valueMode`; only labels change
`valueMode: "count" | "intensity" | "share"` only changes the scale-bar copy and tooltip phrasing. Cell fills are always driven by intensity (`count / maxCount`). Switching mode never repaints the surface — so two heatmaps in different modes remain visually comparable.
Context
Three legitimate ways to answer “how hot was this cell?”:
- count — raw event count. Honest but not normalised — dense matches swamp sparse matches.
- intensity —
count / maxCount. Relative within the chart. - share —
count / totalEvents. Normalised against the whole dataset (useful when the chart is cropped).
The trap: if cell fill depends on mode, then the same cell in the same dataset
renders differently under share vs count, breaking pattern recognition.
Consumers comparing two heatmaps side-by-side can’t tell whether a darker cell
means more events or a different mode selection.
Decision
Fill is always intensity. valueMode only retitles the scale bar and tooltip
rows — “3 events” vs “50% intensity” vs “12% share”. The underlying colour
scale domain is [0, maxCount] computed once and shared across all modes.
Consequences
- Visual comparability is preserved across modes. A cell that reads “dark red” is the local maximum regardless of whether the user is looking at counts, shares, or intensities.
- Consumers who genuinely want a share-driven fill (e.g. for cross-chart
normalisation) override with a custom
colorScalekeyed to share values. - The tooltip label is the user-facing vocabulary switch; the scale bar caption
follows the same rule (see
metricLabelprop). sharemode’s denominator is the filtered event total, not the raw input. Filters liketeamFilterapply upstream; the denominator matches what’s actually rendered.