Heatmap
Categories on both axes; the colorField value sets the cell color on a continuous scale. A gradient legend automatically appears on the right.
By default, heatmap axes are drawn without lines, ticks, or grid — only the category labels remain (bring them back via axes: [{ ..., line: { enabled: true } }]).
import { getData } from './data';
import type { ChartOptions } from 'grafit-charts';
export function createOptions(): ChartOptions {
return {
data: getData(),
title: { text: 'Load by hour' },
series: [
{
type: 'heatmap',
xField: 'day',
yField: 'hour',
colorField: 'load',
colorName: 'Load',
colorRange: ['#e8f0fe', '#1d4fd7'],
},
],
legend: { enabled: false },
};
}export function getData() {
const days = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'];
const hours = ['00', '04', '08', '12', '16', '20'];
const data: Array<{ day: string; hour: string; load: number }> = [];
days.forEach((day, d) => {
hours.forEach((hour, h) => {
const base = h === 2 || h === 3 ? 60 : h === 4 ? 45 : 15;
const weekend = d >= 5 ? 0.5 : 1;
data.push({ day, hour, load: Math.round(base * weekend + ((d * 7 + h * 3) % 13)) });
});
});
return data;
}Color scale placement
gradientLegend controls the scale's position, spacing, and thickness (in a grafit-charts/core build the scale is a separate module: register(gradientLegendModule)):
import { getData } from './data';
import type { ChartOptions } from 'grafit-charts';
export function createOptions(): ChartOptions {
return {
data: getData(),
title: { text: 'Scale at the bottom with spacing' },
series: [{ type: 'heatmap', xField: 'week', yField: 'day', colorField: 'deploys', colorName: 'Deploys' }],
gradientLegend: { position: 'bottom', spacing: 14, thickness: 10 },
legend: { enabled: false },
};
}export function getData() {
const days = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri'];
const weeks = ['W1', 'W2', 'W3', 'W4'];
const data: Array<{ week: string; day: string; deploys: number }> = [];
weeks.forEach((week, w) => {
days.forEach((day, d) => {
data.push({ week, day, deploys: ((w * 5 + d * 3) % 11) + (d === 2 ? 6 : 1) });
});
});
return data;
}| Option | Type | Default | Description |
|---|---|---|---|
gradientLegend.enabled | boolean | true | show the scale |
gradientLegend.position | 'right' | 'bottom' | 'right' | placement side |
gradientLegend.spacing | Pixels | 10 | gap from the plot area |
gradientLegend.thickness | Pixels | 12 | bar thickness |
Value labels
label: { enabled: true } shows the value in each cell; the text color is chosen automatically based on the background luminance. The tooltip here is anchored to the cell center (tooltip.position.anchorTo: 'center'; the default is the top edge):
import { getData } from './data';
import type { ChartOptions } from 'grafit-charts';
export function createOptions(): ChartOptions {
return {
data: getData(),
title: { text: 'Value labels' },
series: [
{
type: 'heatmap',
xField: 'week',
yField: 'day',
colorField: 'deploys',
colorName: 'Deploys',
// text color is chosen automatically based on cell luminance
label: { enabled: true },
},
],
// tooltip at the cell center
tooltip: { position: { anchorTo: 'center' } },
legend: { enabled: false },
};
}export function getData() {
const days = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri'];
const weeks = ['W1', 'W2', 'W3', 'W4'];
const data: Array<{ week: string; day: string; deploys: number }> = [];
weeks.forEach((week, w) => {
days.forEach((day, d) => {
data.push({ week, day, deploys: ((w * 5 + d * 3) % 11) + (d === 2 ? 6 : 1) });
});
});
return data;
}Custom labels
formatter, font, color, and placement (placement: 'top') are configurable; the scale can be disabled:
import { getData } from './data';
import type { ChartOptions } from 'grafit-charts';
export function createOptions(): ChartOptions {
return {
data: getData(),
title: { text: 'Custom labels' },
subtitle: { text: 'formatter, font and color; scale disabled' },
series: [
{
type: 'heatmap',
xField: 'week',
yField: 'day',
colorField: 'deploys',
colorRange: ['#fef3e2', '#e8590c'],
itemPadding: 4,
cornerRadius: 8,
label: {
enabled: true,
placement: 'top-left',
formatter: ({ value }) => `${value}×`,
fontSize: 13,
fontWeight: 'bold',
},
},
],
gradientLegend: { enabled: false },
legend: { enabled: false },
};
}export function getData() {
const days = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri'];
const weeks = ['W1', 'W2', 'W3', 'W4'];
const data: Array<{ week: string; day: string; deploys: number }> = [];
weeks.forEach((week, w) => {
days.forEach((day, d) => {
data.push({ week, day, deploys: ((w * 5 + d * 3) % 11) + (d === 2 ? 6 : 1) });
});
});
return data;
}| Option | Type | Default | Description |
|---|---|---|---|
xField | string | — | axis categories |
yField | string | — | axis categories |
colorField | string | — | numeric value → color |
colorRange | ColorValue[] | blue-cyan | scale stops (2+) |
itemPadding | Pixels | 1 | gap between cells |
cornerRadius | Pixels | 2 | cell corner rounding |
colorName | string | colorField name | value label in the tooltip |
label.enabled | boolean | false | show value labels |
label.placement | center, edges and corners (9 positions) | 'center' | label position |
label.formatter | ({ value, datum }) => string | the value | label content |
label.fontSize | Pixels | 11 | label font size |
label.fontWeight | string | number | normal | font weight |
label.fontFamily | string | theme font | font family |
label.color | ColorValue | foreground; auto-contrast when inside | text color |
Options
Options common to all series (name, showInLegend, tooltip.renderer, …) are covered in Common series options.