Introducing Compose Multiplatform Charts: Solution for Seamless Charts Integration To APP

Yash Kalariya
Mobile Innovation Network
27 min readJul 24, 2024

In today’s data-driven landscape, visual representation is crucial for understanding trends and insights. Whether you’re visualising sales data, market trends, or performance metrics, users expect intuitive and insightful charts that offer clarity at a glance. However, creating a charting library that seamlessly integrates across different platforms can be complex. That’s where CMPCharts Library comes to the rescue!

What is Compose Multiplatform Charts Library?
Compose Multiplatform Charts Library is a robust charting solution crafted for Compose Multiplatform projects. It equips developers with the essential components to seamlessly integrate various chart types such as Line Chart, Bar Chart, Bubble Chart, Donut Chart, Pie Chart, Gauge Chart, Circular Chart, Area Chart, and Point Chart into their applications. This library ensures a unified user experience across both iOS and Android platforms, allowing developers to deliver intuitive and visually compelling data visualisations effortlessly.

Key Features

Cross-Platform Compatibility
With CMPCharts Library, you can confidently integrate a variety of charts into your Compose Multiplatform projects, ensuring consistent functionality and aesthetics across both iOS and Android platforms. Bid farewell to the complexities of platform-specific implementations and embrace a streamlined development process that focuses on delivering powerful data visualisation tools.

Comprehensive Chart Types
Explore a wide range of chart types to suit your data visualization needs. From dynamic Line Charts that depict trends over time to informative Bar Charts for categorical comparisons, our library offers versatile options to convey insights effectively.

Flexible Customisation
Tailor your charts to align perfectly with your app’s design language. Customise colors, styles, and animations to match your brand identity seamlessly. Enable or disable interactive features like tooltips or zoom functionalities to cater to diverse user preferences.

Intuitive Controls
Empower users with intuitive controls that enhance their interaction with charts. Enable features such as data point selection, axis toggling, and legend management for a personalised viewing experience. This library provides configurable options for controlling data display, enabling users to focus on specific data points or ranges effortlessly.

Getting Started

Getting started with Compose Multiplatform Charts is easy! Simply add the library as a dependency in your project’s `build.gradle.kts` file, and you’re good to go:

commonMain.dependencies {
implementation("network.chaintech:cmpcharts:1.0.0")
}

Once you’ve included the Charts library dependency, you can seamlessly integrate various chart types into your app using its composable functions.

Let’s go through each chart implementation in detailed manner and how can it be customised to suit one’s needs.

1) Line Chart

Customisation Parameters

CMPCharts library offers a wide range of customisation options to adjust the Line Charts:

linePlotDataData object containing the line plot data.

xAxisDataConfiguration data for the X-axis.

yAxisDataConfiguration data for the Y-axis.

isZoomAllowedFlag indicating whether zooming is allowed for the chart.

paddingTopPadding at the top of the chart container.

bottomPaddingPadding at the bottom of the chart container.

paddingRightPadding at the right side of the chart container.

containerPaddingEndPadding at the end (right for horizontal, bottom for vertical) of the chart container.

backgroundColorBackground color of the chart.

gridLinesUtility class for managing grid lines on the chart.

A. Straight Line Chart

@Composable
fun LineChartExample(pointsData: List<Point>) {
val textMeasurer = rememberTextMeasurer()
val steps = 5

val xAxisData = AxisData.Builder()
.fontFamily(
fontFamily = FontFamily(
Font(Res.font.Roboto_Regular, weight = FontWeight.Normal)
)
)
.axisStepSize(30.dp)
.topPadding(105.dp)
.axisLabelColor(font_color)
.axisLineColor(font_color)
.steps(pointsData.size - 1)
.labelData { i -> pointsData[i].x.toInt().toString() }
.labelAndAxisLinePadding(15.dp)
.build()

val yAxisData = AxisData.Builder()
.fontFamily(
fontFamily = FontFamily(
Font(Res.font.Roboto_Regular, weight = FontWeight.Normal)
)
)
.steps(steps)
.axisLabelColor(font_color)
.axisLineColor(font_color)
.labelAndAxisLinePadding(20.dp)
.labelData { i ->
// Add yMin to get the negative axis values to the scale
val yMin = pointsData.minOf { it.y }
val yMax = pointsData.maxOf { it.y }
val yScale = (yMax - yMin) / steps
((i * yScale) + yMin).formatToSinglePrecision()
}
.build()

val data = LineChartData(
linePlotData = LinePlotData(
lines = listOf(
Line(
dataPoints = pointsData,
lineStyle = LineStyle(color = purple_dark),
intersectionPoint = IntersectionPoint(color = green_dark),
selectionHighlightPoint = SelectionHighlightPoint(color = magenta_dark),
shadowUnderLine = ShadowUnderLine(),
selectionHighlightPopUp = SelectionHighlightPopUp(
textMeasurer = textMeasurer,
backgroundColor = magenta_dark,
labelColor = white_color,
labelTypeface = FontWeight.Bold
)
)
)
),
xAxisData = xAxisData,
yAxisData = yAxisData,
gridLines = GridLinesUtil(color = gray_light)
)

LineChart(
modifier = Modifier
.fillMaxWidth()
.height(300.dp),
lineChartData = data
)
}

B. Grid Line Chart

@Composable
fun SingleLineChartWithGridLines(pointsData: List<Point>) {
val textMeasurer = rememberTextMeasurer()
val steps = 5
val xAxisData = AxisData.Builder()
.fontFamily(
fontFamily = FontFamily(
Font(Res.font.Roboto_Regular, weight = FontWeight.Normal)
)
)
.axisStepSize(30.dp)
.topPadding(105.dp)
.axisLabelColor(font_color)
.axisLineColor(font_color)
.steps(pointsData.size - 1)
.labelData { i -> pointsData[i].x.toInt().toString() }
.labelAndAxisLinePadding(15.dp)
.build()
val yAxisData = AxisData.Builder()
.fontFamily(
fontFamily = FontFamily(
Font(Res.font.Roboto_Regular, weight = FontWeight.Normal)
)
)
.steps(steps)
.axisLabelColor(font_color)
.axisLineColor(font_color)
.labelAndAxisLinePadding(20.dp)
.labelData { i ->
val yMin = pointsData.minOf { it.y }
val yMax = pointsData.maxOf { it.y }
val yScale = (yMax - yMin) / steps
((i * yScale) + yMin).formatToSinglePrecision()
}.build()
val data = LineChartData(
linePlotData = LinePlotData(
lines = listOf(
Line(
dataPoints = pointsData,
LineStyle(
color = purple_dark
),
IntersectionPoint(
color = green_dark
),
SelectionHighlightPoint(
color = magenta_dark
),
ShadowUnderLine(),
SelectionHighlightPopUp(
textMeasurer = textMeasurer,
backgroundColor = magenta_dark,
labelColor = white_color,
labelTypeface = FontWeight.Bold
)
)
)
),
xAxisData = xAxisData,
yAxisData = yAxisData,
gridLines = GridLinesUtil(color = gray_light)
)
LineChart(
modifier = Modifier
.fillMaxWidth()
.height(300.dp),
lineChartData = data
)
}

C. Dashed Line Chart

@Composable
fun DashedLineChart(pointsData: List<Point>) {
val textMeasurer = rememberTextMeasurer()
val steps = 10
val xAxisData = AxisData.Builder()
.fontFamily(
fontFamily = FontFamily(
Font(Res.font.Roboto_Regular, weight = FontWeight.Normal)
)
)
.axisStepSize(40.dp)
.steps(pointsData.size - 1)
.labelData { i -> i.toString() }
.labelAndAxisLinePadding(15.dp)
.axisLabelColor(font_color)
.axisLineColor(font_color)
.build()
val yAxisData = AxisData.Builder()
.fontFamily(
fontFamily = FontFamily(
Font(Res.font.Roboto_Regular, weight = FontWeight.Normal)
)
)
.steps(steps)
.labelData { i ->
val yMin = pointsData.minOf { it.y }
val yMax = pointsData.maxOf { it.y }
val yScale = (yMax - yMin) / steps
((i * yScale) + yMin).formatToSinglePrecision()
}
.axisLabelColor(font_color)
.axisLineColor(font_color)
.labelAndAxisLinePadding(20.dp)
.build()
val data = LineChartData(
linePlotData = LinePlotData(
lines = listOf(
Line(
dataPoints = pointsData,
lineStyle = LineStyle(
lineType = LineType.SmoothCurve(isDotted = true),
color = pink_dark
),
shadowUnderLine = ShadowUnderLine(
brush = Brush.verticalGradient(
listOf(
pink_dark,
transparent_color
)
), alpha = 0.3f
),
selectionHighlightPoint = SelectionHighlightPoint(
color = pink_dark
),
selectionHighlightPopUp = SelectionHighlightPopUp(
backgroundColor = pink_dark,
labelColor = white_color,
labelTypeface = FontWeight.Bold,
textMeasurer = textMeasurer
)
)
)
),
xAxisData = xAxisData,
yAxisData = yAxisData
)
LineChart(
modifier = Modifier
.fillMaxWidth()
.height(300.dp),
lineChartData = data
)
}

