
Animated, accessible bar, line, pie, radar and gauge charts drawn on Canvas; RTL-aware, allocation-free rendering, and externally controlled selection state for easy integration and testing.
Charts for Compose Multiplatform. Android, iOS and desktop, one codebase.
Five chart types (bar, line, pie, radar, gauge) drawn on Canvas, animated, and
accessible by default.
| Bar | Line |
|---|---|
| Pie | Radar |
| Gauge | |
commonMain.dependencies {
implementation("io.grafima:grafima:1.2.0")
}On an Android-only project, put it in the usual dependencies block instead:
dependencies {
implementation("io.grafima:grafima:1.2.0")
}BarChart(
dataSet = BarDataSet(
entries = listOf(
BarEntry(id = "jan", xLabel = "Jan", y = 45f),
BarEntry(id = "feb", xLabel = "Feb", y = 80f)
),
contentDescription = "Monthly revenue"
),
modifier = Modifier.fillMaxWidth().height(300.dp)
)Γράφημα is the Greek word for chart. I'm Greek, so the name picked itself.
I wanted charts I could ship in a real app without a list of things to fix later. So the hard parts came first: screen readers read them properly, right-to-left layouts work, setup is quick, and drawing stays cheap.
Those four are the easiest to put off and the slowest to add back. If you need to move fast without giving them up, that is what this is for.
Accessible. Every chart is one labelled node, the selection is announced as state, and each item gets a named action, so nobody has to land a tap on a moving target. How it works
RTL throughout. Mirrored properly, down to which end of a bar is rounded.
Cheap to draw. Nothing is allocated per frame, and a running animation redraws without recomposing.
Selection is yours. No chart owns its selection state. You pass it in and get changes back.
Tested. A unit suite on the JVM and an iOS simulator, and a UI suite on an Android emulator and an iOS simulator, including accessibility contracts every chart has to pass. Test suites
Every chart has a guide with a rendered example and the full parameter list:
Bar · Line · Pie · Radar · Gauge
Behaviour shared by every chart is in Concepts.
iosArm64 and iosSimulatorArm64 (Apple silicon simulators; Compose
Multiplatform publishes no iosX64)jvm target, for Compose for Desktop hostsThe sample module holds the demo UI shared by all three apps.
./gradlew :androidApp:installDebug # Android
./gradlew :desktopApp:run # Desktop
open iosApp/iosApp.xcodeproj # iOS, then run from XcodeI'm not just maintaining this, I'm still building it. More chart types and more features are coming.
If you want something changed or added, open an issue first so we can agree on the shape, then send a PR.
CONTRIBUTING.md has the branching model and what CI checks. docs/TESTING.md covers the test suites and how to run them.
Thanks to everyone who has contributed.
I'd rather tell you than let you guess:
Using an LLM on a contribution is fine. Open the PR from your own GitHub account, not a bot's.
See CHANGELOG.md.
Apache 2.0, see LICENSE.
Charts for Compose Multiplatform. Android, iOS and desktop, one codebase.
Five chart types (bar, line, pie, radar, gauge) drawn on Canvas, animated, and
accessible by default.
| Bar | Line |
|---|---|
| Pie | Radar |
| Gauge | |
commonMain.dependencies {
implementation("io.grafima:grafima:1.2.0")
}On an Android-only project, put it in the usual dependencies block instead:
dependencies {
implementation("io.grafima:grafima:1.2.0")
}BarChart(
dataSet = BarDataSet(
entries = listOf(
BarEntry(id = "jan", xLabel = "Jan", y = 45f),
BarEntry(id = "feb", xLabel = "Feb", y = 80f)
),
contentDescription = "Monthly revenue"
),
modifier = Modifier.fillMaxWidth().height(300.dp)
)Γράφημα is the Greek word for chart. I'm Greek, so the name picked itself.
I wanted charts I could ship in a real app without a list of things to fix later. So the hard parts came first: screen readers read them properly, right-to-left layouts work, setup is quick, and drawing stays cheap.
Those four are the easiest to put off and the slowest to add back. If you need to move fast without giving them up, that is what this is for.
Accessible. Every chart is one labelled node, the selection is announced as state, and each item gets a named action, so nobody has to land a tap on a moving target. How it works
RTL throughout. Mirrored properly, down to which end of a bar is rounded.
Cheap to draw. Nothing is allocated per frame, and a running animation redraws without recomposing.
Selection is yours. No chart owns its selection state. You pass it in and get changes back.
Tested. A unit suite on the JVM and an iOS simulator, and a UI suite on an Android emulator and an iOS simulator, including accessibility contracts every chart has to pass. Test suites
Every chart has a guide with a rendered example and the full parameter list:
Bar · Line · Pie · Radar · Gauge
Behaviour shared by every chart is in Concepts.
iosArm64 and iosSimulatorArm64 (Apple silicon simulators; Compose
Multiplatform publishes no iosX64)jvm target, for Compose for Desktop hostsThe sample module holds the demo UI shared by all three apps.
./gradlew :androidApp:installDebug # Android
./gradlew :desktopApp:run # Desktop
open iosApp/iosApp.xcodeproj # iOS, then run from XcodeI'm not just maintaining this, I'm still building it. More chart types and more features are coming.
If you want something changed or added, open an issue first so we can agree on the shape, then send a PR.
CONTRIBUTING.md has the branching model and what CI checks. docs/TESTING.md covers the test suites and how to run them.
Thanks to everyone who has contributed.
I'd rather tell you than let you guess:
Using an LLM on a contribution is fine. Open the PR from your own GitHub account, not a bot's.
See CHANGELOG.md.
Apache 2.0, see LICENSE.