charty

CalendarHeatmapChart#

Best for visualizing daily activity or intensity over weeks and months in a calendar grid, like GitHub's contribution graph. For a grid that is not tied to dates, see MatrixHeatmapChart.

CalendarHeatmapChart

Kotlin
CalendarHeatmapChart(    data = {        listOf(            CalendarData(year = 2024, month = 1, day = 1, value = 3f),            CalendarData(year = 2024, month = 1, day = 2, value = 7f),            CalendarData(year = 2024, month = 1, day = 3, value = 0f),            CalendarData(year = 2024, month = 1, day = 4, value = 12f),            CalendarData(year = 2024, month = 1, day = 7, value = 5f),        )    },    modifier = Modifier.fillMaxWidth(),    config = CalendarHeatmapConfig(animation = Animation.Default),    visibleWeeks = 12,    scrollEnabled = true,    onDayClick = { data -> println("${data.year}-${data.month}-${data.day}: ${data.value}") },)

CalendarData validates month in 1..12 and day in 1..31 at construction. Data points need not be contiguous — missing dates render as empty cells.

visibleWeeks is nullable (Int?, default null): leave it out to fit the whole range, or set it to cap how many week columns are on screen at once. scrollEnabled (default true) allows horizontal scrolling through the full date range.

Cell appearance#

Kotlin
config = CalendarHeatmapConfig(    cellShape = CellShape.Circle,    cellSize = 16.dp,    cellSpacing = 3.dp,)

CellShape is a sealed class: Square, RoundedSquare(cornerRadius), Circle, or Diamond.

Intensity colours#

Kotlin
config = CalendarHeatmapConfig(    intensityColors = listOf(        Color(0xFFD7CCF7),        Color(0xFFB39DDB),        Color(0xFF7E57C2),        Color(0xFF4527A0),    ),    emptyColor = Color(0xFFF0F0F0),)

Values are interpolated across intensityColors from lowest to highest; days with no data use emptyColor. The list must not be empty. Note these are plain Color values, not ChartyColor.

Labels and week start#

Kotlin
config = CalendarHeatmapConfig(    showMonthLabels = true,    showDayLabels = true,    weekStartDay = WeekStartDay.MONDAY,    labelTextStyle = TextStyle(fontSize = 11.sp),)

Tooltip#

Tapping a day with data raises the built-in canvas tooltip. There is no tooltip parameter on this chart, so the canvas bubble is the only option; style and format it through the config.

Kotlin
config = CalendarHeatmapConfig(    tooltipConfig = TooltipConfig(showArrow = false),    tooltipFormatter = { data -> "${data.value.toInt()} commits on ${data.month}/${data.day}" },)

Accessibility#

The chart attaches a generated summary to its root: "Calendar heatmap, N days with data. Busiest day: …". Unlike most charts there is no way to override or suppress itCalendarHeatmapChart has no accessibilityDescription parameter and no interactionConfig. There is also no per-day screen-reader traversal.

CalendarHeatmapConfig#

PropertyTypeDefaultDescription
intensityColorsList<Color>four GitHub-green shadesLow-to-high intensity scale; must not be empty
emptyColorColor#EBEDF0Fill for days with no data
cellShapeCellShapeRoundedSquare(cornerRadius = 2f)Square, RoundedSquare, Circle, or Diamond
cellSizeDp14.dpSide length of each cell
cellSpacingDp2.dpGap between cells
showMonthLabelsBooleantrueDraws month abbreviations above the grid
showDayLabelsBooleantrueDraws day-of-week labels beside the grid
weekStartDayWeekStartDaySUNDAYSUNDAY or MONDAY
labelTextStyleTextStyle10 sp, #57606AStyle of the month and day labels
animationAnimationAnimation.DefaultCell entry animation
tooltipConfigTooltipConfig?null (the theme's)Canvas tooltip appearance
tooltipFormatter(CalendarData) -> String"<value> on <Mon> <day>, <year>"Tooltip text

Limitations#