D. Multi Color Line Chart

@Composable
fun MultipleToneLineChart(pointsData: List<Point>) {
val textMeasurer = rememberTextMeasurer()
val xAxisData = AxisData.Builder()
.fontFamily(
fontFamily = FontFamily(
Font(Res.font.Roboto_Regular, weight = FontWeight.Normal)
)
)
.axisStepSize(40.dp)
.steps(pointsData.size - 1)
.labelData { i -> (1900 + i).toString() }
.axisLabelAngle(20f)
.labelAndAxisLinePadding(15.dp)
.axisLabelColor(font_color)
.axisLineColor(font_color)
.typeFace(FontWeight.Bold)
.build()
val yAxisData = AxisData.Builder()
.fontFamily(
fontFamily = FontFamily(
Font(Res.font.Roboto_Regular, weight = FontWeight.Normal)
)
)
.steps(10)
.labelData { i -> "${(i * 20)}k" }
.labelAndAxisLinePadding(30.dp)
.axisLabelColor(font_color)
.axisLineColor(font_color)
.typeFace(FontWeight.Bold)
.build()
val data = LineChartData(
linePlotData = LinePlotData(
lines = listOf(
Line(
dataPoints = pointsData,
lineStyle = LineStyle(lineType = LineType.Straight(), color = pink_dark),
intersectionPoint = IntersectionPoint(color = blue_dark),
selectionHighlightPopUp = SelectionHighlightPopUp(
popUpLabel = { x, y ->
val xLabel = "x : ${(1900 + x).toInt()} "
val yLabel = "y : ${y.formatNumber()}"
"$xLabel $yLabel"
},
textMeasurer = textMeasurer,
backgroundColor = magenta_dark,
labelColor = white_color,
labelTypeface = FontWeight.Bold
)
), Line(
dataPoints = pointsData.subList(0, 10),
lineStyle = LineStyle(lineType = LineType.Straight(), color = blue_dark),
intersectionPoint = IntersectionPoint(color = gray_dark),
selectionHighlightPopUp = SelectionHighlightPopUp(
popUpLabel = { x, y ->
val xLabel = "x : ${(1900 + x).toInt()} "
val yLabel = "y : ${y.formatNumber()}"
"$xLabel $yLabel"
},
textMeasurer = textMeasurer,
backgroundColor = pink_dark,
labelColor = white_color,
labelTypeface = FontWeight.Bold
)
), Line(
dataPoints = pointsData.subList(15, 30),
lineStyle = LineStyle(lineType = LineType.Straight(), color = purple_dark),
intersectionPoint = IntersectionPoint(color = green_dark),
selectionHighlightPopUp = SelectionHighlightPopUp(
popUpLabel = { x, y ->
val xLabel = "x : ${(1900 + x).toInt()} "
val yLabel = "y : ${y.formatNumber()}"
"$xLabel $yLabel"
},
textMeasurer = textMeasurer,
backgroundColor = pink_dark,
labelColor = white_color,
labelTypeface = FontWeight.Bold
)
)
)
),
xAxisData = xAxisData,
yAxisData = yAxisData
)
LineChart(
modifier = Modifier
.fillMaxWidth()
.height(300.dp),
lineChartData = data
)
}

E. Multiple Lines Line Chart

@Composable
fun CombinedLineChart(pointsData: List<Point>) {
val textMeasurer = rememberTextMeasurer()
val steps = 5
val xAxisData = AxisData.Builder()
.fontFamily(
fontFamily = FontFamily(
Font(Res.font.Roboto_Regular, weight = FontWeight.Normal)
)
)
.axisStepSize(30.dp)
.steps(pointsData.size - 1)
.labelData { i -> i.toString() }
.labelAndAxisLinePadding(15.dp)
.axisLabelColor(font_color)
.axisLineColor(font_color)
.build()
val yAxisData = AxisData.Builder()
.fontFamily(
fontFamily = FontFamily(
Font(Res.font.Roboto_Regular, weight = FontWeight.Normal)
)
)
.steps(steps)
.labelAndAxisLinePadding(20.dp)
.labelData { i ->
val yMin = pointsData.minOf { it.y }
val yMax = pointsData.maxOf { it.y }
val yScale = (yMax - yMin) / steps
((i * yScale) + yMin).formatToSinglePrecision()
}.build()
val colorPaletteList = listOf<Color>(magenta_dark, green_dark, purple_dark, blue_dark)
val legendsConfig = LegendsConfig(
legendLabelList = getLegendsLabelData(colorPaletteList),
gridColumnCount = 4
)
val data = LineChartData(
linePlotData = LinePlotData(
lines = listOf(
Line(
dataPoints = pointsData,
lineStyle = LineStyle(
lineType = LineType.SmoothCurve(isDotted = true),
color = colorPaletteList.first()
),
shadowUnderLine = ShadowUnderLine(
brush = Brush.verticalGradient(
listOf(
magenta_dark,
transparent_color
)
), alpha = 0.3f
),
selectionHighlightPoint = SelectionHighlightPoint(
color = pink_dark
),
selectionHighlightPopUp = SelectionHighlightPopUp(
backgroundColor = pink_dark,
labelColor = white_color,
labelTypeface = FontWeight.Bold,
textMeasurer = textMeasurer
)
),
Line(
dataPoints = pointsData.subList(10, 20),
lineStyle = LineStyle(
lineType = LineType.SmoothCurve(),
color = colorPaletteList[1]
),
intersectionPoint = IntersectionPoint(color = Color.Red),
selectionHighlightPopUp = SelectionHighlightPopUp(
popUpLabel = { x, y ->
val xLabel = "x : ${(1900 + x).toInt()} "
val yLabel = "y : ${y.formatNumber()}"
"$xLabel $yLabel"
},
textMeasurer = textMeasurer,
backgroundColor = pink_dark,
labelColor = white_color,
labelTypeface = FontWeight.Bold
)
),
Line(
dataPoints = getLineChartData(
20,
start = 0,
maxRange = 50
),
LineStyle(color = colorPaletteList[2]),
IntersectionPoint(),
SelectionHighlightPoint(),
shadowUnderLine = ShadowUnderLine(
brush = Brush.verticalGradient(
listOf(
green_dark,
transparent_color
)
), alpha = 0.5f
),
SelectionHighlightPopUp(
textMeasurer = textMeasurer,
backgroundColor = pink_dark,
labelColor = white_color,
labelTypeface = FontWeight.Bold
)
),
Line(
dataPoints = pointsData.subList(10, 20),
LineStyle(color = colorPaletteList[3]),
IntersectionPoint(),
SelectionHighlightPoint(),
ShadowUnderLine(),
SelectionHighlightPopUp(
textMeasurer = textMeasurer,
backgroundColor = pink_dark,
labelColor = white_color,
labelTypeface = FontWeight.Bold
)
)
)
),
xAxisData = xAxisData,
yAxisData = yAxisData,
gridLines = GridLinesUtil()
)

Column(modifier = Modifier.height(400.dp)) {
LineChart(
modifier = Modifier
.fillMaxWidth()
.height(300.dp),
lineChartData = data
)
Legends(
legendsConfig = legendsConfig
)
}
}

F. Multiple Lines Line Chart with different styles

