Skip to content

Repository files navigation

Aught One Charts

Maven Central License

Charts Banner

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.

πŸ™ Accreditation

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.

πŸ“₯ Installation

Using local build

Go to the root directory and build the project, or run the local publish script:

./publish-local.sh

This builds the artifacts and publishes them to your local Maven repository (~/.m2/repository).

Using maven dependency

Add the dependency to your Kotlin Multiplatform or Android project:

// commonMain sourceSet dependencies
implementation("io.github.aughtone:charts:0.0.1")

πŸš€ Usage

The library provides following components:

ChartLegend can also be used on its own to place a legend elsewhere in your own layout.

Most of the components have arguments like:

  • data - depends on chart type it's complex dataset or few primitives arguments
  • colors - gives the possibility to change colors of the chart. In some cases the colors are stored in datasets (like in BarChart or LineChart). See theming section to set same appearance to all charts.
  • config - allows to personalize charts. Depends on chart type it can modify different parts of component. See documentation of specific chart
  • animation - the way how chart should appear at the first time

BarChart

Bar chart

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.

BubbleChart

Bubble chart

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

Dial chart

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

Gas bottle chart

GasBottle(
    percentage = 75f,
    modifier = Modifier.size(width = 200.dp, height = 300.dp),
    animation = ChartAnimation.Simple {
        spring(
            dampingRatio = Spring.DampingRatioMediumBouncy,
            stiffness = Spring.StiffnessVeryLow
        )
    }
)

LineChart

Line chart

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()
)

PieChart

Pie chart

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.

Simple charts

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.

🎨 Theming

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,
)

πŸ“„ License

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.

About

Charts library for Kotlin multiplatform applications

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages