Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
203 changes: 203 additions & 0 deletions COMPOSE_MIGRATION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,203 @@
# AndroidChart Compose Integration

## Overview

All chart classes from the `info.appdev.charting.charts` package have been successfully converted to Jetpack Compose composables. The implementation uses AndroidView wrappers to provide a Compose-friendly API while maintaining full compatibility with the existing chart rendering engine.

## Usage Examples

### Basic Line Chart

```kotlin
@Composable
fun MyLineChart() {
val entries = remember {
listOf(
Entry(0f, 10f),
Entry(1f, 20f),
Entry(2f, 15f),
Entry(3f, 30f)
)
}

val dataSet = LineDataSet(entries, "Sample Data").apply {
color = Color.BLUE
setDrawCircles(true)
}

val lineData = LineData(dataSet)

LineChart(
data = lineData,
modifier = Modifier
.fillMaxWidth()
.height(300.dp),
description = "Sales Over Time",
animationDuration = 1000,
onValueSelected = { entry, highlight ->
println("Selected: ${entry?.y}")
}
)
}
```

### Bar Chart with Configuration

```kotlin
@Composable
fun MyBarChart() {
val barData = remember { createBarData() }

BarChart(
data = barData,
modifier = Modifier.fillMaxSize(),
description = "Monthly Revenue",
backgroundColor = Color(0xFFF5F5F5),
drawValueAboveBar = true,
animationDuration = 1500,
legend = { legend ->
legend.isEnabled = true
legend.textSize = 12f
},
xAxisConfig = { xAxis ->
xAxis.position = XAxis.XAxisPosition.BOTTOM
xAxis.setDrawGridLines(false)
},
leftAxisConfig = { axis ->
axis.axisMinimum = 0f
}
)
}
```

### Pie Chart with Customization

```kotlin
@Composable
fun MyPieChart() {
val pieData = remember { createPieData() }

PieChart(
data = pieData,
modifier = Modifier
.fillMaxWidth()
.height(400.dp),
drawHoleEnabled = true,
holeRadius = 40f,
transparentCircleRadius = 45f,
centerText = "Total Sales",
rotationEnabled = true,
usePercentValuesEnabled = true,
animationDuration = 1200,
legend = { legend ->
legend.verticalAlignment = Legend.LegendVerticalAlignment.BOTTOM
legend.orientation = Legend.LegendOrientation.HORIZONTAL
}
)
}
```

### Combined Chart

```kotlin
@Composable
fun MyCombinedChart() {
val combinedData = remember {
CombinedData().apply {
setData(createLineData())
setData(createBarData())
}
}

CombinedChart(
data = combinedData,
modifier = Modifier.fillMaxSize(),
drawOrder = arrayOf(
CombinedChart.DrawOrder.BAR,
CombinedChart.DrawOrder.LINE
),
description = "Sales and Forecast",
animationDuration = 1000
)
}
```

### Stateful Chart with Updates

```kotlin
@Composable
fun InteractiveLineChart() {
val state = rememberLineChartState()
var selectedValue by remember { mutableStateOf<Float?>(null) }

Column {
LineChart(
data = state.data,
modifier = Modifier
.fillMaxWidth()
.height(300.dp),
state = state,
onValueSelected = { entry, _ ->
selectedValue = entry?.y
}
)

selectedValue?.let { value ->
Text("Selected: $value", modifier = Modifier.padding(16.dp))
}

Button(
onClick = {
state.data = generateNewData()
}
) {
Text("Refresh Data")
}
}
}
```

## Migration from View-Based Charts

### Before (View-Based)
```kotlin
AndroidView(factory = { context ->
LineChart(context).apply {
data = lineData
description.isEnabled = false
setTouchEnabled(true)
animateX(1000)
invalidate()
}
})
```

### After (Compose)
```kotlin
LineChart(
data = lineData,
description = null,
touchEnabled = true,
animationDuration = 1000
)
```

## Implementation Details

### AndroidView Wrapper Pattern
Each composable uses the `AndroidView` wrapper to embed the existing View-based chart implementation. This provides:
- Immediate compatibility with existing rendering code
- Full feature support without rewriting rendering logic
- Efficient integration with Compose's recomposition system

### Lifecycle Management
- `remember {}` - Creates chart instance once
- `DisposableEffect` - Cleans up chart resources on disposal
- `AndroidView.update {}` - Updates chart when parameters change

### Data Flow
1. User provides chart data as composable parameter
2. `update` lambda calls `chart.setData(data)`
3. Chart configuration applied (colors, animations, axes)
4. `chart.invalidate()` triggers redraw
5. Recomposition on parameter changes updates the chart
1 change: 1 addition & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ dependencies {
implementation("androidx.appcompat:appcompat:1.7.1")
implementation("com.google.android.material:material:1.13.0")
implementation(project(":chartLib"))
implementation(project(":chartLibCompose"))
implementation("androidx.window:window:1.5.1")

// Compose BOM
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import androidx.test.ext.junit.rules.activityScenarioRule
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation
import info.appdev.chartexample.compose.HorizontalBarComposeActivity
import info.appdev.chartexample.compose.HorizontalBarFullComposeActivity
import info.appdev.chartexample.fragments.ViewPagerSimpleChartDemo
import info.appdev.chartexample.notimportant.ContentItem
import info.appdev.chartexample.notimportant.DemoBase
Expand Down Expand Up @@ -249,6 +250,7 @@ class StartTest {
contentItem.clazz == RealtimeLineChartActivity::class.java ||
contentItem.clazz == LineChartTimeActivity::class.java ||
contentItem.clazz == HorizontalBarComposeActivity::class.java ||
contentItem.clazz == HorizontalBarFullComposeActivity::class.java ||
contentItem.clazz == GradientActivity::class.java ||
contentItem.clazz == TimeLineActivity::class.java
) {
Expand Down
1 change: 1 addition & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
<activity android:name="info.appdev.chartexample.BarChartActivity" />
<activity android:name="info.appdev.chartexample.HorizontalBarChartActivity" />
<activity android:name="info.appdev.chartexample.compose.HorizontalBarComposeActivity" />
<activity android:name="info.appdev.chartexample.compose.HorizontalBarFullComposeActivity" />
<activity android:name="info.appdev.chartexample.HorizontalBarNegativeChartActivity" />
<activity android:name="info.appdev.chartexample.PieChartActivity" />
<activity android:name="info.appdev.chartexample.PieChartRoundedActivity" />
Expand Down
Loading
Loading