@Composable
fun CombinedLineChartWithBackground(pointsData: List<Point>) {
val textMeasurer = rememberTextMeasurer()
val steps = 5
val xAxisData = AxisData.Builder()
.fontFamily(
fontFamily = FontFamily(
Font(Res.font.Roboto_Regular, weight = FontWeight.Normal)
)
)
.axisStepSize(30.dp)
.steps(pointsData.size - 1)
.backgroundColor(yellow_light)
.axisLabelColor(font_color)
.axisLineColor(font_color)
.labelData { i -> i.toString() }
.labelAndAxisLinePadding(15.dp)
.build()
val yAxisData = AxisData.Builder()
.fontFamily(
fontFamily = FontFamily(
Font(Res.font.Roboto_Regular, weight = FontWeight.Normal)
)
)
.steps(steps)
.backgroundColor(yellow_light)
.labelAndAxisLinePadding(20.dp)
.axisLabelColor(font_color)
.axisLineColor(font_color)
.labelData { i ->
val yMin = pointsData.minOf { it.y }
val yMax = pointsData.maxOf { it.y }
val yScale = (yMax - yMin) / steps
((i * yScale) + yMin).formatToSinglePrecision()
}.build()
val colorPaletteList = listOf<Color>(magenta_dark, green_dark, purple_dark, blue_dark)
val legendsConfig = LegendsConfig(
legendLabelList = getLegendsLabelData(colorPaletteList),
gridColumnCount = 4
)
val data = LineChartData(
linePlotData = LinePlotData(
lines = listOf(
Line(
dataPoints = pointsData,
lineStyle = LineStyle(
lineType = LineType.SmoothCurve(isDotted = true),
color = colorPaletteList.first()
),
shadowUnderLine = ShadowUnderLine(
brush = Brush.verticalGradient(
listOf(
magenta_dark,
transparent_color
)
), alpha = 0.3f
),
selectionHighlightPoint = SelectionHighlightPoint(
color = pink_dark
),
selectionHighlightPopUp = SelectionHighlightPopUp(
backgroundColor = pink_dark,
labelColor = white_color,
labelTypeface = FontWeight.Bold,
textMeasurer = textMeasurer
)
),
Line(
dataPoints = pointsData.subList(10, 20),
lineStyle = LineStyle(
lineType = LineType.SmoothCurve(),
color = colorPaletteList[1]
),
intersectionPoint = IntersectionPoint(color = Color.Red),
selectionHighlightPopUp = SelectionHighlightPopUp(
popUpLabel = { x, y ->
val xLabel = "x : ${(1900 + x).toInt()} "
val yLabel = "y : ${y.formatNumber()}"
"$xLabel $yLabel"
},
textMeasurer = textMeasurer,
backgroundColor = pink_dark,
labelColor = white_color,
labelTypeface = FontWeight.Bold
)
),
Line(
dataPoints = getLineChartData(
20,
start = 0,
maxRange = 50
),
LineStyle(color = colorPaletteList[2]),
IntersectionPoint(),
SelectionHighlightPoint(),
shadowUnderLine = ShadowUnderLine(
brush = Brush.verticalGradient(
listOf(
blue_dark,
transparent_color
)
), alpha = 0.5f
),
SelectionHighlightPopUp(
textMeasurer = textMeasurer,
backgroundColor = pink_dark,
labelColor = white_color,
labelTypeface = FontWeight.Bold,
)
),
Line(
dataPoints = pointsData.subList(10, 20),
LineStyle(color = colorPaletteList[3]),
IntersectionPoint(),
SelectionHighlightPoint(),
ShadowUnderLine(),
SelectionHighlightPopUp(
textMeasurer = textMeasurer,
backgroundColor = pink_dark,
labelColor = white_color,
labelTypeface = FontWeight.Bold,
)
)
)
),
xAxisData = xAxisData,
yAxisData = yAxisData,
gridLines = GridLinesUtil(
color = blue_light,
lineWidth = 0.5.dp
),
backgroundColor = yellow_light
)

Column(
modifier = Modifier
.height(400.dp)
) {
LineChart(
modifier = Modifier
.fillMaxWidth()
.height(300.dp),
lineChartData = data
)
Legends(
legendsConfig = legendsConfig
)
}
}

2) Bar Chart

Customisation Parameters

chartDataList of data objects representing each bar in the chart.

xAxisDataConfiguration data for the X-axis.

yAxisDataConfiguration data for the Y-axis.

backgroundColorBackground color of the chart.

horizontalExtraSpaceAdditional horizontal space allocated beyond the chart's content.

barStyleStyle settings for the bars in the chart, including colors and appearance.

paddingEndPadding at the end (right for vertical, bottom for horizontal) of the chart.

paddingTopPadding at the top of the chart.

tapPaddingPadding for tap interactions on the chart, enhancing usability.

barChartTypeType of bar chart (VERTICAL or HORIZONTAL), defining its orientation.

drawBarFunction for custom drawing of bars, allowing advanced customization.

A. Simple Bar Chart

@Composable
fun BarChartExample() {
val maxRange = 50
val barData = getBarChartData(50, maxRange, BarChartType.VERTICAL, DataCategoryOptions())
val yStepSize = 10

val xAxisData = AxisData.Builder()
.fontFamily(
fontFamily = FontFamily(
Font(Res.font.Roboto_Regular, weight = FontWeight.Normal)
)
)
.axisStepSize(30.dp)
.steps(barData.size - 1)
.bottomPadding(40.dp)
.axisLabelAngle(20f)
.startDrawPadding(48.dp)
.axisLabelColor(font_color)
.axisLineColor(font_color)
.labelData { index -> barData[index].label }
.build()
val yAxisData = AxisData.Builder()
.fontFamily(
fontFamily = FontFamily(
Font(Res.font.Roboto_Regular, weight = FontWeight.Normal)
)
)
.steps(yStepSize)
.labelAndAxisLinePadding(20.dp)
.axisOffset(20.dp)
.axisLabelColor(font_color)
.axisLineColor(font_color)
.labelData { index -> (index * (maxRange / yStepSize)).toString() }
.build()
val barChartData = BarChartData(
chartData = barData,
xAxisData = xAxisData,
yAxisData = yAxisData,
barStyle = BarStyle(
cornerRadius = 5.dp,
paddingBetweenBars = 20.dp,
barWidth = 25.dp,
selectionHighlightData = SelectionHighlightData(
highlightBarColor = gray_light,
highlightTextColor = white_color,
highlightTextTypeface = FontWeight.Bold,
highlightTextBackgroundColor = magenta_dark,
popUpLabel = { _, y -> " Value : $y " }
)
),
horizontalExtraSpace = 10.dp,
)
BarChart(modifier = Modifier.height(350.dp), barChartData = barChartData)
}

B. Gradient Bar Chart

@Composable
fun BarChartWithGradientBars() {
val maxRange = 100
val barData = getGradientBarChartData(50, 100)
val yStepSize = 10
val xAxisData = AxisData.Builder()
.fontFamily(
fontFamily = FontFamily(
Font(Res.font.Roboto_Regular, weight = FontWeight.Normal)
)
)
.axisStepSize(30.dp)
.steps(barData.size - 1)
.bottomPadding(40.dp)
.axisLabelAngle(20f)
.startDrawPadding(48.dp)
.axisLabelColor(font_color)
.axisLineColor(font_color)
.labelData { index -> barData[index].label }
.build()
val yAxisData = AxisData.Builder()
.fontFamily(
fontFamily = FontFamily(
Font(Res.font.Roboto_Regular, weight = FontWeight.Normal)
)
)
.steps(yStepSize)
.labelAndAxisLinePadding(20.dp)
.axisOffset(20.dp)
.axisLabelColor(font_color)
.axisLineColor(font_color)
.labelData { index -> (index * (maxRange / yStepSize)).toString() }
.build()
val barChartData = BarChartData(
chartData = barData,
xAxisData = xAxisData,
yAxisData = yAxisData,
barStyle = BarStyle(paddingBetweenBars = 20.dp,
barWidth = 35.dp,
isGradientEnabled = true,
selectionHighlightData = SelectionHighlightData(
highlightBarColor = gray_light,
highlightTextColor = white_color,
highlightTextTypeface = FontWeight.Bold,
highlightTextBackgroundColor = magenta_dark,
popUpLabel = { _, y -> " Value : $y " }
)),
horizontalExtraSpace = 20.dp
)
BarChart(modifier = Modifier.height(350.dp), barChartData = barChartData)
}

