[Kotlin/Android] MPAndroidChart 이용해서 LineChart 그리기 (커스텀)
연나연
2024. 8. 28. 14:36
< 만들고자 하는 것 >
아래와 같이 유량, 수압 두 개의 그래프를 하나의 차트 안에 그리고자 한다. 여기서 조건이 몇 가지 붙는다
(1) 가로축 항목은 1440개 (2) 한 번에 보여지는 화면은 가장 오른쪽(최근데이터) 부터 인데 60개씩 보여지고 왼쪽으로 슬라이스하여 더 볼 수 있도록 (3) 선그래프의 값에 일정범위제한을 두어 해당 범위 이상부분의 점은 색을 다르게한다.
▼방법
1. build.gradle.kts (Module:app) 에 MPAndroid 라이브러리 추가
2. 코드 추가
아래는 차트를 만드는 함수이고, 나는 해당 함수를 onViewCreated에서 호출했따.
private fun setChart(){
// lineChart 초기화
val lineChart: LineChart = requireView().findViewById(R.id.lineChartDataInquiry)
// 데이터 생성 (예시 데이터)
val flowEntries = ArrayList<Entry>()
val pressureEntries = ArrayList<Entry>()
// 가상의 데이터 생성 (1440개, 1분 간격)
for (i in 0 until 1440) {
val flowValue = (Math.random() * 20).toFloat() // 유량 데이터: 0 ~ 20 사이 랜덤 값
val pressureValue = (Math.random() * 10).toFloat() // 수압 데이터: 0 ~ 10 사이 랜덤 값
flowEntries.add(Entry(i.toFloat(), flowValue))
pressureEntries.add(Entry(i.toFloat(), pressureValue))
}
// 유량 데이터셋 생성
val flowDataSet = LineDataSet(flowEntries, "Flow Rate")
flowDataSet.color = Color.BLUE
flowDataSet.valueTextColor = Color.WHITE
flowDataSet.setDrawCircles(true)
flowDataSet.circleRadius = 4f
flowDataSet.setDrawValues(false)
// 유량 데이터셋의 색상 설정 (범위에 따라 색상 변경)
flowDataSet.setDrawCircles(true)
flowDataSet.circleColors = flowEntries.map { entry ->
when {
entry.y < 6 -> Color.GREEN //정상
entry.y < 10 -> Color.YELLOW //주의
entry.y < 13 -> Color.MAGENTA // 경계
else -> Color.RED
}
}
// 수압 데이터셋 생성
val pressureDataSet = LineDataSet(pressureEntries, "Pressure")
pressureDataSet.color = Color.CYAN
pressureDataSet.valueTextColor = Color.WHITE
pressureDataSet.setDrawCircles(false)
pressureDataSet.setDrawValues(false)
// LineData 생성
val lineData = LineData(flowDataSet, pressureDataSet)
// 차트에 데이터 설정
lineChart.data = lineData
// x축 설정
val xAxis: XAxis = lineChart.xAxis
xAxis.position = XAxis.XAxisPosition.BOTTOM // X축 레이블 아래 표시
xAxis.setDrawGridLines(false) // x축의 그리드 라인을 숨김
xAxis.labelRotationAngle= -45F // x축 레이블 각도 조정
xAxis.valueFormatter = XAxisFormatter()
xAxis.setLabelCount(6, true) // 레이블 수 설정
xAxis.granularity = 1f // X축 스크롤 시 간격 유지
xAxis.axisMinimum = 0f
xAxis.axisMaximum = 1440f // 1440개의 데이터 포인트
xAxis.setDrawLabels(true)
xAxis.isGranularityEnabled = true
xAxis.textColor = Color.WHITE
// 범례 설정
val legend = lineChart.legend
legend.isEnabled = true // 범례 표시
legend.textColor = Color.WHITE // 범례 텍스트 색상 설정
// Y축 설정
lineChart.axisLeft.axisMinimum = 0f // Y축 최소값 설정
lineChart.axisLeft.axisMaximum = 22f // Y축 최대값 설정 (유량 기준)
lineChart.axisRight.isEnabled = false // 오른쪽 Y축 비활성화
lineChart.axisLeft.textColor = Color.WHITE
// 차트 애니메이션 설정
lineChart.animateX(1000)
// 차트가 오른쪽에서 60개 항목(1시간)부터 시작되도록 설정
lineChart.setVisibleXRangeMaximum(60f) // 한 번에 60개씩 보여줌
lineChart.moveViewToX(1440f - 60f) // 오른쪽으로 이동 (가장 최근 데이터부터)
// 차트 업데이트
// 차트를 다시 그리게하여 데이터가 반영되도록 함
lineChart.invalidate()
}
// X축 레이블을 설정하기 위한 포매터 클래스
inner class XAxisFormatter : com.github.mikephil.charting.formatter.ValueFormatter() {
override fun getFormattedValue(value: Float): String {
// 1440개의 데이터 포인트 중 특정 위치를 시간으로 변환 (24시간 표현)
val minutes = value.toInt()
val hours = minutes / 60
val mins = minutes % 60
return String.format("%02d:%02d", hours, mins) // 시간:분 형식
}
}