charty

BubbleBarChart#

Best for a playful alternative to a plain bar: instead of a solid rectangle, each column is filled with a stack of circles whose overall height still encodes the value.

BubbleBarChart

Kotlin
BubbleBarChart(    data = {        listOf(            BarData(label = "Mon", value = 5f),            BarData(label = "Tue", value = 8f),            BarData(label = "Wed", value = 3f),            BarData(label = "Thu", value = 10f),            BarData(label = "Fri", value = 6f),        )    },    modifier = Modifier.fillMaxWidth().height(320.dp),    color = ChartyColor.Solid(ChartyColors.Blue),    bubbleConfig = BubbleBarChartConfig(        bubbleRadius = 40f,        bubbleSpacing = 8f,        animation = Animation.Default,    ),    onBarClick = { barData -> println("Clicked: ${barData.label} = ${barData.value}") },)

The value maps to the column's height exactly as in a normal bar chart; the number of bubbles is then derived from that pixel height divided by bubbleRadius * 2 + bubbleSpacing. It is not a count of items, and there is no partial bubble — the topmost bubble is clipped to the column instead. A larger bubbleRadius means fewer, bigger bubbles for the same value.

A BarData may carry its own color: ChartyColor?, which overrides the chart-level color. A ChartyColor.Gradient is sampled per bubble, so the stack shades from one end of the gradient to the other.

Rolling window#

Kotlin
bubbleConfig = BubbleBarChartConfig(visibleWindow = 15, animation = Animation.Fast)

Keeps only the last N columns on screen; null or at least 2.

Persistent markers#

Kotlin
bubbleConfig = BubbleBarChartConfig(    visibleWindow = 15,    markers = listOf(PersistentMarker(dataIndex = -1, label = "Now")),)

A negative dataIndex counts back from the end of the drawn data, so -1 marks the newest column.

Animating value changes#

Kotlin
bubbleConfig = BubbleBarChartConfig(animateValueChanges = true, animation = Animation.Fast)

Tooltip#

BubbleBarChart has no tooltip parameter — tapping a column raises the built-in canvas tooltip only, styled through the config.

Kotlin
bubbleConfig = BubbleBarChartConfig(    tooltipConfig = TooltipConfig(showArrow = false),    tooltipPosition = TooltipPosition.ABOVE,    tooltipFormatter = { barData -> "${barData.label}: ${barData.value}" },)

Accessibility#

A generated summary plus one focusable node per column.

Kotlin
interactionConfig = ChartInteractionConfig(accessibilityDescription = "Daily activity")

BubbleBarChartConfig#

PropertyTypeDefaultDescription
barWidthFractionFloat0.2fColumn width as a fraction of its slot; 0f..1f
bubbleRadiusFloat100fRadius of each bubble in pixels; must be positive
bubbleSpacingFloat8fVertical gap between bubbles; non-negative
negativeValuesDrawModeNegativeValuesDrawModeBELOW_AXISBELOW_AXIS or FROM_MIN_VALUE
animationAnimationAnimation.DefaultFill-from-baseline entry animation
animateValueChangesBooleanfalseTween values on data change
referenceLineReferenceLineConfig?nullOptional horizontal guide line
markersList<PersistentMarker>emptyList()Persistent pinned labels
tooltipConfigTooltipConfig?null (the theme's)Canvas tooltip appearance
tooltipPositionTooltipPositionAUTOABOVE, BELOW, or AUTO
tooltipFormatter(BarData) -> String"label: value"Tooltip text
visibleWindowInt?nullRolling "show last N" window; null or >= 2

The default bubbleRadius of 100f produces one very large bubble per column at typical chart heights; set it explicitly.

Limitations#