
Composable chart components offering bar, line, pie, bubble, dial and sparkline visuals with configurable styling, legends, animations and lightweight "simple" variants for inline indicators.
Chart composables for Kotlin Multiplatform projects. Targets Android, JVM/Desktop, iOS and JS.
[!WARNING] This library is alpha (
0.0.x), and its API is still being worked out. Composable signatures, config classes and the defaults objects may change between releases, and some changes will be breaking. Each one is listed in the changelog.
This library was originally forked from the compose-multiplatform-charts project, created and maintained by the team at Netguru.
Since the original project appears to no longer be actively maintained and reaching out went unanswered, we have forked the library to continue its development, support newer Kotlin Multiplatform environments, add new chart components, and prepare it for publishing.
The original code is licensed under the MIT License and remains under it — see LICENSE-MIT.md. This fork is licensed under the Apache License 2.0 — see LICENSE and NOTICE.md.
Go to the root directory and build the project, or run the local publish script:
./publish-local.shThis builds the artifacts and publishes them to your local Maven repository (~/.m2/repository).
Add the dependency to your Kotlin Multiplatform or Android project:
// commonMain sourceSet dependencies
implementation("io.github.aughtone:charts:0.0.1")The library provides following components:
BarChartWithLegend
PercentageDial, a variant fixed to 0–100LineChartWithLegend
PieChartWithLegend
SimpleLineChart, SimpleBarChart and ArcProgressBar
ChartLegend can also be used on its own to place a legend elsewhere in your own layout.
Most of the components have arguments like:
Before using component the BarChartData has to be prepared:
val barChartData = BarChartData(
categories = listOf(
BarChartCategory(
name = "Bar Chart 1",
entries = listOf(
BarChartEntry(
x = "primary",
y = 17f,
color = Color.Yellow,
),
BarChartEntry(
x = "secondary",
y = 30f,
color = Color.Red,
),
)
),
BarChartCategory(
name = "Bar Chart 2",
entries = listOf(
BarChartEntry(
x = "primary",
y = -5f,
color = Color.Yellow,
),
BarChartEntry(
x = "secondary",
y = -24f,
color = Color.Red,
),
)
),
)
)BarChart(
data = barChartData,
config = BarChartConfig(
thickness = 14.dp,
cornerRadius = 7.dp,
),
modifier = Modifier.height(500.dp),
animation = ChartAnimation.Sequenced(),
)There is another component called BarChartWithLegend. It renders bar chart with legend.
Before using component the list of Bubble has to be prepared:
val bubbles = listOf(
Bubble(
name = "first",
value = 1.2f,
icon = Icons.Default.Album,
color = Color.Yellow
),
Bubble(
name = "second",
value = 4.6f,
icon = Icons.Default.House,
color = Color.Green
),
Bubble(
name = "third",
value = 6.9f,
icon = Icons.Default.Bed,
color = Color.Blue
),
)BubbleChart(
bubbles = bubbles,
modifier = Modifier.size(300.dp),
animation = ChartAnimation.Sequenced(),
)Dial(
value = 22,
minValue = -20,
maxValue = 50,
modifier = Modifier.fillMaxWidth(),
animation = ChartAnimation.Simple {
spring(
dampingRatio = Spring.DampingRatioMediumBouncy,
stiffness = Spring.StiffnessLow
)
},
config = DialConfig(
thickness = 20.dp,
roundCorners = true,
),
mainLabel = {
Column(
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(
text = "$it°C",
style = MaterialTheme.typography.h4,
color = Color.Yellow
)
Text(
text = "outside temperature",
style = MaterialTheme.typography.body2,
modifier = Modifier.padding(top = 12.dp)
)
}
}
)There is another component ProcentageDial. It accepts only one data argument percentage in [0-100] range.
GasBottle(
percentage = 75f,
modifier = Modifier.size(width = 200.dp, height = 300.dp),
animation = ChartAnimation.Simple {
spring(
dampingRatio = Spring.DampingRatioMediumBouncy,
stiffness = Spring.StiffnessVeryLow
)
}
)Before using component the LineChartData has to be prepared:
val lineData = remember {
LineChartData(
series = (1..3).map {
LineChartSeries(
dataName = "data $it",
lineColor = listOf(
Color.Yellow,
Color.Red,
Color.Blue,
)[it - 1],
listOfPoints = (1..10).map { point ->
LineChartPoint(
x = DateTime.now().minus(TimeSpan(point * 24 * 60 * 60 * 1000.0)).unixMillisLong,
y = (1..15).random().toFloat(),
)
}
)
},
)
}LineChart(
lineChartData = lineData,
modifier = Modifier.height(300.dp),
xAxisLabel = {
Text(
fontSize = 12.sp,
text = DateTime.fromUnix(it as Long).format("yyyy-MM-dd"),
textAlign = TextAlign.Center
)
},
overlayHeaderLabel = {
Text(
text = DateTime.fromUnix(it as Long).format("yyyy-MM-dd"),
style = MaterialTheme.typography.overline
)
},
animation = ChartAnimation.Sequenced()
)Before using component the list of PieChartData has to be prepared:
val data = listOf(
PieChartData(
name = "Data 1",
value = 10.0,
color = Color.Yellow,
),
PieChartData(
name = "Data 2",
value = 20.0,
color = Color.Green,
),
PieChartData(
name = "Data 3",
value = 30.0,
color = Color.Blue,
),
PieChartData(
name = "Data 4",
value = 40.0,
color = Color.Red,
)
)PieChart(
data = data,
modifier = Modifier.size(300.dp),
config = PieChartConfig(
thickness = 40.dp
),
)By default the thickness is Dp.Infinity, it means the chart will be fully filled.
Lightweight charts that take a plain list of values and no configuration object. They draw no axes, grid or labels, which makes them suited to sparklines and inline indicators rather than full charts. Unlike the charts above they read their default colors from MaterialTheme, not from LocalChartColors.
SimpleLineChart(
dataPoints = listOf(3f, 1f, 4f, 1f, 5f, 9f, 2f),
modifier = Modifier.fillMaxWidth().height(64.dp),
useCurvedLines = true,
)
SimpleBarChart(
dataPoints = listOf(3f, 1f, 4f, 1f, 5f, 9f, 2f),
modifier = Modifier.fillMaxWidth().height(64.dp),
)
ArcProgressBar(
progress = 0.72f,
modifier = Modifier.size(120.dp),
)With adaptToData = true (the default) the line and bar charts scale to the range of the values given; set it to false when the values are already normalised to 0f..1f. ArcProgressBar always takes progress in 0f..1f, and its arc can be swept elsewhere with startAngle and totalArcDegrees.
The easiest way to set the same colors for all charts is to provide ChartColors in the app theme.
private val chartColors = ChartColors(
primary = Color.Green,
grid = Color.LightGray,
surface = Color.White,
fullGasBottle = Color.Green,
emptyGasBottle = Color.Red,
overlayLine = Color.Magenta
)
@Composable
fun AppTheme(
darkTheme: Boolean = isSystemInDarkTheme(),
content: @Composable () -> Unit,
) {
CompositionLocalProvider(
// ...
LocalChartColors provides chartColors,
) {
MaterialTheme(
// ...
content = content,
)
}
}
There is also default ChartColors provided by the library. It uses the default color set from MaterialTheme.
LocalChartColors provides ChartDefaults.chartColors()Each chart has its own color set which can be used like:
BarChart(
data = barChartData,
colors = BarChartColors(grid = Color.LightGray, surface = Color.White)
)Also there is possibility to use ChartColors inside the specific chart:
BarChart(
data = barChartData,
colors = ChartColors(...).barChartColors,
)Apache License 2.0 — see LICENSE and NOTICE.md.
Most of the charts module is derived from compose-multiplatform-charts, Copyright (c) 2022 Netguru, which is licensed under the MIT License and remains under it — see LICENSE-MIT.md.
Chart composables for Kotlin Multiplatform projects. Targets Android, JVM/Desktop, iOS and JS.
[!WARNING] This library is alpha (
0.0.x), and its API is still being worked out. Composable signatures, config classes and the defaults objects may change between releases, and some changes will be breaking. Each one is listed in the changelog.
This library was originally forked from the compose-multiplatform-charts project, created and maintained by the team at Netguru.
Since the original project appears to no longer be actively maintained and reaching out went unanswered, we have forked the library to continue its development, support newer Kotlin Multiplatform environments, add new chart components, and prepare it for publishing.
The original code is licensed under the MIT License and remains under it — see LICENSE-MIT.md. This fork is licensed under the Apache License 2.0 — see LICENSE and NOTICE.md.
Go to the root directory and build the project, or run the local publish script:
./publish-local.shThis builds the artifacts and publishes them to your local Maven repository (~/.m2/repository).
Add the dependency to your Kotlin Multiplatform or Android project:
// commonMain sourceSet dependencies
implementation("io.github.aughtone:charts:0.0.1")The library provides following components:
BarChartWithLegend
PercentageDial, a variant fixed to 0–100LineChartWithLegend
PieChartWithLegend
SimpleLineChart, SimpleBarChart and ArcProgressBar
ChartLegend can also be used on its own to place a legend elsewhere in your own layout.
Most of the components have arguments like:
Before using component the BarChartData has to be prepared:
val barChartData = BarChartData(
categories = listOf(
BarChartCategory(
name = "Bar Chart 1",
entries = listOf(
BarChartEntry(
x = "primary",
y = 17f,
color = Color.Yellow,
),
BarChartEntry(
x = "secondary",
y = 30f,
color = Color.Red,
),
)
),
BarChartCategory(
name = "Bar Chart 2",
entries = listOf(
BarChartEntry(
x = "primary",
y = -5f,
color = Color.Yellow,
),
BarChartEntry(
x = "secondary",
y = -24f,
color = Color.Red,
),
)
),
)
)BarChart(
data = barChartData,
config = BarChartConfig(
thickness = 14.dp,
cornerRadius = 7.dp,
),
modifier = Modifier.height(500.dp),
animation = ChartAnimation.Sequenced(),
)There is another component called BarChartWithLegend. It renders bar chart with legend.
Before using component the list of Bubble has to be prepared:
val bubbles = listOf(
Bubble(
name = "first",
value = 1.2f,
icon = Icons.Default.Album,
color = Color.Yellow
),
Bubble(
name = "second",
value = 4.6f,
icon = Icons.Default.House,
color = Color.Green
),
Bubble(
name = "third",
value = 6.9f,
icon = Icons.Default.Bed,
color = Color.Blue
),
)BubbleChart(
bubbles = bubbles,
modifier = Modifier.size(300.dp),
animation = ChartAnimation.Sequenced(),
)Dial(
value = 22,
minValue = -20,
maxValue = 50,
modifier = Modifier.fillMaxWidth(),
animation = ChartAnimation.Simple {
spring(
dampingRatio = Spring.DampingRatioMediumBouncy,
stiffness = Spring.StiffnessLow
)
},
config = DialConfig(
thickness = 20.dp,
roundCorners = true,
),
mainLabel = {
Column(
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(
text = "$it°C",
style = MaterialTheme.typography.h4,
color = Color.Yellow
)
Text(
text = "outside temperature",
style = MaterialTheme.typography.body2,
modifier = Modifier.padding(top = 12.dp)
)
}
}
)There is another component ProcentageDial. It accepts only one data argument percentage in [0-100] range.
GasBottle(
percentage = 75f,
modifier = Modifier.size(width = 200.dp, height = 300.dp),
animation = ChartAnimation.Simple {
spring(
dampingRatio = Spring.DampingRatioMediumBouncy,
stiffness = Spring.StiffnessVeryLow
)
}
)Before using component the LineChartData has to be prepared:
val lineData = remember {
LineChartData(
series = (1..3).map {
LineChartSeries(
dataName = "data $it",
lineColor = listOf(
Color.Yellow,
Color.Red,
Color.Blue,
)[it - 1],
listOfPoints = (1..10).map { point ->
LineChartPoint(
x = DateTime.now().minus(TimeSpan(point * 24 * 60 * 60 * 1000.0)).unixMillisLong,
y = (1..15).random().toFloat(),
)
}
)
},
)
}LineChart(
lineChartData = lineData,
modifier = Modifier.height(300.dp),
xAxisLabel = {
Text(
fontSize = 12.sp,
text = DateTime.fromUnix(it as Long).format("yyyy-MM-dd"),
textAlign = TextAlign.Center
)
},
overlayHeaderLabel = {
Text(
text = DateTime.fromUnix(it as Long).format("yyyy-MM-dd"),
style = MaterialTheme.typography.overline
)
},
animation = ChartAnimation.Sequenced()
)Before using component the list of PieChartData has to be prepared:
val data = listOf(
PieChartData(
name = "Data 1",
value = 10.0,
color = Color.Yellow,
),
PieChartData(
name = "Data 2",
value = 20.0,
color = Color.Green,
),
PieChartData(
name = "Data 3",
value = 30.0,
color = Color.Blue,
),
PieChartData(
name = "Data 4",
value = 40.0,
color = Color.Red,
)
)PieChart(
data = data,
modifier = Modifier.size(300.dp),
config = PieChartConfig(
thickness = 40.dp
),
)By default the thickness is Dp.Infinity, it means the chart will be fully filled.
Lightweight charts that take a plain list of values and no configuration object. They draw no axes, grid or labels, which makes them suited to sparklines and inline indicators rather than full charts. Unlike the charts above they read their default colors from MaterialTheme, not from LocalChartColors.
SimpleLineChart(
dataPoints = listOf(3f, 1f, 4f, 1f, 5f, 9f, 2f),
modifier = Modifier.fillMaxWidth().height(64.dp),
useCurvedLines = true,
)
SimpleBarChart(
dataPoints = listOf(3f, 1f, 4f, 1f, 5f, 9f, 2f),
modifier = Modifier.fillMaxWidth().height(64.dp),
)
ArcProgressBar(
progress = 0.72f,
modifier = Modifier.size(120.dp),
)With adaptToData = true (the default) the line and bar charts scale to the range of the values given; set it to false when the values are already normalised to 0f..1f. ArcProgressBar always takes progress in 0f..1f, and its arc can be swept elsewhere with startAngle and totalArcDegrees.
The easiest way to set the same colors for all charts is to provide ChartColors in the app theme.
private val chartColors = ChartColors(
primary = Color.Green,
grid = Color.LightGray,
surface = Color.White,
fullGasBottle = Color.Green,
emptyGasBottle = Color.Red,
overlayLine = Color.Magenta
)
@Composable
fun AppTheme(
darkTheme: Boolean = isSystemInDarkTheme(),
content: @Composable () -> Unit,
) {
CompositionLocalProvider(
// ...
LocalChartColors provides chartColors,
) {
MaterialTheme(
// ...
content = content,
)
}
}
There is also default ChartColors provided by the library. It uses the default color set from MaterialTheme.
LocalChartColors provides ChartDefaults.chartColors()Each chart has its own color set which can be used like:
BarChart(
data = barChartData,
colors = BarChartColors(grid = Color.LightGray, surface = Color.White)
)Also there is possibility to use ChartColors inside the specific chart:
BarChart(
data = barChartData,
colors = ChartColors(...).barChartColors,
)Apache License 2.0 — see LICENSE and NOTICE.md.
Most of the charts module is derived from compose-multiplatform-charts, Copyright (c) 2022 Netguru, which is licensed under the MIT License and remains under it — see LICENSE-MIT.md.