Heatmap chart
The heatmap chart visualizes a two-dimensional matrix of values as a grid of colored tiles. It works well for activity calendars, density maps, and any data with two categorical axes and a single numeric value.
TIP
This component is best used inside a Chart pane.
Props
series: FluxStatisticsChartHeatmapSeries[]
The data series for the heatmap. Each point holds named `x`, `y`, and `value` fields.
x-labels?: string[]
Category labels for the X-axis.
y-labels?: string[]
Category labels for the Y-axis.
tooltip?: boolean
Show a tooltip on hover. Disabled by default.
x-axis-labels?: boolean
Show the labels on the X-axis. Disabled by default.
y-axis-labels?: boolean
Show the labels on the Y-axis. Disabled by default.
advanced-options?: EChartsOption
Escape-hatch for raw ECharts options merged on top of the Flux defaults. Use for custom `visualMap` ranges.
Examples
Activity calendar
A weekly activity heatmap that resembles a contribution graph.
<template>
<FluxStatisticsChartPane
icon="calendar"
title="Contribution graph"
:aspect-ratio="3">
<FluxStatisticsHeatmapChart
x-axis-labels
y-axis-labels
:advanced-options="advancedOptions"
:series="series"
:x-labels="weeks"
:y-labels="days"/>
</FluxStatisticsChartPane>
</template>
<script
setup
lang="ts">
import { emerald100, emerald300, emerald500, emerald700 } from '@flux-ui/internals';
import type { EChartsOption } from 'echarts/core';
import type { FluxStatisticsChartHeatmapPoint, FluxStatisticsChartHeatmapSeries } from '@flux-ui/types';
import { FluxStatisticsChartPane, FluxStatisticsHeatmapChart } from '@flux-ui/statistics';
const days = ['Mon', 'Wed', 'Fri', 'Sun'];
const weeks = Array.from({ length: 24 }, (_, i) => `W${i + 1}`);
const data: FluxStatisticsChartHeatmapPoint[] = days.flatMap(day =>
weeks.map(week => ({ x: week, y: day, value: Math.round(Math.random() * 12) }))
);
const series: FluxStatisticsChartHeatmapSeries[] = [{ data }];
const advancedOptions: EChartsOption = {
visualMap: {
show: false,
min: 0,
max: 12,
pieces: [
{ min: 0, max: 2, color: emerald100 },
{ min: 3, max: 5, color: emerald300 },
{ min: 6, max: 8, color: emerald500 },
{ min: 9, max: 12, color: emerald700 }
]
}
};
</script>Single series
A simpler one-series heatmap with custom color ranges.
<template>
<FluxStatisticsChartPane
icon="grid-2"
title="Hourly traffic"
:aspect-ratio="3">
<FluxStatisticsHeatmapChart
x-axis-labels
y-axis-labels
:advanced-options="advancedOptions"
:series="series"
:x-labels="hours"
:y-labels="['Traffic']"/>
</FluxStatisticsChartPane>
</template>
<script
setup
lang="ts">
import { violet100, violet300, violet500, violet700 } from '@flux-ui/internals';
import type { EChartsOption } from 'echarts/core';
import type { FluxStatisticsChartHeatmapPoint, FluxStatisticsChartHeatmapSeries } from '@flux-ui/types';
import { FluxStatisticsChartPane, FluxStatisticsHeatmapChart } from '@flux-ui/statistics';
const hours = Array.from({ length: 24 }, (_, i) => `${i.toString().padStart(2, '0')}:00`);
const data: FluxStatisticsChartHeatmapPoint[] = hours.map(hour => ({
x: hour,
y: 'Traffic',
value: Math.round(Math.random() * 1000)
}));
const series: FluxStatisticsChartHeatmapSeries[] = [{ data }];
const advancedOptions: EChartsOption = {
visualMap: {
show: false,
min: 0,
max: 1000,
inRange: {
color: [violet100, violet300, violet500, violet700]
}
}
};
</script>Custom colors
A heatmap configured with a custom color scale.
<template>
<FluxStatisticsChartPane
icon="grid-2"
title="Performance grid"
:aspect-ratio="2.4">
<FluxStatisticsHeatmapChart
x-axis-labels
y-axis-labels
:advanced-options="advancedOptions"
:series="series"
:x-labels="slots"
:y-labels="servers"/>
</FluxStatisticsChartPane>
</template>
<script
setup
lang="ts">
import { amber500, green500, red500 } from '@flux-ui/internals';
import type { EChartsOption } from 'echarts/core';
import type { FluxStatisticsChartHeatmapPoint, FluxStatisticsChartHeatmapSeries } from '@flux-ui/types';
import { FluxStatisticsChartPane, FluxStatisticsHeatmapChart } from '@flux-ui/statistics';
const servers = ['Server A', 'Server B', 'Server C', 'Server D'];
const slots = Array.from({ length: 10 }, (_, i) => `T${i + 1}`);
const data: FluxStatisticsChartHeatmapPoint[] = servers.flatMap(server =>
slots.map(slot => ({ x: slot, y: server, value: Math.round(Math.random() * 100) }))
);
const series: FluxStatisticsChartHeatmapSeries[] = [{ data }];
const advancedOptions: EChartsOption = {
visualMap: {
show: false,
min: 0,
max: 100,
pieces: [
{ min: 0, max: 33, color: red500 },
{ min: 34, max: 66, color: amber500 },
{ min: 67, max: 100, color: green500 }
]
}
};
</script>Cohort retention
A retention heatmap that fades as cohorts decay over time.
<template>
<FluxStatisticsChartPane
icon="grid-2"
title="Cohort retention"
:aspect-ratio="2.4">
<FluxStatisticsHeatmapChart
x-axis-labels
y-axis-labels
:series="series"
:x-labels="months"
:y-labels="cohorts"/>
</FluxStatisticsChartPane>
</template>
<script
setup
lang="ts">
import type { FluxStatisticsChartHeatmapPoint, FluxStatisticsChartHeatmapSeries } from '@flux-ui/types';
import { FluxStatisticsChartPane, FluxStatisticsHeatmapChart } from '@flux-ui/statistics';
const cohorts = ['Jan', 'Feb', 'Mar', 'Apr', 'May'];
const months = ['M1', 'M2', 'M3', 'M4', 'M5', 'M6'];
const data: FluxStatisticsChartHeatmapPoint[] = cohorts.flatMap((cohort, rowIdx) =>
months.map((month, colIdx) => {
const decay = Math.max(0, 100 - colIdx * 14 - rowIdx * 5 + Math.round(Math.random() * 8));
return { x: month, y: cohort, value: decay };
})
);
const series: FluxStatisticsChartHeatmapSeries[] = [{ data }];
</script>Punchcard
A weekly punchcard heatmap highlighting peak working hours.
<template>
<FluxStatisticsChartPane
icon="grid-2"
title="Commit punchcard"
:aspect-ratio="3">
<FluxStatisticsHeatmapChart
x-axis-labels
y-axis-labels
:advanced-options="advancedOptions"
:series="series"
:x-labels="hours"
:y-labels="days"/>
</FluxStatisticsChartPane>
</template>
<script
setup
lang="ts">
import { amber500, orange500, red500 } from '@flux-ui/internals';
import type { EChartsOption } from 'echarts/core';
import type { FluxStatisticsChartHeatmapPoint, FluxStatisticsChartHeatmapSeries } from '@flux-ui/types';
import { FluxStatisticsChartPane, FluxStatisticsHeatmapChart } from '@flux-ui/statistics';
const days = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'];
const hours = Array.from({ length: 24 }, (_, i) => `${i.toString().padStart(2, '0')}:00`);
const data: FluxStatisticsChartHeatmapPoint[] = days.flatMap(day =>
hours.map(hour => {
const h = parseInt(hour, 10);
const isWeekday = !['Sat', 'Sun'].includes(day);
const peak = isWeekday && h >= 9 && h <= 17 ? Math.round(Math.random() * 24) : Math.round(Math.random() * 6);
return { x: hour, y: day, value: peak };
})
);
const series: FluxStatisticsChartHeatmapSeries[] = [{ data }];
const advancedOptions: EChartsOption = {
visualMap: {
show: false,
min: 0,
max: 24,
inRange: { color: [amber500, orange500, red500] }
}
};
</script>With tooltip
Enable the hover tooltip by setting the `tooltip` prop.
<template>
<FluxStatisticsChartPane
icon="grid-2"
title="Weekly activity"
:aspect-ratio="2.4">
<FluxStatisticsHeatmapChart
tooltip
x-axis-labels
y-axis-labels
:series="series"
:x-labels="weeks"
:y-labels="days"/>
</FluxStatisticsChartPane>
</template>
<script
setup
lang="ts">
import type { FluxStatisticsChartHeatmapPoint, FluxStatisticsChartHeatmapSeries } from '@flux-ui/types';
import { FluxStatisticsChartPane, FluxStatisticsHeatmapChart } from '@flux-ui/statistics';
const days = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'];
const weeks = Array.from({ length: 12 }, (_, i) => `W${i + 1}`);
const data: FluxStatisticsChartHeatmapPoint[] = days.flatMap(day =>
weeks.map(week => ({ x: week, y: day, value: Math.round(Math.random() * 100) }))
);
const series: FluxStatisticsChartHeatmapSeries[] = [{ data }];
</script>