DGchart(aka 'Charts') 라이브러리를 사용하여 Line chart View를 구현하고 이슈를 해결한 과정을 작성합니다.
📍 Line chart view를 구현하는 과정을 다루고 있습니다.
먼저 제가 구현하고자 하는 Line 그래프는 아래와 같습니다.
그러나 기본 LineChartView() 에 데이터를 적용하면 다음과 같이 나타납니다
... 😰
조금씩 원하는 화면으로 설정해 보겠습니다.
y축의 아래 사항들을 설정합니다.
- 오른쪽 y축 label 제거
- 왼쪽 y축 label의 font와 색상 설정
// 오른쪽 y축 label 제거하기
self.chart.rightAxis.enabled = false
// y축 label의 font와 색상 설정
self.chart.leftAxis.labelTextColor = 원하는 색상
self.chart.leftAxis.labelFont = .systemFont(ofSize: 14, weight: .light)
x축의 아래 사항들을 설정합니다.
- x축 위치 아래로 변경
- x축 label의 font와 색상 설정
- x축 세로선 제거
- x축 처음, 마지막 label text 잘리지 않게 수정
- x축 하단 범례 제거
- x축 label text 날짜로 설정
// x축 label 위치 아래로 변경
self.chart.xAxis.labelPosition = .bottom
// x축 label의 font와 색상 설정
self.chart.xAxis.labelTextColor = 원하는 색상
self.chart.xAxis.labelFont = .systemFont(ofSize: 13, weight: .light)
// x축 세로선 제거
self.chart.xAxis.drawGridLinesEnabled = false
// x축 처음, 마지막 label text 잘리지 않게 수정
self.chart.xAxis.avoidFirstLastClippingEnabled = true
// x축 하단 범례 제거
self.chart.legend.enabled = false
// 날짜 Text를 가지는 배열
var dayData = [String]()
// 그래프 Data를 가지는 배열
var valueData = [Double]()
// valueFormatter 위임하기
self.chart.xAxis.valueFormatter = self
// AxisValueFormatter 채택하여 text 설정하기
extension ChartView: AxisValueFormatter {
func stringForValue(_ value: Double, axis: AxisBase?) -> String {
return dayData[Int(value) % dayData.count]
}
}
Line Data의 아래 사항들을 변경합니다.
- 점 색상 설정
- 점 내부 흰 원 제거
- 점 상단 value label 제거
- 점 크기 설정
- 라인 색상 설정
func setLineData(_ lineChartView: LineChartView, _ dataEntries: [ChartDataEntry]) {
let lineChartDataSet = LineChartDataSet(entries: dataEntries, label: "")
// 점 색상 설정
lineChartDataSet.setCircleColor(원하는 색상)
// 점 내부 흰 원 제거
lineChartDataSet.drawCircleHoleEnabled = false
// 점 상단 value label 제거
lineChartDataSet.drawValuesEnabled = false
// 점 크기 설정
lineChartDataSet.circleRadius = 4
// 라인 색상 설정
lineChartDataSet.colors = [DojeonColor.lightBlue2.color]
let lineChartData = LineChartData(dataSet: lineChartDataSet)
lineChartView.data = lineChartData
}
- 사용자 인터렉션 enable
- 드래그 enable
- 더블 탭, 핀치 zoom disable
- 데이터 탭할 때 생기는 세로 선 제거
- 그래프 드래그할 때 생기는 세로 선 제거
- 그래프 애니메이션 추가
// 사용자 인터렉션 enable
self.chart.isUserInteractionEnabled = true
// 드래그 enable
self.chart.dragEnabled = true
// 더블 탭, 핀치 zoom disable
self.chart.pinchZoomEnabled = false
self.chart.doubleTapToZoomEnabled = false
// 데이터 탭할 때 생기는 세로 선 제거
self.chart.highlightPerTapEnabled = false
// 그래프 드래그할 때 생기는 세로 선 제거
self.chart.highlightPerDragEnabled = false
// 그래프 애니메이션 추가
self.chart.animate(xAxisDuration: 2.0, yAxisDuration: 2.0)
UI 설정이 완료되었습니다.
그런데 data(점)의 개수와 label의 개수가 다르게 나타나고 있습니다.
이는 화면 내에 보여질 data(점)의 개수와 label의 개수가 설정되어 있지 않기 때문입니다.
- 화면 내에 보여지는 점의 최소, 최대 개수 설정
- label 개수 설정
- y축 데이터의 최대, 최소 설정
func addChartData(_ data: [DojeonResult]) {
for d in data {
dayData.append(d.date.customToString(format: "MM/dd"))
valueData.append(d.value)
}
// LineDataView에 데이터 세팅
setLineData(chart, entryData(valueData))
// 화면 내에 보여지는 점의 최소 개수 설정
self.chart.setVisibleXRangeMaximum(5)
// 화면 내에 보여지는 점의 최대 개수 설정
self.chart.setVisibleXRangeMinimum(10)
// label 개수 설정(= 총 data의 개수와 동일)
self.chart.xAxis.setLabelCount(dayData.count, force: true)
// y축 데이터의 최대, 최소 설정
self.chart.leftAxis.axisMaximum = (valueData.max() ?? 80.0) + 5.0
self.chart.leftAxis.axisMinimum = (valueData.min() ?? 30.0) - 5.0
}
와 !!
이제 원하는 대로 설정이 완료되었습니다
..
라고 생각했는데
데이터가 하나만 있는 경우에 label이 두개가 보여지는 이슈가 발생했습니다.
하하하하하