Android에서 그래프를 사용할 때, 사용하는 MpAndroidChart 라이브러리에 대해서 알아보려고 한다.

MpAndroidChart는 그래프 라이브러리 중 하나이다. 가장 널리 알려져 있고, Github의 star가 가장 많은 그래프 라이브러리이다. 라이브러리를 선택할 때 중요하게 생각해야 할 점 중의 하나로는 star가 많은 것을 선택하라고 한다. 그 이유는 star가 많은 것은 그만큼 오픈 소스 라이브러리 활동이 활발하여 오류에 대한 수정이나 기능 추가 같은 활동들이 활발하기 때문이라고 한다. 그래서 나는 안드로이드에서 그래프를 그리기 위해 MpAndroidChart 라이브러리를 사용했다.

종류

종류는 Github에서도 확인할 수 있듯이 엄청 다양하다. 그 중에서 나는 LineChart를 이용해서 원하는 데이터를 표현하려고 했다. 한국말로는 꺾은선 그래프라고도 하며, 이를 이용해서 데이터를 간단하게 표시할 수 있다.

LineaChart 말고도 다양한 그래프들이 존재한다. 예를 들면, BarChart, PieChart 등등이 있다.

삽질 후기

그렇다면 내가 원하는 데이터를 그래프에 표시하기 위해서 삽질했던 후기를 정리하고자 한다.

##1. 데이터 생성**

그래프에서 표현하고자 하는 데이터를 생성해야 한다. 데이터는 Entry라고 하는 라이브러리에서 제공하는 타입으로 만들면 된다. 기본적으로 x, y의 Float(실수)형 데이터를 넣어서 만들 수 있다.

1
2
3
4
5
List<Entry> entires = new ArrayList<>();
entries.add(new Entry(0,1f));
entries.add(new Entry(1,2f));
entries.add(new Entry(2,3f));
entries.add(new Entry(3,4f));
  • entries를 이용해 LineDataSet을 생성한다.
1
2
3
4
5
6
7
8
9
10
LineDataSet lineDataSet = new LineDataSet(entries, "Emotion");
// entries와 지정할 label을 생성자에 넘겨준다.

lineDataSet.setLineWidth(2); // 선 굵기
lineDataSet.setCircleRadius(6); // 곡률
lineDataSet.setCircleColor(ContextCompat.getColor(mContext, R.color.graphColor)); // LineChart에서 Line Circle Color 설정
lineDataSet.setCircleHoleColor(ContextCompat.getColor(mContext, R.color.graphColor)); // LineChart에서 Line Hole Circle Color 설정
lineDataSet.setColor(ContextCompat.getColor(mContext, R.color.graphColor)); // LineChart에서 Line Color 설정

// 그리고 기타 설정 등도 할 수 있다.
  • LineDataSet을 담는 LineData를 만들어준다. 여러 개의 라인 데이터가 들어갈 수 있다.
1
2
3
4
5
LineData lineData = new LineData(lineDataSet);
// 라인 데이터의 텍스트 컬러 / 사이즈를 설정할 수 있다.
// 물론 나는 사용하지 않았다.
lineData.setValueTextColor(ContextCompat.getColor(getContext(), R.color.black));
lineData.setValueTextSize(9);
  • 또한, 추가적으로 x축, y축에 대한 label과 텍스트, 갯수 등을 설정할 수 있다.
1
2
3
4
5
// x축 설정
view.setLineData(lineData);
xAxis = view.getXAxis(); // x축에 대한 정보를 View로부터 받아온다.
xAxis.setPosition(XAxis.XAxisPosition.BOTTOM); // x축 표시에 대한 위치 설정으로 아래쪽에 위치시킨다.
xAxis.setTextColor(R.color.black); // x축 텍스트 컬러 설정
  • y축에 대한 설정은 왼쪽과 오른쪽 따로 제공하고 있기 때문에 각각 가져와서 사용하지 않는 방향은 비활성화 하는 것이 좋다.
1
2
3
4
5
6
7
8
9
10
// y축 설정

yLAxis = view.getYLeftAxis(); // y축 왼쪽 데이터 가져오기.
yLAxis.setTextColor(R.color.black); // y축 텍스트 컬러 설정

// y축 오른쪽 비활성화
yRAxis = view.getYRightAxis();
yRAxis.setDrawLabels(false);
yRAxis.setDrawAxisLine(false);
yRAxis.setDrawGridLines(false);
  • 위에는 기본적인 설정과 같다. 그리고 구글에 검색하면 쉽게 찾아볼 수 있는 글이다. 이제 x축과 y축을 사용하고 싶은 데이터로 custom하게 사용하는 방법을 정리하려고 한다.
  • 먼저, x축에 내가 원하는 요일들을 설정하기 위해서 아래와 같은 클래스를 만들어준다. IAxisValueFormatter 인터페이스를 구현한다.
