Skip to content

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 } }]).

ts
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 },
  };
}
ts
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)):

ts
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 },
  };
}
ts
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;
}
OptionTypeDefaultDescription
gradientLegend.enabledbooleantrueshow the scale
gradientLegend.position'right' | 'bottom''right'placement side
gradientLegend.spacingPixels10gap from the plot area
gradientLegend.thicknessPixels12bar 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):

ts
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 },
  };
}
ts
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:

ts
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 },
  };
}
ts
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;
}
OptionTypeDefaultDescription
xFieldstringaxis categories
yFieldstringaxis categories
colorFieldstringnumeric value → color
colorRangeColorValue[]blue-cyanscale stops (2+)
itemPaddingPixels1gap between cells
cornerRadiusPixels2cell corner rounding
colorNamestringcolorField namevalue label in the tooltip
label.enabledbooleanfalseshow value labels
label.placementcenter, edges and corners (9 positions)'center'label position
label.formatter({ value, datum }) => stringthe valuelabel content
label.fontSizePixels11label font size
label.fontWeightstring | numbernormalfont weight
label.fontFamilystringtheme fontfont family
label.colorColorValueforeground; auto-contrast when insidetext color

Options

Options common to all series (name, showInLegend, tooltip.renderer, …) are covered in Common series options.