C. Bar Chart With Background Color

@Composable
fun BarChartWithBackgroundColor() {
val maxRange = 100
val backgroundColor = gray_light
val barData = getBarChartData(50, 100, BarChartType.VERTICAL, DataCategoryOptions())
val yStepSize = 10
val xAxisData = AxisData.Builder()
.fontFamily(
fontFamily = FontFamily(
Font(Res.font.Roboto_Regular, weight = FontWeight.Normal)
)
)
.axisStepSize(30.dp)
.steps(barData.size - 1)
.bottomPadding(40.dp)
.startDrawPadding(48.dp)
.axisLabelAngle(20f)
.axisLabelColor(font_color)
.axisLineColor(font_color)
.labelData { index -> barData[index].label }
.backgroundColor(backgroundColor)
.build()
val yAxisData = AxisData.Builder()
.fontFamily(
fontFamily = FontFamily(
Font(Res.font.Roboto_Regular, weight = FontWeight.Normal)
)
)
.steps(yStepSize)
.labelAndAxisLinePadding(20.dp)
.axisOffset(20.dp)
.backgroundColor(backgroundColor)
.axisLabelColor(font_color)
.axisLineColor(font_color)
.labelData { index -> (index * (maxRange / yStepSize)).toString() }
.build()
val barChartData = BarChartData(
chartData = barData,
xAxisData = xAxisData,
yAxisData = yAxisData,
barStyle = BarStyle(paddingBetweenBars = 20.dp,
barWidth = 35.dp,
selectionHighlightData = SelectionHighlightData(
highlightBarColor = gray_light,
highlightTextColor = white_color,
highlightTextTypeface = FontWeight.Bold,
highlightTextBackgroundColor = magenta_dark,
popUpLabel = { _, y -> " Value : $y " }
)),
horizontalExtraSpace = 20.dp,
backgroundColor = backgroundColor
)
BarChart(modifier = Modifier.height(350.dp), barChartData = barChartData)
}

D. Horizontal Bar Chart

@Composable
fun HorizontalBarChart() {
val maxRange = 30
val barData =
getBarChartData(
10,
maxRange,
BarChartType.HORIZONTAL,
DataCategoryOptions(isDataCategoryInYAxis = true)
)
val xStepSize = 10

val xAxisData = AxisData.Builder()
.fontFamily(
fontFamily = FontFamily(
Font(Res.font.Roboto_Regular, weight = FontWeight.Normal)
)
)
.steps(xStepSize)
.bottomPadding(12.dp)
.endPadding(40.dp)
.axisLabelColor(font_color)
.axisLineColor(font_color)
.labelData { index -> (index * (maxRange / xStepSize)).toString() }
.build()
val yAxisData = AxisData.Builder()
.fontFamily(
fontFamily = FontFamily(
Font(Res.font.Roboto_Regular, weight = FontWeight.Normal)
)
)
.axisStepSize(30.dp)
.steps(barData.size - 1)
.labelAndAxisLinePadding(20.dp)
.axisOffset(20.dp)
.axisLabelColor(font_color)
.axisLineColor(font_color)
.setDataCategoryOptions(
DataCategoryOptions(
isDataCategoryInYAxis = true,
isDataCategoryStartFromBottom = false
)
)
.startDrawPadding(48.dp)
.labelData { index -> barData[index].label }
.build()
val barChartData = BarChartData(
chartData = barData,
xAxisData = xAxisData,
yAxisData = yAxisData,
barStyle = BarStyle(
isGradientEnabled = false,
paddingBetweenBars = 20.dp,
barWidth = 35.dp,
selectionHighlightData = SelectionHighlightData(
highlightBarColor = gray_light,
highlightTextColor = white_color,
highlightTextTypeface = FontWeight.Bold,
highlightTextBackgroundColor = magenta_dark,
popUpLabel = { _, y -> " Value : $y " }
),
),
horizontalExtraSpace = 20.dp,
barChartType = BarChartType.HORIZONTAL
)
BarChart(
modifier = Modifier.height(350.dp),
barChartData = barChartData
)
}

E. Grouped Bar Chart

@Composable
fun VerticalGroupBarChart() {
val maxRange = 100
val barSize = 3
val groupBarData = getGroupBarChartData(50, maxRange, barSize)
val yStepSize = 10
val xAxisData = AxisData.Builder()
.fontFamily(
fontFamily = FontFamily(
Font(Res.font.Roboto_Regular, weight = FontWeight.Normal)
)
)
.axisStepSize(30.dp)
.bottomPadding(5.dp)
.startDrawPadding(48.dp)
.axisLabelColor(font_color)
.axisLineColor(font_color)
.labelData { index -> index.toString() }
.build()
val yAxisData = AxisData.Builder()
.fontFamily(
fontFamily = FontFamily(
Font(Res.font.Roboto_Regular, weight = FontWeight.Normal)
)
)
.steps(yStepSize)
.labelAndAxisLinePadding(20.dp)
.axisOffset(20.dp)
.axisLabelColor(font_color)
.axisLineColor(font_color)
.labelData { index -> (index * (maxRange / yStepSize)).toString() }
.build()
val colorPaletteList = getColorPaletteList1()
val legendsConfig = LegendsConfig(
legendLabelList = getLegendsLabelDataBarChart(colorPaletteList),
gridColumnCount = 3
)
val groupBarPlotData = BarPlotData(
groupBarList = groupBarData,
barStyle = BarStyle(barWidth = 35.dp),
barColorPaletteList = colorPaletteList
)
val groupBarChartData = GroupBarChartData(
barPlotData = groupBarPlotData,
xAxisData = xAxisData,
yAxisData = yAxisData,
groupSeparatorConfig = GroupSeparatorConfig(0.dp)
)
Column(
Modifier
.height(450.dp)
) {
GroupBarChart(
modifier = Modifier
.height(400.dp),
groupBarChartData = groupBarChartData
)
Legends(
legendsConfig = legendsConfig
)
}
}

F. Stacked Bar Chart

@Composable
fun VerticalStackedBarChart() {
val barSize = 3
val listSize = 10
val groupBarData = getGroupBarChartData(listSize, 100, barSize)
val yStepSize = 10
val xAxisData = AxisData.Builder()
.fontFamily(
fontFamily = FontFamily(
Font(Res.font.Roboto_Regular, weight = FontWeight.Normal)
)
)
.axisStepSize(30.dp)
.steps(listSize - 1)
.startDrawPadding(48.dp)
.axisLabelColor(font_color)
.axisLineColor(font_color)
.labelData { index -> "C $index" }
.build()
val yAxisData = AxisData.Builder()
.fontFamily(
fontFamily = FontFamily(
Font(Res.font.Roboto_Regular, weight = FontWeight.Normal)
)
)
.steps(yStepSize)
.labelAndAxisLinePadding(20.dp)
.axisOffset(20.dp)
.axisLabelColor(font_color)
.axisLineColor(font_color)
.labelData { index ->
val valueList = mutableListOf<Float>()
groupBarData.map { groupBar ->
var yMax = 0f
groupBar.barList.forEach {
yMax += it.point.y
}
valueList.add(yMax)
}
val maxElementInYAxis = getMaxElementInYAxis(valueList.maxOrNull() ?: 0f, yStepSize)

(index * (maxElementInYAxis / yStepSize)).toString()
}
.topPadding(36.dp)
.build()
val colorPaletteList = getColorPaletteList2()
val legendsConfig = LegendsConfig(
legendLabelList = getLegendsLabelDataBarChart(colorPaletteList),
gridColumnCount = 3
)
val groupBarPlotData = BarPlotData(
groupBarList = groupBarData,
barStyle = BarStyle(
barWidth = 35.dp,
selectionHighlightData = SelectionHighlightData(
isHighlightFullBar = true,
groupBarPopUpLabel = { name, value ->
"Name : C$name Value : ${value.formatNumber()}"
}
)
),
barColorPaletteList = colorPaletteList
)
val groupBarChartData = GroupBarChartData(
barPlotData = groupBarPlotData,
xAxisData = xAxisData,
yAxisData = yAxisData,
paddingBetweenStackedBars = 4.dp,
drawBar = { drawScope, barChartData, barStyle, drawOffset, height, barIndex ->
with(drawScope) {
drawRect(
color = colorPaletteList[barIndex],
topLeft = drawOffset,
size = Size(barStyle.barWidth.toPx(), height),
style = barStyle.barDrawStyle,
blendMode = barStyle.barBlendMode
)
}
}
)
Column(
Modifier
.height(500.dp)
) {
StackedBarChart(
modifier = Modifier
.height(400.dp),
groupBarChartData = groupBarChartData
)
Legends(
legendsConfig = legendsConfig
)
}
}

