안드로이드스튜디오

[Kotlin] 안드로이드 Linegraph 사용하기 (MPAndroidChart)

eunda_coding 2023. 1. 27. 14:53

이번 프로젝트에서 ESP32에서 센서값을 가져와서 안드로이드 앱에서 그래프로 나타내주는 것을 했다

아직 블루투스 연결은 하지 않고 난수를 이용해서 그래프 먼저 구현을 하려는데 예제도 별로 없고 코틀린으로 짠건 더더욱 없어서 애먹었었다. 내 글을 보고 다른 사람들은 쉽게 해결할 수 있었으면 좋겠다.

 

1. gradle dependencies에 추가

    implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0'  //그래프

 

2. setting.gradle에 추가

   maven { url 'https://jitpack.io'}

이거를 추가하는 곳이 바껴서 애먹었다. 다른 사람들은 gradle에 같이 추가하던데 나는 계속 오류가 나서 헤매다가 setting.gradle에 추가하니깐 오류가 안났다. repositories 안에 mavenCentral()아래에 추가하면 된다.

 

3. xml에 추가

<com.github.mikephil.charting.charts.LineChart
	android:layout_width="match_parent"
    android:layout_height="200dp" />

레이아웃은 의외로 간단했다.

 

4. MainActivity.kt

        chart1 = findViewById<View>(R.id.linechart1) as LineChart
        chart1!!.xAxis.position = XAxis.XAxisPosition.BOTTOM
        chart1!!.axisRight.isEnabled = false
        chart1!!.legend.textColor = Color.BLACK //그래프 하단에 데이터 표시박스 옆 네이밍
        chart1!!.animateXY(2000, 2000)
        chart1!!.invalidate()
        val data1 = LineData()
//        chart1!!.description.isEnabled = false //차트 밑에 설명
        chart1!!.description.text = "손목 BPM"
        chart1!!.data = data1

onCreate에서 라인차트 바인딩해주고 간단한 속성들을 설정해주었다.

 

5. 우선 난수로 그래프 데이터값을 생성 (나중에 BT로 받은 값을 넘겨 줄 예정)

    그래프 안에 데이터가 없으면 createSet으로 그래프를 생성하고 있으면 그냥 데이터만 추가하고 notifyDataChanged로      알려준다.

    private fun addEntry() {
        val data1 = chart1!!.data
        if (data1 != null) {
            var set = data1.getDataSetByIndex(0)
            if (set == null) {
                set = createSet()
                data1.addDataSet(set)
            }
            var num1 = (Math.random() * 40).toFloat() + 30f
            data1.addEntry(Entry(set.entryCount.toFloat(), num1), 0)
            data1.notifyDataChanged()
            chart1!!.notifyDataSetChanged()
            chart1!!.setVisibleXRangeMaximum(40f) //x축에 표시할 데이터 갯수
            chart1!!.moveViewToX(data1.entryCount.toFloat())
        }
    }

6. 새로운 그래프를 그리는 함수 및 속성

    private fun createSet(): LineDataSet {
        val set = LineDataSet(null, "BPM")
        set.fillAlpha = 110
        set.fillColor = Color.parseColor("#d7e7fa") //그래프 채우는 색상
        set.color = Color.parseColor("#0B80C9") //그래르 선 색상
        set.setCircleColor(Color.parseColor("#FFA1B4DC"))
        set.circleHoleColor = Color.parseColor("#5F00FF")
        set.valueTextColor = Color.BLACK
        set.setDrawValues(false) //그래프 값 표시 유무
        set.lineWidth = 2f
        set.circleRadius = 6f
        set.setDrawCircleHole(false)
        set.setDrawCircles(false)
        set.valueTextSize = 9f
        set.setDrawFilled(true)
        set.axisDependency = YAxis.AxisDependency.LEFT
        set.highLightColor = Color.rgb(244, 117, 117)

        return set
    }

7. 값을 실시간으로 받아와서 갱신해 줘야하기 때문에 thread를 사용했다.

   private fun feedMultiple() {
        if (thread != null) thread!!.interrupt()
        val runnable = Runnable { addEntry() }
        thread = Thread {
            while (true) {
                runOnUiThread(runnable)
                try {
                    Thread.sleep(1000) //차트 갱신하는 시간
                } catch (ie: InterruptedException) {
                    ie.printStackTrace()
                }
            }
        }
        thread!!.start()
    }

그래프 완성!