Skip to content

ehsannarmani/ComposeCharts

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Compose Charts

banner mockup

Kotlin License Kotlin Multiplatform

Platform Platform Platform Platform

Table of Contents

Gradle Setup

Maven Central

dependencies {
    implementation ("io.github.ehsannarmani:compose-charts:latest_version")
}

Note

We migrated to maven central repository in 0.0.5v, so if you want to access previous versions of library, see this.

All Charts:

mockup

Examples:

Warning

Put chart data in remember and do not use directly to avoid additional recompositions.

Pie Chart:

PieChart(
   modifier = Modifier.size(200.dp),
  data = remember {
    listOf(
      Pie(label = "Android", data = 20.0, color = Color.Red, selectedColor = Color.Green),
      Pie(label = "Windows", data = 45.0, color = Color.Cyan, selectedColor = Color.Blue),
      Pie(label = "Linux", data = 35.0, color = Color.Gray, selectedColor = Color.Yellow),
    )
  },
   onPieClick = {
       println("${it.label} Clicked")
       val pieIndex = data.indexOf(it)
       data = data.mapIndexed { mapIndex, pie -> pie.copy(selected = pieIndex == mapIndex) }
   },
   selectedScale = 1.2f,
   scaleAnimEnterSpec = spring<Float>(
       dampingRatio = Spring.DampingRatioMediumBouncy,
       stiffness = Spring.StiffnessLow
   ),
   colorAnimEnterSpec = tween(300),
   colorAnimExitSpec = tween(300),
   scaleAnimExitSpec = tween(300),
   spaceDegreeAnimExitSpec = tween(300),
   style = Pie.Style.Fill
)

Note

You can change chart style to stroke:


PieChart(
   ...,
   spaceDegree = 7f,
   selectedPaddingDegree = 4f,
   style = Pie.Style.Stroke(width = 100f)
)

Column Chart:


ColumnChart(
    modifier= Modifier.fillMaxSize().padding(horizontal = 22.dp),
  data = remember {
    listOf(
        Bars(
          label = "Jan",
          values = listOf(
            Bars.Data(label = "Linux", value = 50.0, color = Brush.verticalGradient(...)
          ),
          Bars.Data(
            label = "Windows", value = 70.0, color = SolidColor(Color.Red)
          ),
        )
    ),
        Bars(
          label = "Feb",
          values = listOf(
            Bars.Data(label = "Linux", value = 80.0, color = Brush.verticalGradient(...)
          ),
          Bars.Data(
            label = "Windows", value = 60.0, color = SolidColor(Color.Red)
          ),
        )
        ),
    ...
    )
  },
    barProperties = BarProperties(
        radius = Bars.Data.Radius.Rectangle(topRight = 6.dp, topLeft = 6.dp),
        spacing = 3.dp,
        strokeWidth = 20.dp
    ),
    animationSpec = spring(
        dampingRatio = Spring.DampingRatioMediumBouncy,
        stiffness = Spring.StiffnessLow
    ),
)

Note

You can set how many data you want for every bar:

ColumnChart(
  data = remember {
    listOf(
        Bars(
          label = "1", values = listOf(
            Bars.Data(value = 10.0, color = Color.Blue)
          )
        ),
        Bars(
          label = "2", values = listOf(
            Bars.Data(value = 20.0, color = Color.Blue)
          )
        ),
        ...
    )
  },
    barProperties = BarProperties(
        spacing = 1.dp,
        strokeWidth = 10.dp,
    ),
    ...
)

Tip

You can set negative values for this chart and define max value and min value:

Example:

ColumnChart(
  data = remember {
    listOf(
        Bars(
          label = "1", values = listOf(
            Bars.Data(value = -40.0, color = Color.Blue)
          )
        ),
        Bars(
          label = "2", values = listOf(
            Bars.Data(value = 50.0, color = Color.Blue)
          )
        ),
        ...
    )
  },
    maxValue = 75.0,
    minValue = -75.0
    ...
)

Note

By default, max value is the highest value of given data, min value is 0 when there is no value under the zero in given data, otherwise if there is value under zero, min value will be (-maxValue)


Row Chart:


RowChart(
    modifier= Modifier.fillMaxSize().padding(horizontal = 22.dp),
  data = remember {
    listOf(
        Bars(
          label = "Jan",
          values = listOf(
            Bars.Data(label = "Linux", value = 50.0, color = Brush.verticalGradient(...)
          ),
          Bars.Data(
            label = "Windows", value = 70.0, color = SolidColor(Color.Red)
          ),
        )
    ),
        Bars(
          label = "Feb",
          values = listOf(
            Bars.Data(label = "Linux", value = 80.0, color = Brush.verticalGradient(...)
          ),
          Bars.Data(
            label = "Windows", value = 60.0, color = SolidColor(Color.Red)
          ),
        )
        ),
    ...
    )
  },
    barProperties = BarProperties(
        radius = Bars.Data.Radius.Rectangle(topRight = 6.dp, topLeft = 6.dp),
        spacing = 3.dp,
        strokeWidth = 20.dp
    ),
    animationSpec = spring(
        dampingRatio = Spring.DampingRatioMediumBouncy,
        stiffness = Spring.StiffnessLow
    ),
)

Tip

You can set negative values for this chart and define max value and min value:

Example:

RowChart(
  data = remember {
    listOf(
        Bars(
          label = "1", values = listOf(
            Bars.Data(value = -40.0, color = Color.Blue)
          )
        ),
        Bars(
          label = "2", values = listOf(
            Bars.Data(value = 50.0, color = Color.Blue)
          )
        ),
        ...
    )
  },
    maxValue = 75.0,
    minValue = -75.0
    ...
)

Note

By default, max value is the highest value of given data, min value is 0 when there is no value under the zero in given data, otherwise if there is value under zero, min value will be (-maxValue)


Line Chart:


LineChart(
    modifier = Modifier.fillMaxSize().padding(horizontal = 22.dp),
  data = remember {
    listOf(
      Line(
        label = "Windows",
        values = listOf(28.0, 41.0, 5.0, 10.0, 35.0),
        color = SolidColor(Color(0xFF23af92)),
        firstGradientFillColor = Color(0xFF2BC0A1).copy(alpha = .5f),
        secondGradientFillColor = Color.Transparent,
        strokeAnimationSpec = tween(2000, easing = EaseInOutCubic),
        gradientAnimationDelay = 1000,
        drawStyle = DrawStyle.Stroke(width = 2.dp),
      )
    )
  },
    animationMode = AnimationMode.Together(delayBuilder = {
        it * 500L
    }),
)

Note

You can set min & max value for all charts and show zero line:

Example:

LineChart(
  data = remember {
    listOf(
      Line(
            label = "Temperature",
            values = listOf(28.0,41.0,-5.0,10.0,35.0),
            color = Brush.radialGradient(...),
            ...
    )
    )
  },
    zeroLineProperties = LineProperties(
        enabled = true,
        color = SolidColor(Color.Red),
    ),
    minValue = -20.0,
    maxValue = 100.0
)

Max value by default is highest value of chart data and Min value is 0 when there is no value under the zero, otherwise it's the lowest data.


Note

You can set gradient color for lines:

LineChart(
  data = remember {
    listOf(
      Line(
            label = "Linux",
            values = listOf(28.0,41.0,5.0,10.0,35.0),
            color = Brush.radialGradient(...),
            ...
    )
    )
  },
    ...
)

Note

You can add how many lines you want:

LineChart(
  data = remember {
    listOf(
      Line(
            label = "Windows",
            values = listOf(...),
            color = Color.Green,
            curvedEdges = true
    ),
    Line(
      label = "Linux",
      values = listOf(...
    ),
    color = Color.Orange,
    curvedEdges = false
    ),
    Line(
      label = "Linux",
      values = listOf(...
    ),
    color = Color.Blue,
    curvedEdges = true
    ),
    )
  },
    ...
)

Note

You can show dots and disable line edge curving:

LineChart(
  data = remember {
    listOf(
      Line(
            label = "Windows",
            values = listOf(...),
            color = Color.Orange,
            curvedEdges = true,
            dotProperties = DotProperties(
              enabled = true,
              color = SolidColor(Color.White),
              strokeWidth = 4f,
              radius = 7f,
              strokeColor = SolidColor(Color.Orange),
            )
    ),
    Line(
            label = "Linux",
            values = listOf(...),
            color = Color.Cyan,
            curvedEdges = false,
            dotProperties = DotProperties(
              ...
            )
    ),
    )
  },
    curvedEdges = false
)

Note

You can make chart line dashed:

LineChart(
  data = remember {
    listOf(
      Line(
        label = "Windows",
        values = listOf(...
      ),
      drawStyle = DrawStyle.Stroke(
        width = 3.dp,
        strokeStyle = StrokeStyle.Dashed(intervals = floatArrayOf(10f, 10f), phase = 15f)
      )
      ...
    ),
    Line(
      label = "Linux",
      values = listOf(...
    ),
    ...
    ),
    )
  },
)

Note

You can make chart fill color:

LineChart(
    data = listOf(
         Line(
            label = "Windows",
            values = listOf(...),
            color = Color.Orange,
            drawStyle = DrawStyle.Fill,
            ...
         ),
    ),
)

Animation Mode:

In Row/Column/Line charts you can set running animations at the same time types:

Mode Description
OneByOne Animations will run one by one, for example in line charts, lines will be drawn after previous line animation finished.
Together By default, animations will run async, but you can set delay for next animations

Example:

LineChart(
   ...,
   animationMode = AnimationMode.OneByOne
)

LineChart(
   ...,
   animationMode = AnimationMode.Together(delayBuilder = { index-> index*200 })
)

Note

In the last example, every animation will be start 200ms after previous animations start.


Chart Properties:

Bars: BarProperties

Usage: In Column/Row Charts you can set bar properties with this property

Property Type Default Description
thickness Dp 20 specifies bar width
spacing Dp 4 specifies space between data bars when you have more than one bar in a data
cornerRadius Bars.Data.Radius Bars.Data.Radius.None specifies space between data bars when you have more than one bar in a data
style DrawStyle DrawStyle.Fill specifies bar style

Example:

val barProperties = BarProperties(
   thickness = 15.dp,
   spacing = 4.dp,
   cornerRadius = Bars.Data.Radius.Circular(6.dp),
   style = DrawStyle.Fill
)

Dots: DotProperties

Usage: In Line Charts you can set data dot shape properties with this property

Property Type Default Description
enabled Boolean false specifies dots visibility
radius Float 10f specifies dot size
color Brush SolidColor(Color.Unspecified) specifies dot color
strokeWidth Float 3f specifies dot stroke width
strokeColor Brush SolidColor(Color.Unspecified) specifies dot stroke color
strokeStyle StrokeStyle StrokeStyle.Normal specifies dot stroke style
animationEnabled Boolean true set false if you want to show dots without delay and animation
animationSpec AnimationSpec tween(300) specifies dots visibility animation spec

Example:

val dotProperties = DotProperties(
   enabled = true,
   radius = 10f,
   color = SolidColor(Color.Red),
   strokeWidth = 3f,
   strokeColor = Color.White,
   strokeStyle = StrokeStyle.Normal,
   animationEnabled = true,
   animationSpec = tween(500)
)

Indicators: IndicatorProperties

Usage: In every chart you can set properties of counters next to the chart

Property Type Default Description
enabled Boolean true specifies indicator visiblity
textStyle TextStyle TextStyle.Default specifies counter style
count IndicatorCount IndicatorCount.CountBased(5) specifies counters type and count
position IndicatorPosition Depends on chart specifies indicator position, in line & column charts can be: start or end, in line charts can be: top or bottom
padding Dp 12 specifies indicator area padding with chart area
contentBuilder (Double) -> String { "%.2f".format(it) } specifies counter content creation template

Example For Column/Line Charts:

val indicatorProperties = HorizontalIndicatorProperties(
   enabled = true,
   textStyle = MaterialTheme.typography.labelSmall,
  count = IndicatorCount.CountBased(count = 5),
  position = IndicatorPosition.Horizontal.End,
  padding = 32.dp,
   contentBuilder = { indicator->
        "%.2f".format(indicator)+" Million"
   }
)

Example For Row Charts:

val indicatorProperties = VerticalIndicatorProperties(
  enabled = true,
  textStyle = MaterialTheme.typography.labelSmall,
  count = IndicatorCount.CountBased(count = 5),
  position = IndicatorPosition.Vertical.Top,
  padding = 32.dp,
  contentBuilder = { indicator ->
    "%.2f".format(indicator) + " Million"
  }
)

Tip: You can specify type of indicator counts, we have two type: CountBased, StepBased

CountBased: it will receive a count number and will divide & calculate and in the end it will show the requested count of indicators.

StepBased: it will receive a stepBy value and will split step by given value until it reach min value, for example if (max value = 20, min value = -10) and stepBy value is 5, the indicators will be: 20,15,10,5,0,-5,-10


Grid Lines: GridProperties

Usage: In every chart you can set properties of grid lines

Property Type Default Description
enabled Boolean true specifies grid lines visibility
xAxisProperties AxisProperties AxisProperties(..) specifies grid horizontal lines properties
yAxisProperties AxisProperties AxisProperties(..) specifies grid vertical lines properties