3) Bubble Chart

Customisation Parameters

bubblesList of bubble data points to be displayed on the chart.

maximumBubbleRadiusMaximum radius of bubbles in the chart.

xAxisDataConfiguration data for the X-axis.

yAxisDataConfiguration data for the Y-axis.

isZoomAllowedFlag indicating whether zooming functionality is allowed in the chart.

paddingTopPadding at the top of the chart.

bottomPaddingPadding at the bottom of the chart.

paddingRightPadding at the right side of the chart.

containerPaddingEndPadding at the end of the chart container.

backgroundColorBackground color of the chart.

gridLinesUtility class for rendering grid lines on the chart, if provided.

A. Solid Bubble Chart

@Composable
fun BubbleChartExample(pointsData: List<Point>) {
val steps = 5
val textMeasurer = rememberTextMeasurer()
val xAxisData = AxisData.Builder()
.fontFamily(
fontFamily = FontFamily(
Font(Res.font.Roboto_Regular, weight = FontWeight.Normal)
)
)
.axisLineColor(lineColor = font_color)
.axisStepSize(30.dp)
.steps(pointsData.size - 1)
.labelData { i -> pointsData[i].x.toInt().toString() }
.labelAndAxisLinePadding(15.dp)
.build()

val yAxisData = AxisData.Builder()
.fontFamily(
fontFamily = FontFamily(
Font(Res.font.Roboto_Regular, weight = FontWeight.Normal)
)
)
.axisLineColor(lineColor = font_color)
.steps(steps)
.labelAndAxisLinePadding(15.dp)
.labelData { i ->
val yMin = pointsData.minOf { it.y }
val yMax = pointsData.maxOf { it.y }
val yScale = (yMax - yMin) / steps
((i * yScale) + yMin).formatToSinglePrecision()
}.build()

val data = BubbleChartData(
getBubbleChartDataWithSolidStyle(points = pointsData, textMeasurer = textMeasurer),
xAxisData = xAxisData,
yAxisData = yAxisData,
gridLines = GridLinesUtil()
)

BubbleChart(
modifier = Modifier
.fillMaxWidth()
.height(500.dp),
bubbleChartData = data
)
}

B. Gradient Bubble Chart

@Composable
fun GradientBubbleChart(pointsData: List<Point>) {
val steps = 5
val textMeasurer = rememberTextMeasurer()
val xAxisData = AxisData.Builder()
.fontFamily(
fontFamily = FontFamily(
Font(Res.font.Roboto_Regular, weight = FontWeight.Normal)
)
)
.axisLineColor(lineColor = font_color)
.axisStepSize(30.dp)
.steps(pointsData.size - 1)
.labelData { i -> pointsData[i].x.toInt().toString() }
.labelAndAxisLinePadding(15.dp)
.build()

val yAxisData = AxisData.Builder()
.fontFamily(
fontFamily = FontFamily(
Font(Res.font.Roboto_Regular, weight = FontWeight.Normal)
),
)
.axisLineColor(lineColor = font_color)
.steps(steps)
.labelAndAxisLinePadding(15.dp)
.labelData { i ->
// Add yMin to get the negative axis values to the scale
val yMin = pointsData.minOf { it.y }
val yMax = pointsData.maxOf { it.y }
val yScale = (yMax - yMin) / steps
((i * yScale) + yMin).formatToSinglePrecision()
}.build()

val data = BubbleChartData(
getBubbleChartDataWithGradientStyle(points = pointsData, textMeasurer = textMeasurer),
xAxisData = xAxisData,
yAxisData = yAxisData,
gridLines = GridLinesUtil()
)

BubbleChart(
modifier = Modifier
.fillMaxWidth()
.height(500.dp),
bubbleChartData = data
)
}

4) Donut Chart

Customisation Parameters

startAngleStarting angle for the first slice of the pie chart, in degrees.

showSliceLabelsFlag indicating whether slice labels should be displayed.

sliceLabelTextSizeText size of the slice labels.

sliceLabelTextColorText color of the slice labels.

sliceLabelTypefaceTypeface (font weight) of the slice labels.

isAnimationEnableFlag indicating whether animation is enabled for the pie chart.

animationDurationDuration of the animation in milliseconds. Minimum value is 1

strokeWidthWidth of the stroke around each slice in the pie chart.

labelFontSizeFont size of additional labels (e.g., percentage labels).

labelFontWeightFont weight of additional labels.

labelVisibleFlag indicating whether additional labels are visible.

fontFamilyFont family for the text in the chart.

labelTypeType of label to display (e.g., percentage or custom).

labelColorColor of additional labels.

labelColorTypeType of color to use for labels (e.g., specified or automatic).

backgroundColorBackground color of the pie chart.

activeSliceAlphaAlpha value (transparency) of active (selected) slices.

inActiveSliceAlphaAlpha value (transparency) of inactive (unselected) slices.

isEllipsizeEnabledFlag indicating whether text ellipsization is enabled for slice labels.

sliceMinTextWidthToEllipsizeMinimum width for slice label text before ellipsization is applied.

chartPaddingPadding around the pie chart.

isSumVisibleFlag indicating whether a sum value is visible in the chart.

sumUnitUnit of measurement for the sum value, if visible.

isClickOnSliceEnabledFlag indicating whether clicking on slices is enabled for interaction.

A. Simple Donut Chart

@Composable
fun SimpleDonutChart() {
val data = getDonutChartData()
val pieChartConfig =
PieChartConfig(
labelVisible = true,
strokeWidth = 120f,
labelColor = font_color,
activeSliceAlpha = .9f,
isEllipsizeEnabled = true,
fontFamily = FontFamily(
Font(Res.font.Roboto_Medium, weight = FontWeight.Normal)
),
labelFontWeight = FontWeight.Bold,
isAnimationEnable = true,
chartPadding = 25,
labelFontSize = 42.sp,
)
Column(
modifier = Modifier
.fillMaxWidth()
.height(500.dp)
) {
Legends(
legendsConfig = getLegendsConfigFromPieChartDataForDonutChart(
pieChartData = data,
3
)
)
DonutPieChart(
modifier = Modifier
.fillMaxWidth()
.height(400.dp),
data,
pieChartConfig
) { slice ->
//Custom event on slice tap
}
}
}

B. Multiple Small Donut Chart

@Composable
fun MultipleSmallDonutCharts() {
val data = getDonutChartData()
val firstPieChartConfig =
PieChartConfig(
labelVisible = true,
strokeWidth = 50f,
labelColor = font_color,
fontFamily = FontFamily(
Font(Res.font.Roboto_Medium, weight = FontWeight.Normal)
),
backgroundColor = blue_light,
activeSliceAlpha = .9f,
isEllipsizeEnabled = true,
labelFontWeight = FontWeight.Bold,
isAnimationEnable = true,
chartPadding = 25,
labelFontSize = 13.sp
)
val secondPieChartConfig =
PieChartConfig(
labelVisible = true,
strokeWidth = 50f,
labelColor = font_color,
activeSliceAlpha = .9f,
isEllipsizeEnabled = true,
fontFamily = FontFamily(
Font(Res.font.Roboto_Medium, weight = FontWeight.Normal)
),
backgroundColor = green_light,
labelFontWeight = FontWeight.Bold,
isAnimationEnable = true,
chartPadding = 25,
labelFontSize = 12.sp,
isSumVisible = true,
sumUnit = "unit",
labelColorType = PieChartConfig.LabelColorType.SLICE_COLOR,
labelType = PieChartConfig.LabelType.VALUE
)
val thirdPieChartConfig =
PieChartConfig(
labelVisible = true,
strokeWidth = 50f,
labelColor = font_color,
activeSliceAlpha = .9f,
fontFamily = FontFamily(
Font(Res.font.Roboto_Medium, weight = FontWeight.Normal)
),
backgroundColor = gray_light,
isEllipsizeEnabled = true,
labelFontWeight = FontWeight.Bold,
isAnimationEnable = true,
chartPadding = 25,
labelFontSize = 13.sp
)
Column(
modifier = Modifier
.fillMaxWidth()
.height(300.dp)
) {
Legends(
legendsConfig = getLegendsConfigFromPieChartDataForDonutChart(
pieChartData = data,
3
)
)
Spacer(modifier = Modifier.height(20.dp))
LazyRow(
modifier = Modifier
.fillMaxWidth()
) {
item {
DonutPieChart(
modifier = Modifier
.width(100.dp)
.height(100.dp),
data,
firstPieChartConfig
) { slice ->

}
Spacer(modifier = Modifier.width(30.dp))
}
item {
DonutPieChart(
modifier = Modifier
.width(100.dp)
.height(100.dp),
data,
secondPieChartConfig
) { slice ->

}
Spacer(modifier = Modifier.width(30.dp))
}
item {
DonutPieChart(
modifier = Modifier
.width(100.dp)
.height(100.dp),
data,
thirdPieChartConfig
) { slice ->

}
Spacer(modifier = Modifier.width(30.dp))
}
}
}
}

