본문 바로가기
IT/Android

Android(Kotlin), Jetpack Compose로 구현한 UI에서 MPAndroidChart를 활용하여 그래프 그리기

by Cyber_ 2024. 4. 8.

0. 개요

MPAndroidCart는 Philipp jahoda라는 분이 만든 앱을 위한 차트 라이브러리이다. 이번엔 Room DB에 저장된 데이터들을 불러 그래프를 선형 그래프를 구현해보자.

1. MPAndroidChart를 활용하여 구현할 수 있는 그래프

1) LineChart
- simple design
- cubic lines
- grdient fill
2) BarChart
- simple design
- grouped DataSets
3) Horizontal-BarChart
4) Combiend-BarChart(bar - andlineChart in this case)
5) PieChart(with selection, ..)
6) ScatterChart(with squares, triangles, circles, ... and more)
7) CandleSticChart(for financial data)
8) BubbleChart(area covered by bubbles indicates the yValue)
9) RagarChart(spider web chart)

1. LineChart 구현

1) settings.gradle.kts(Project Settings)

pluginManagement {
    repositories {
        google()
        mavenCentral()
        gradlePluginPortal()
    }
}
dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories{
        maven(url="https://jitpack.io") // 추가
        mavenCentral()
        google()
    }
}

2) build.gradle(Module: mymodule)

dependencies{
	....
    
    implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0' // 추가
    
    ````
}

3) Compose를 활용하여 UI 구현

  • DbEntity: DB에 접근하기 위한 Entity이다.
interface DbEntity {
    val date: String
    val time: String
    val rate: Double
}
  • sample 데이터(이 부분은 데이터가 없을 때 참고)
data class SampleRate(
    override val date: String,
    override val time: String,
    override val rate: Double
) : DbEntity

val sampleDataList = listOf(
    SampleRate("2023-10-19", "09:30", 5.0),
    SampleRate("2023-10-19", "10:00", 5.2),
    SampleRate("2023-10-19", "11:15", 5.5),
    SampleRate("2023-10-19", "12:00", 5.8),
    SampleRate("2023-10-19", "13:45", 6.0),
    SampleRate("2023-10-19", "14:30", 5.7),
    SampleRate("2023-10-19", "15:00", 5.6)
)
  • Graph를 위한 View
class MyGragph{
	@Composeable
    fun GraphView(){

		Column(){
        	Row()
            // my ui
            ...
            
            Graph(sampleDataList) 
            
        
        }
    
    }
    
    @Composable
    fun Graph(data: List<DbEntity>) { // 본인의 DbEntity이다.
        val entries = mutableListOf<Entry>() // Entry 객체의 가변 리스트. 여기에 그래프에 
        									// 표시될 데이터 포인트들이 추가

        // 09:00부터 15:00까지의 데이터만 필터링
        data.filter {
            val timeParts = it.time.split(":")
            val hour = timeParts[0].toInt()
            hour in 9..15
        }.forEachIndexed { index, rate ->
            val hour = rate.time.substringBefore(":").toFloat()
            val minute = rate.time.split(":")[1].toFloat() / 60
            val timeAsFloat = hour + minute
            entries.add(Entry(timeAsFloat, rate.rate.toFloat()))
        }

        val dataSet = LineDataSet(entries, "예시")// MpAndroidChart 라이브러리에서 제공하는 클래스로서, 
        										// Entry 객체들의 집합을 나타냅니다.
        dataSet.color = Color.Black.toArgb()
        dataSet.valueTextColor = Color.Black.toArgb()

        // Remove the points on the graph
        dataSet.setDrawCircles(false)

        // Remove the color below the graph line
        dataSet.setDrawFilled(false)

        val lineData = LineData(dataSet)

        AndroidView(
            modifier = Modifier
                .fillMaxWidth(1f)
                .fillMaxHeight(0.5f),
            factory = { context -> // AndroidView를 생성하는 람다
                LineChart(context).apply {
                    this.data = lineData
                    description.isEnabled = false
                    xAxis.position = XAxis.XAxisPosition.BOTTOM
                    xAxis.setLabelCount(7, true)
                    xAxis.valueFormatter = object : ValueFormatter() {
                        override fun getFormattedValue(value: Float): String {
                            return "${value.toInt()}:00"
                        }
                    }
                    animateX(1500)
                }
            },
            update = { chart -> // View가 Compose환경에서 업데이트 될때 바다 호출되는 람다
                chart.data = lineData
                chart.notifyDataSetChanged()
                chart.invalidate()
            }
        )
    }
}

AndroidView는 기존 XML에서의 TextView, Button 같은 'View'나 라이브러리 기반 UI 요소를 통합하고 사용하기위한 Composable
factory를 사용하여 Composable에서 어떤 View가 사용되는지 결정할 수 있다.

3. 결론

편리한 라이브러리다. 하지만 MPAndroidChart가 그래프를 위한 유일한 라이브러리는 아니니 혹시 필요한 다른 기능이 있다면 찾아보시길 바랍니다.