Example:

val gridProperties = GridProperties(
   enabled = true,
   xAxisProperties = AxisProperties(
      ...
   ),
   yAxisProperties = AxisProperties(
      ...
   )
)

Axis: AxisProperties

Property Type Default Description
enabled Boolean true specifies axis line visibility
style StrokeStyle StrokeStyle.Normal specifies axis line style
color Color Color.Gray specifies axis line color
thickness Dp (0.5).dp specifies axis line stroke width
lineCount Int 5 specifies count of axis lines

Example:

val axisProperties = AxisProperties(
   enabled = true,
   style = StrokeStyle.Dashed(intervals = floatArrayOf(10f,10f)),
   color = Color.Gray,
   thickness = (.5).dp,
   lineCount = 5
)

Dividers: DividerProperties

Usage: In every chart you can set properties of dividers between labels and chart, indicators and chart

Property Type Default Description
enabled Boolean true specifies dividers visibility
xAxisProperties LineProperties LineProperties(..) specifies horizontal divider properties
yAxisProperties LineProperties LineProperties(..) specifies vertical divider properties

Example:

val dividerProperties = DividerProperties(
   enabled = true,
   xAxisProperties = LineProperties(
      ...
   ),
   yAxisProperties = LineProperties(
      ...
   )
)

Line: LineProperties

Property Type Default Description
enabled Boolean true specifies axis line visibility
style StrokeStyle StrokeStyle.Normal specifies axis line style
color Color Color.Gray specifies axis line color
thickness Dp (0.5).dp specifies axis line stroke width

Example:

val lineProperties = LineProperties(
   enabled = true,
   style = StrokeStyle.Dashed(intervals = floatArrayOf(10f,10f)),
   color = Color.Gray,
   thickness = (.5).dp,
)

Labels: LabelProperties

Usage: In every chart you can set properties of the labels (Apr, Jan, ...)

Property Type Default Description
enabled Boolean true specifies labels visibility
textStyle TextStyle TextStyle.Default specifies label textStyle
verticalPadding Dp 12.dp specifies vertical padding of labels area
labels List emptyList() In line charts, specifies chart labels
rotationDegreeOnSizeConflict Float -45 rotation degree of label on size confilict with other labels (See)
forceRotation Boolean - specifies force rotation for labels (in false mode, labels rotate only when there is a label whose width is more than 50% different from the others)

Note

Example of label rotation degree

Example:

val labelProperties = LabelProperties(
   enabled = true,
   textStyle = MaterialTheme.typography.labelSmall,
   verticalPadding = 16.dp,
   labels = listOf("Apr","Mar",...)
)

Label Helpers: LabelHelperProperties

Usage: In every chart you can set properties of the labels helper which positioned in top of chart

Property Type Default Description
enabled Boolean true specifies label helpers visibility
textStyle TextStyle TextStyle.Default specifies label helper textStyle

Example:

val labelHelperProperties = LabelHelperProperties(
   enabled = true,
   textStyle = MaterialTheme.typography.labelMedium
)

Popups: PopupProperties

Usage: In every chart you can set properties of popup which shown when user click or drag on chart

Note

In line charts your can set specific popup properties for each line, for example you can disable one of lines popup and e.g.

Property Type Default Description
enabled Boolean true specifies popup visibility
animationSpec AnimationSpec tween(400) specifies popup visibility animation spec
duration Long 1500 in column/row charts, specifies how long the popup will be visible
textStyle TextStyle TextStyle.Default specifies popup text style
containerColor Color Color(0xff313131) specifies popup background color
cornerRadius Dp 6.dp specifies popup corner radius
contentHorizontalPadding Dp 4.dp specifies popup horizontal padding
contentVerticalPadding Dp 2.dp specifies popup vertical padding
contentBuilder (Double)->String { "%.2f".format(it) } specifies popup content creation template

Example:

val popupProperties = PopupProperties(
   enabled = true,
   animationSpec = tween(300),
   duration = 2000L,
   textStyle = MaterialTheme.typography.labelSmall,
   containerColor = Color.White,
   cornerRadius = 8.dp,
   contentHorizontalPadding = 4.dp,
   contentVerticalPadding = 2.dp,
   contentBuilder = { value->
      "%.1f".format(value)+"Million"
   }
)

Todos:

  1. Add Candle Stick Chart
  2. Add Circle Progress Chart
  3. MultiPlatform Support