5) Pie Chart

Customisation Parameters

startAngleStarting angle for the first slice of the pie chart, in degrees.

showSliceLabelsFlag indicating whether slice labels should be displayed.

sliceLabelTextSizeText size of the slice labels.

sliceLabelTextColorText color of the slice labels.

sliceLabelTypefaceTypeface (font weight) of the slice labels.

isAnimationEnableFlag indicating whether animation is enabled for the pie chart.

animationDurationDuration of the animation in milliseconds. Minimum value is 1

strokeWidthWidth of the stroke around each slice in the pie chart.

labelFontSizeFont size of additional labels (e.g., percentage labels).

labelFontWeightFont weight of additional labels.

labelVisibleFlag indicating whether additional labels are visible.

fontFamilyFont family for the text in the chart.

labelTypeType of label to display (e.g., percentage or custom).

labelColorColor of additional labels.

labelColorTypeType of color to use for labels (e.g., specified or automatic).

backgroundColorBackground color of the pie chart.

activeSliceAlphaAlpha value (transparency) of active (selected) slices.

inActiveSliceAlphaAlpha value (transparency) of inactive (unselected) slices.

isEllipsizeEnabledFlag indicating whether text ellipsization is enabled for slice labels.

sliceMinTextWidthToEllipsizeMinimum width for slice label text before ellipsization is applied.

chartPaddingPadding around the pie chart.

isSumVisibleFlag indicating whether a sum value is visible in the chart.

sumUnitUnit of measurement for the sum value, if visible.

isClickOnSliceEnabledFlag indicating whether clicking on slices is enabled for interaction.

A. Simple Pie Chart

@Composable
fun PieChartExample() {
val pieChartData = PieChartData(
slices = listOf(
PieChartData.Slice("Android", 30f, green_dark),
PieChartData.Slice("iOS", 30f, blue_dark),
),
plotType = PlotType.Pie
)
val pieChartConfig =
PieChartConfig(
labelVisible = true,
activeSliceAlpha = .9f,
isEllipsizeEnabled = true,
sliceLabelTypeface = FontWeight.Bold,
fontFamily = FontFamily(
Font(Res.font.Roboto_Medium, weight = FontWeight.Normal)
),
isAnimationEnable = true,
chartPadding = 30,
backgroundColor = white_color,
showSliceLabels = false,
animationDuration = 1500
)
Column(modifier = Modifier.height(500.dp)) {
Spacer(modifier = Modifier.height(20.dp))
Legends(legendsConfig = getLegendsConfigFromPieChartData(pieChartData, 3))
PieChart(
modifier = Modifier
.fillMaxWidth()
.height(400.dp),
pieChartData,
pieChartConfig
) { slice ->
//Custom event on slice tap
}
}
}

B. PieChart With Slice Labels

@Composable
fun PieChartWithSliceLabels() {
val pieChartData = getPieChartData2()

val pieChartConfig =
PieChartConfig(
activeSliceAlpha = .9f,
isEllipsizeEnabled = true,
sliceLabelTypeface = FontWeight.Bold,
isAnimationEnable = true,
chartPadding = 20,
fontFamily = FontFamily(
Font(Res.font.Roboto_Medium, weight = FontWeight.Normal)
),
showSliceLabels = true,
labelVisible = true
)
Column(modifier = Modifier.height(500.dp)) {
Legends(legendsConfig = getLegendsConfigFromPieChartData(pieChartData, 3))
PieChart(
modifier = Modifier
.fillMaxWidth()
.height(400.dp),
pieChartData,
pieChartConfig
) { slice ->
//Custom event on slice tap
}
}
}

6) Gauge Chart

Customisation Parameters

placeHolderColorColor for the gauge chart placeholder.

primaryColorPrimary color used for the gauge chart.

strokeWidthWidth of the gauge chart's stroke.

showNeedleFlag indicating whether to show the gauge needle.

showIndicatorFlag indicating whether to show the gauge indicator.

indicatorColorColor of the gauge indicator.

indicatorWidthWidth of the gauge indicator.

@Composable
fun GaugeChartExample() {
Box(
modifier = Modifier
.fillMaxWidth()
.height(250.dp)
.padding(10.dp),
contentAlignment = Alignment.Center
) {
GaugeChart(percentValue = 60, gaugeChartConfig = GaugeChartDefaults.gaugeConfigDefaults().copy(
primaryColor = pink_dark, placeHolderColor = pink_light, indicatorColor = yellow_dark
), needleConfig = GaugeChartDefaults.needleConfigDefaults().copy(
color = green_dark
))
}
}

7) Circular Chart

Customisation Parameters

chartSizeSize of the circular chart.

startAngleStarting angle for drawing the chart, in degrees.

strokeWidthWidth of the stroke used to draw the chart.

strokeCapStroke cap style for the chart's path.

textSizeFont size of text within the chart.

textColorColor of the text within the chart.

fontFamilyFont family for the text within the chart.

@Composable
fun CircularChartDemo() {
Box(
modifier = Modifier
.fillMaxWidth()
.height(250.dp)
.padding(10.dp),
contentAlignment = Alignment.TopStart
) {
CircularChart(
chartListData = listOf(
CircularBarChartEntry(value = 100F, "Activity A", green_dark, 200),
CircularBarChartEntry(value = 80F, "Activity B", blue_dark, 200),
CircularBarChartEntry(value = 150F, "Activity C", yellow_dark, 200),
),
chartStyle = CircularChartStyle(
chartSize = 200.dp, strokeWidth = 20.dp,
fontFamily = FontFamily(
Font(Res.font.Roboto_Medium, weight = FontWeight.Normal)
)
),
)
}
}

8) Area Chart

Customisation Parameters

showAxesFlag indicating whether to show axes.

showGridLinesFlag indicating whether to show grid lines.

showGridLabelFlag indicating whether to show grid labels.

axisStrokeStroke width of the axes.

minLabelCountMinimum count of labels to display on the axis.

axisColorColor of the axes.

axisLabelFontFamilyFont family for the axis labels.

gridColorColor of the grid lines, derived from axisColor with adjusted alpha.

@Composable
fun AreaChartDemo() {
Box(
modifier = Modifier
.wrapContentSize()
.padding(10.dp),
contentAlignment = Alignment.Center
) {
AreaChart(
modifier = Modifier
.size(400.dp),
areaData = ComposeList(
getAreaData()
),
axisConfig = ChartDefaults.axisConfigDefaults().copy(
axisColor = font_color,
showGridLabel = true,
gridColor = gray_light,
axisLabelFontFamily = FontFamily(
Font(Res.font.Roboto_Bold, weight = FontWeight.Bold)
),
)
)
}
}
fun getAreaData() = listOf(
AreaData(
points = listOf(0.5f, 0.8f, 0.6f, 0.9f, 0.7f, 0.4f),
xValue = "Item 1",
color = yellow_dark
),
AreaData(
xValue = "Item 2",
points = listOf(0.33f, 0.6f, 0.93f, 0.7f, 0.9f, 1.5f),
color = pink_dark
),
AreaData(
xValue = "Item 3",
points = listOf(0.3f, 0.6f, 0.4f, 0.7f, 0.9f, 0.3f),
color = green_dark
),
)

9) Point Chart

Customisation Parameters

showAxesFlag indicating whether to show axes.

showGridLinesFlag indicating whether to show grid lines.

showGridLabelFlag indicating whether to show grid labels.

axisStrokeStroke width of the axes.

minLabelCountMinimum count of labels to display on the axis.

axisColorColor of the axes.

axisLabelFontFamilyFont family for the axis labels.

gridColorColor of the grid lines, derived from axisColor with adjusted alpha.

@Composable
fun PointChartDemo() {
Box(
modifier = Modifier
.fillMaxWidth()
.wrapContentHeight(),
contentAlignment = Alignment.Center
) {
PointChart(
dataCollection = ChartDataCollection(getPointChartList()),
pointType = PointType.Fill,
modifier = Modifier
.size(400.dp),
chartColors = ChartDefaults.colorDefaults().copy(
backgroundColors = white_color,
contentColor = green_dark
),
axisConfig = ChartDefaults.axisConfigDefaults().copy(
axisColor = font_color,
gridColor = green_light,
axisLabelFontFamily = FontFamily(
Font(Res.font.Roboto_Bold, weight = FontWeight.Bold)
),
minLabelCount = 3
)
)
}
}
fun getPointChartList() = listOf(
PointData(0F, "Jan"),
PointData(10F, "Feb"),
PointData(05F, "Mar"),
PointData(50F, "Apr"),
PointData(55F, "May"),
PointData(03F, "June"),
PointData(9F, "July"),
PointData(40F, "Aug"),
PointData(60F, "Sept"),
PointData(33F, "Oct"),
PointData(11F, "Nov"),
)

10) Bottle Chart

Customisation Parameters

  • bottleHeight The height of the bottle.
  • bottleWidth The width of the bottle.
  • bottleCorkWidth The width of the bottle cork.
  • bottleCorkHeight The height of the bottle cork.
  • shouldAnimateProgress Indicates whether the progress animation should be played.
  • animationDurationMillis The duration of the progress animation in milliseconds.
  • bottleFilledProgressPercent The percentage of the bottle that should appear filled, ranging from 0.0 to 1.0.
  • bottleColorStyle The style configuration for the bottle's color.
@Composable
fun BottleChartDemo() {
BottleChart(
bottleChartConfig = BottleChartConfig(
bottleHeight= 300.dp,
bottleWidth = 200.dp,
bottleCorkWidth = 220.dp,
bottleCorkHeight = 93.0.dp,
bottleColorStyle = BottleColorStyle(
bottleColor = Color(0x66E3E3E3),
bottleFluidColor = Color(0xFF59A7D9),
bottleCorkColor = Color(0xFF40291D)
),
bottleFilledProgressPercent = 0.6f,
shouldAnimateProgress = true,
animationDurationMillis = 1500
)
)
}

11) Segment Progress Bar Chart

Customisation Parameters

  • cornerRadius The corner radius of the segments.
  • displayScale Indicates whether the scale should be displayed.
  • scaleLabels The labels to be displayed on the scale, typically representing percentage values.
  • segmentsHeight The height of each segment.
  • segmentsWidth The width of each segment.
  • scaleThickness The thickness of the scale lines.
  • scaleFontFamily The font family used for the scale labels. Can be null if no specific font is required.
  • scaleFontWeight The font weight used for the scale labels, defaulting to Normal.
  • scaleFontSize The font size used for the scale labels.
  • pointerHeight The height of the pointer that indicates progress.
  • pointerWidth The width of the pointer that indicates progress.
  • shouldAnimateProgress Indicates whether the progress animation should be played.
  • animationDurationMillis The duration of the progress animation in milliseconds.
  • segmentsList A list of SegmentInfo objects, each defining the color and weight of a segment in the progress bar.
  • progress The current progress value, represented as a float between 0.0 and 1.0.
  • segmentProgressBarColors The color configuration for the segments in the progress bar.
@Composable
fun SegmentProgressBarChartDemo() {
Box(modifier = Modifier.padding(top = 16.dp).fillMaxSize()) {
SegmentedProgressBarChart(
segmentProgressBarConfig = SegmentProgressBarConfig(
cornerRadius = 8.dp,
segmentsHeight = 120.dp,
segmentsWidth = 350.dp,
scaleThickness = 1.1.dp,
scaleFontFamily = FontFamily(
Font(Res.font.Poppins_Regular, weight = FontWeight.Normal)
),
animationDurationMillis = 1200,
scaleFontWeight = FontWeight.Normal,
shouldAnimateProgress = true,
segmentsList = listOf(
SegmentInfo(
segmentColor = Color(0xFFFF3849), segmentWeight = 1.0f
), SegmentInfo(
segmentColor = Color(0xFFFFBB4E), segmentWeight = 1.8f
), SegmentInfo(
segmentColor = Color(0xFFFFE34E), segmentWeight = 1.5f
), SegmentInfo(
segmentColor = Color(0x8087C682), segmentWeight = 1.0f
), SegmentInfo(
segmentColor = Color(0xFF6CB14C), segmentWeight = 1.0f
)
),
scaleLabels = listOf("0%", "20%", "40%", "60%", "80%", "100%"),
pointerWidth = 16.dp,
pointerHeight = 78.dp,
displayScale = true,
scaleFontSize = 10.sp,
segmentProgressBarColors = SegmentProgressBarColors(
pointerColor = Color(0xFF222222),
scaleTextColor = Color(0xFF7D7F7C),
scaleColor = Color(0xFF7D7F7C)
)
)
)
}
}

12) Radar Chart

Customisation Parameters

  • sideLength The number of sides or vertices of the radar chart.
  • scaleStepsCount The number of steps or intervals between the center and the outer edge of the radar chart.
  • maxLabelWidth The maximum width allowed for the labels displayed on the radar chart.
  • radarChartLineStyle The style applied to the lines of the radar chart.
  • radarChartDataSet The data set(s) that will be plotted on the radar chart.
  • labelTextStyle The text style applied to the labels on the radar chart.
  • scaleTextStyle The text style applied to the scale labels.
  • scaleUnit The unit of measurement displayed with the scale values.
  • maxScaleValue The maximum value that can be represented on the radar chart.
  • radarSegmentsLabels The labels for each segment of the radar chart.
@Composable
fun RadarChartDemo(modifier: Modifier) {
RadarChart(
modifier = modifier,
radarChartConfig = RadarChartConfig(
sideLength = 5,
maxLabelWidth = 25.dp,
scaleStepsCount = 5,
radarChartDataSet = listOf(
RadarChartDataSet(style = RadarChartDataSetStyle(
color = blue_medium,
strokeCap = StrokeCap.Butt,
strokeWidth = 1.0f,
colorAlpha = 0.3f,
borderColor = font_color
),
data = listOf(117.0, 180.0, 120.0, 145.0, 85.0)
),
RadarChartDataSet(style = RadarChartDataSetStyle(
brush = Brush.horizontalGradient(
colors = listOf(
green_dark,
green_medium
)
),
colorAlpha = 0.1f,
strokeCap = StrokeCap.Butt,
strokeWidth = 1.0f,
borderColor = font_color
), data = listOf(110.0, 150.0, 120.0, 190.0, 35.0)
),
),
radarChartLineStyle = RadarChartLineStyle(
color = gray_medium,
strokeCap = StrokeCap.Butt,
strokeWidth = 1f
),
scaleTextStyle = TextStyle(
color = Color.Black,
fontSize = 11.sp,
fontFamily = FontFamily(
Font(Res.font.Roboto_Regular, weight = FontWeight.Normal)
)
),
labelTextStyle = TextStyle(
color = Color.Black,
fontSize = 12.sp,
fontFamily = FontFamily(
Font(Res.font.Roboto_Medium, weight = FontWeight.Medium)
)
),
maxScaleValue = 200.0,
scaleUnit = "cm",
radarSegmentsLabels = listOf("A", "B", "C", "D", "E")
)
)
}

13) Heat Map Chart