1
2
3
4
5
6
7
8
9
10
11
12
public class GraphAxisValueFormatter implements IAxisValueFormatter{
private String[] mValues;
// 생성자 초기화
GraphAxisValueFormatter(String[] values){
this.values = values;
}

@Override
public String getFormattedValue(float value, AxisBase axis){
return mValues[(int) value];
}
}
  • 위와 같은 클래스를 만든다. 그리고 아래와 같이 custom 클래스를 지정하여줌으로써 x축의 데이터를 재가공한다.
1
2
xAxis.setValueFormatter(new GraphAxisValueFormatter(mDays));
// mDays는 요일을 가지고 있는 String 배열
  • 그렇다면 y축의 데이터를 재가공하기 위해서는 어떻게 하면될까?? 방법은 x축과 똑같다.
1
2
3
4
5
6
7
8
9
10
11
12
13
public class GraphYAxisValueFormatter implements IAxisValueFormatter {
private String[] mEmojis;

// 생성자 초기화
GraphYAxisValueFormatter(String[] values) {
this.mEmojis = values;
}

@Override
public String getFormattedValue(float value, AxisBase axis) {
return mEmojis[(int) value];
}
}
  • y축의 데이터를 재가공하기 위해서 custom하게 만든 클래스를 지정하면 된다.
1
2
yLAxis.setValueFormatter(new GraphYAxisValueFormatter(mEmojis));
// mEmojis는 이모지를 가지고 있는 배열

2. y축 데이터 재가공

  1. y축에 icon 삽입
    y축의 데이터를 재가공 하기 위해서 일단 y축의 이미지를 넣어야 한다는 생각으로 접근을 했다. 그래서 구글링을 통해서 MpAndroidChart에 이미지 혹은 icon을 삽입한 그래프를 찾아보았다. 일단, LineChart는 찾아볼 수 없었고, BarChart, PieChart에서는 손가락 안에 꼽을 수 있을 정도로 발견할 수 있었다.

  2. 라이브러리 커스텀
    그래서 라이브러리를 파헤쳐서 커스텀을 해보자는 마음을 먹었다. (어리석은 생각이었다.) 그래서 BarChart를 통해 이미지를 넣은 것을 보고 이를 토대로 LineChart를 커스텀하기로 마음을 먹었지만, LineChart에서는 이미지를 그릴 수 있는 메소드를 찾지 못했다.

  3. y축 데이터에 이모지에 대한 유니코드 삽입
    두 개의 방법이 실패하고 제일 처음 생각했지만, 위에서 언급하지 않았던 방법인 이모지에 대한 유니코드 값을 넣어서 간단하게 구현해보는 방법이다. 처음에 이모지에 대한 유니코드를 넣어서 확인해보았는데, 적용이 되지 않아서 실패라고 생각을 했었다. 하지만, 갓자이너 여자친구의 도움으로 다른 사이트를 알았다.

이 사이트에서 이모지에 대한 유니코드 값을 얻어서 그래프의 y축에 데이터를 재가공하였더니 이모지가 정상적으로 들어가는 것을 확인할 수 있었다. :)

3. 중복과 간격 문제

위의 2번까지의 과정을 해결하고 나니 내가 원하는 데이터로 재가공하여 그래프를 표현할 수 있게 되었다. 하지만, y축의 이모지 데이터가 중복해서 나오는 현상을 마주하게 되었다…

이 문제는 도대체 왜 그러는 것일까라는 의문을 가지고 구글링을 하고 커스텀을 위한 Class에서 return 하기 전에 로그 값을 찍는데 value가 float이라서 int로 캐스팅하는 과정에서 값이 손실되어서 같은 인덱스가 여러 번 참조되어 중복되는 것이라고 판단을 하게 되었다.

그래서 이를 해결할 수 있는 방법이 무엇이 있을까 생각해보고 이 라이브러이의 issue 탭에서 실마리를 찾아보고자 했다. 아니나 다를까 비슷한 문제를 직면한 사람을 찾을 수 있었다. 또한, 이에 대한 답변도 존재했다.

답변은 다음과 같았다. y축의 Max / Min 값을 지정하고 증가 간격(세분성) 설정을 true로 지정하고 세분 간격을 1.0f로 설정해주었다. 그리고 빌드를 해보니 내가 원하는 것처럼 이모지가 하나씩 증가하면서 나타나는 것을 확인할 수 있었다.

느낀점

외부 라이브러리를 사용할 때는 정말로 star가 많은 것을 사용하자. 분명 내가 직면한 문제를 먼저 경험한 개발자들이 있을 것이다. issue 탭에서 문제와 답을 찾을 수 있으니 포기는 휴지통에 버리자.

참고