Customisation Parameters

  • heatMapData A list of HeatMapData objects that define the value, row, and column information for each cell in the heat map.
  • listIntensityStyle A list of HeatMapIntensityStyle objects used to determine the background color of cells based on the intensity scale.
  • heatMapEntriesTextStyle The text style applied to the entries (cell values) within the heat map. This controls font size, weight, and color of the cell text.
  • heatMapTitleTextStyle The text style used for the titles of the heatmap rows and columns.
  • dividerStrokeSize The thickness of the dividers between the cells in the heat map.
  • verticalTitlePadding The padding applied to the vertical titles (row titles) of the heat map, helping to space them out from the cells.
  • horizontalTitlePadding The padding applied to the horizontal titles (column titles) of the heatmap, which adjusts their spacing relative to the cells.
  • itemVerticalPadding The vertical padding inside each heatmap cell, which affects how the text or content within each cell is spaced.
  • itemHorizontalPadding The horizontal padding inside each heatmap cell, controlling the space between text and the cell borders.
  • cellHeight The height of each cell in the heat map. This sets how tall each row in the heat map will be.
  • cellWidth The width of each cell in the heat map, defining how wide each column will be.
  • cellCornerRadius The corner radius of each heat map cell, allowing you to create rounded corners for a softer look.
  • itemTextAlignment Defines the alignment of the text within each heat map cell, such as center, start, or end.
  • horizontalTitleTextAlignment The text alignment for horizontal titles (column titles), such as center-aligned or left-aligned.
  • verticalTitleTextAlignment The text alignment for vertical titles (row titles), helping control their appearance.
  • dividerColor The color of the dividers between cells, used to visually separate the heat map cells.
  • showHorizontalTitles A Boolean flag that controls whether the horizontal titles (column headers) are displayed in the heat map.
  • showVerticalTitles A Boolean flag that controls whether the vertical titles (row headers) are displayed in the heat map.
@Composable
fun HeatMapChartDemo() {
val heatMapData = getHeatMapData()
HeatMapChart(
heatMapConfig =
HeatMapConfig(
heatMapData = heatMapData,
listIntensityStyle = listOf(
HeatMapIntensityStyle(
intensityColor = red_dark,
intensityRange = 0.0..0.0
),
HeatMapIntensityStyle(
intensityColor = red_light,
intensityRange = 0.71..1.00
),
HeatMapIntensityStyle(
intensityColor = red_medium,
intensityRange = 0.41..0.70
),
HeatMapIntensityStyle(
intensityColor = red_dark,
intensityRange = 0.10..0.40
),
HeatMapIntensityStyle(
intensityColor = green_light,
intensityRange = 1.01..1.40
),
HeatMapIntensityStyle(
intensityColor = green_medium,
intensityRange = 1.41..1.70
),
HeatMapIntensityStyle(
intensityColor = green_dark,
intensityRange = 1.71..2.00
)
),
heatMapTitleTextStyle = TextStyle(
color = gray_dark,
fontSize = 12.sp,
fontFamily = FontFamily(
Font(Res.font.Roboto_Regular, weight = FontWeight.Normal)
)
),
heatMapEntriesTextStyle = TextStyle(
color = Color.Black,
fontSize = 13.sp,
fontFamily = FontFamily(
Font(Res.font.Roboto_Regular, weight = FontWeight.Normal)
)
),
verticalTitlePadding = 0.dp,
)
)
}

fun getHeatMapData(): List<HeatMapData> {
return listOf(
HeatMapData(
cellValue = "-6.1",
cellGroupId = "1",
cellRow = "Canada",
cellColumn = "Transport",
scaleIntensity = 0.6
),
HeatMapData(
cellValue = "1.5",
cellGroupId = "1",
cellRow = "Canada",
cellColumn = "Textile",
scaleIntensity = 1.30
),
HeatMapData(
cellValue = "-8.9",
cellGroupId = "1",
cellRow = "Canada",
cellColumn = "Metals",
scaleIntensity = 0.6
),
HeatMapData(
cellValue = "2.6",
cellGroupId = "1",
cellRow = "Canada",
cellColumn = "Plastics",
scaleIntensity = 1.45
),
HeatMapData(
cellValue = "-0.1",
cellGroupId = "1",
cellRow = "Canada",
cellColumn = "Petroleum",
scaleIntensity = 0.75
),

HeatMapData(
cellValue = "10.9",
cellGroupId = "2",
cellRow = "China",
cellColumn = "Transport",
scaleIntensity = 1.75
),
HeatMapData(
cellValue = "-12.3",
cellGroupId = "2",
cellRow = "China",
cellColumn = "Textile",
scaleIntensity = 0.20
),
HeatMapData(
cellValue = "-3.1",
cellGroupId = "2",
cellRow = "China",
cellColumn = "Metals",
scaleIntensity = 0.45
),
HeatMapData(
cellValue = "-15.7",
cellGroupId = "2",
cellRow = "China",
cellColumn = "Plastics",
scaleIntensity = 0.15
),
HeatMapData(
cellValue = "0.6",
cellGroupId = "2",
cellRow = "China",
cellColumn = "Petroleum",
scaleIntensity = 1.10
),

HeatMapData(
cellValue = "-30.9",
cellGroupId = "3",
cellRow = "Mexico",
cellColumn = "Transport",
scaleIntensity = 0.20
),
HeatMapData(
cellValue = "-1.1",
cellGroupId = "3",
cellRow = "Mexico",
cellColumn = "Textile",
scaleIntensity = 0.45
),
HeatMapData(
cellValue = "3.1",
cellGroupId = "3",
cellRow = "Mexico",
cellColumn = "Metals",
scaleIntensity = 1.45
),
HeatMapData(
cellValue = "-1.9",
cellGroupId = "3",
cellRow = "Mexico",
cellColumn = "Plastics",
scaleIntensity = 0.45
),
HeatMapData(
cellValue = "-1.2",
cellGroupId = "3",
cellRow = "Mexico",
cellColumn = "Petroleum",
scaleIntensity = 0.45
),

HeatMapData(
cellValue = "-45.2",
cellGroupId = "4",
cellRow = "Europe",
cellColumn = "Transport",
scaleIntensity = 0.20
),
HeatMapData(
cellValue = "-0.3",
cellGroupId = "4",
cellRow = "Europe",
cellColumn = "Textile",
scaleIntensity = 0.75
),
HeatMapData(
cellValue = "-1.8",
cellGroupId = "4",
cellRow = "Europe",
cellColumn = "Metals",
scaleIntensity = 0.45
),
HeatMapData(
cellValue = "-2",
cellGroupId = "4",
cellRow = "Europe",
cellColumn = "Plastics",
scaleIntensity = 0.45
),
HeatMapData(
cellValue = "0.1",
cellGroupId = "4",
cellRow = "Europe",
cellColumn = "Petroleum",
scaleIntensity = 1.10
),

HeatMapData(
cellValue = "8.8",
cellGroupId = "5",
cellRow = "Japan",
cellColumn = "Transport",
scaleIntensity = 1.75
),
HeatMapData(
cellValue = "0.2",
cellGroupId = "5",
cellRow = "Japan",
cellColumn = "Textile",
scaleIntensity = 1.10
),
HeatMapData(
cellValue = "-10.4",
cellGroupId = "5",
cellRow = "Japan",
cellColumn = "Metals",
scaleIntensity = 0.20
),
HeatMapData(
cellValue = "0.5",
cellGroupId = "5",
cellRow = "Japan",
cellColumn = "Plastics",
scaleIntensity = 1.10
),
HeatMapData(
cellValue = "18.3",
cellGroupId = "5",
cellRow = "Japan",
cellColumn = "Petroleum",
scaleIntensity = 1.80
)
)
}

Conclusion

With CMPCharts, harnessing powerful data visualisation capabilities for your applications has never been more straightforward. Whether you’re an experienced developer or new to integrating visual data representations with CMPCharts, our library empowers you to create compelling and insightful charts that enhance user understanding and engagement.

So why hesitate? Dive into CMPCharts today and elevate your app’s data visualisation to new heights!

All the code examples and detailed documentation are available in our repository. Start exploring and transforming your data into impactful visual narratives effortlessly.

All the code and examples can be found in this repository.

Connect with us 👇

Linkedin

GitHub

--

--