반응형
flutter-paint

Flutter CustomPainter 및 차트 그려보기

 

  • custom painter란?
  • canvas, paint
  • drawLine 등 메소드 사용해보기
  • 그래프 그려보기

 

이 글에 쓰인 소스 코드는 Github 에서찾아보실 수 있습니다.


플러터를 쓰다보니 입맛에 딱 맞는 그래프 라이브러리가 없더군요.

그래서 커스텀 페인터를 공부해서 직접 차트를 만들어보고 있습니다.

그 과정에서 정리한 걸 공유하려고 합니다!

글을 마칠 때는 아래 같은 차트를 그릴 수 있게 될 거에요.

flutter_graph_resize

그럼 시작해 볼께요.

 

1.CustomPainter 란?

커스텀 페인터는 화면에 직접 UI를 그릴 때 사용합니다. 기존의 UI로 만들기 어려운 화면을 만들고 싶을 때 유용해요.

개인적으론 그래프를 그릴 때 사용했습니다.

직접 UI를 그릴려면 CustomPaint와 CustomPainter 클래스가 있어야 합니다.

용어가 비슷해서 헷갈리는데 정리해볼께요.

 

1.1CustomPainter와 CustomPaint

CustomPaint는 Container나, Center 같은 위젯이에요.

CustomPaint는 CustomPainter를 담는 그릇이라고 보면 됩니다.

 

  • CustomPaint

    • Container나, Center 같은 위젯입니다.
    • painter를 갖고 있습니다. painter에게 화면을 그리도록 합니다.
    • painter -> child -> foregroundPainter 순으로 화면을 그립니다.
  • CustomPainter

    • canvas, paint, size등을 통해 실제 화면을 그릴 때 쓰인다.
    • 선 그리기 (drawLine), 원 그리기 (drawCircle) 등 다양한 그리기 함수를 지원합니다.

 

정의만 보니 어떤 뜻인지 잘 모르겠죠?

실제 코드로 확인해 볼께요.

화면에 직선을 그리는 코드입니다.

완성되면 아래 그림처럼 나올 거에요.

 

 

flutter_01

 

 

1.2.1 CustomPainter - 스크린에 선 긋기

 

일단 CustomPainter 클래스를 정의해볼께요.

CustomPainter는 paint(Canvas canvas, Size size)shouldRepaint(CustomPainter oldDelegate)를 구현해야합니다.

 

  • paint()는 화면을 그릴 때 사용합니다. 화면을 새로 그릴때마다 호출되죠.
  • shouldRepaint()는 화면을 새로 그릴지 말지 정합니다. 예전에 위젯의 좌표값과 비교해, 좌표값이 변했을 때 그린다든지 원하는 대로 조건을 줄 수 있죠.

 

paint(Canvas canvas, Size size) 은 canvas 객체를 써서 화면을 그립니다.

canvas는 다양한 그리기용 함수를 지원합니다. 선그리기, 사각형 그리기 등 다양하죠.

canvas는 항상 Paint클래스를 객체로 받는데요. Paint 클래스는 화면이 어떤식으로 그려질지 정합니다.

 

그럼 방금 만든 MyPainter() 클래스를 사용해 보겠습니다.

 

1.2.2 CustomPaint 위젯

 

CustomPaint() 위젯에 좀 전에 만든 MyPainter() 클래스를 넣어주면 됩니다.

 

flutter_01

 

그림처럼 나오면 성공입니다.

 

1.2.3 CustomPaint 위젯 - painter와 foregroundPainter의 차이

CustomPaint()는 위젯의 크기를 정하고, 어떤 painter를 쓸지 결정합니다.

painter는 2 종류가 있습니다.

foregroundPainter, painter인데요.

위젯이 그려지는 순서와 관련이 있습니다.

 

  • painter : painter -> child 순으로 그려진다. 나중에 그려지는 위젯이 맨앞에 보인다.

flutter_02

선이 보이지 않네요. child 위젯이 가려서 그렇습니다.

 

  • foregroundPainter: child -> foregroundPainter 순으로 그려짐.

 

flutter_03

 

선이 잘 보이죠? CustomPainter(커스텀 페인터)가 child에 가려지는 걸 원치 않으면 foregroundPainter를 써주세요.

 

1.2.4 CustomPaint 위젯 - 위젯 크기 정하기

커스텀 페인트을 쓰다보면 헷갈리는 부분이 있습니다.

바로 위젯의 크기입니다.

크기가 부모나 자식 위젯때문에 쉽게 변하기에 혼란스럽죠.

위젯의 크기는 기본적으로 부모 > 자식(child) > size (CustomPaint의 속성) 값을 따릅니다.

부모가 크기가 제일 중요하고, 그 다음이 자식이고, 아무것도 없으면 size 값에 따라 위젯의 크기를 정합니다. size도 없으면 위젯이 그려지지 않습니다.

 

부모, 자식, Size()가 다 있는 경우

flutter_04

부모가 있을 때는 부모의 크기 (넓이 300, 높이 300)로 위젯이 그려집니다.

 

자식과 Size()만 있는 경우

 

flutter_05

자식이 있을 때는 자식의 크기 (넓이 150, 높이 150)로 위젯이 그려집니다.

 

 

Size()만 있는 경우

 

flutter_06

 

 

Size만 있을 때는 Size의 크기에 따라 (넓이 150, 높이 150)로 위젯이 그려집니다.

 

Size가 우선순위가 제일 낮습니다.

 

2.그래프(차트 ) 그려보기

2.1 - 파이 차트 그려보기

CustomPainter를 써서 직접 차트를 그려볼께요.

가장 먼저 그릴 차트는 파이 (원) 차트 입니다.

완성되면 아래 그림처럼 나올거에요.

 

그림 2-1. pie chart

flutter_pie_chart_r

 

프로젝트 구조는 아래와 같습니다.

ui와 chart만 있는 간단한 구조입니다.

flutter_chart_project

 

일단 main을 정의해주세요.

2.1 main.dart

 

대부분의 코드는 chart_page.dart에 작성할 거에요.

2.1 chart_page.dart

 

파이 차트는 원을 2개 그리고, 그 안에 텍스트를 그려서 만듭니다.

원을 그릴 때는 drawCircle() 와 drawArc() 함수를 사용합니다.

drawCircle()는 정해진 위치에 원을 그릴 때 쓰고,

drawArc()는 타원이나, 열린 원(끝이 닫히지 않은 원)을 그릴 때 씁니다.

 

2.1 pie_chart.dart

 

텍스트를 그리는 부분만 볼께요.

CustomPainter에 텍스트를 적으려면 꼭 TextPainter를 써야 합니다.

TextPainter()는 텍스트의 좌표를 정하는데 쓰입니다.

TextPainter를 쓸 땐 꼭 layout() 함수를 호출해줘야 합니다. 그래야 텍스트의 크기와 방향을 에서 알 수 있습니다.

TextSpan()은 기존의 Text() 위젯과 거의 동일합니다.

 

원과 글자가 제대로 나오나요?

그럼 다음에 그릴 차트는 라인 차트(선) 차트입니다.

 

2.2 라인 차트 그려보기

 

라인 차트는 아래의 그림처럼 생겼습니다.

각각의 값이 점(포인트)로 표현되고, 점들을 연결하고 있습니다.

또한 최저값이랑 최고값을 표시합니다.

 

flutter_line_chart_re

 

라인 차트는 파이 차트랑 비슷한데요.

drawArc() 대신에 drawPath()와 drawPoints() 함수를 사용합니다.

 

  • drawPath(Path path, Paint paint) 선을 그릴 때 씁니다. path에 있는 좌표를 따라서 선을 그립니다.

     

  • drawPoints(PointMode pointMode, List points, Paint paint) 은 점을 그릴 때 씁니다.

 

라인 차트에서 쓰는 주요 함수를 알아봤으니 직접 차트를 그려볼께요.

일단 chart_page.dart 에 라인 차트를 포함해주세요.

2.2 chart_page.dart

 

line_chart는 크게 4개의 함수로 되어 있습니다.

  • getCoordinates() : 좌표 구하기
  • drawText() : 텍스트 그리기
  • drawLines(): 선 그리기
  • drawPoints(): 점 그리기

 

2.2 line_chart.dart

 

 

차트가 잘 그려지나요?

 

이번엔 바 차트(막대 그래프)를 만들어보겠습니다

 

2.3. 바 차트 그려보기

바 차트는 가로와 세로에 텍스트를 적을 수 있게 만들었습니다.

연도별 제품 판매량이나 생산량 같은 걸 나타내기에 좋습니다.

 

flutter_bar_chart_02_r

 

2.3 chart_page.dart

 

바 차트는 3부분으로 되어 있습니다.

  • 좌표를 구하는 부분 - 어디다 그래프를 그릴지 정합니다.
  • 그래프를 그리는 부분 - 실제 막대 그래프를 그립니다. 그래프를 그릴 때는 drawRect() 함수를 사용합니다.
  • 텍스트를 그리는 부분 - x축과 y축에 텍스트를 그립니다. 이번엔 정해진 폰트 크기가 아니라, 화면 크기에 비례해 폰트 크기가 정해지도록 계산합니다.

 

바 차트는 길어서 설명 보다는 주석으로 대체하였습니다.

코드를 따라하면서 익히시기를 권합니다.

2.3 bar_chart.dart

 

이제 커스텀 페인터를 쓰는 데 익숙해 졌나요?

이번 글에선 직접 차트를 만들어 보았습니다.

다음 번엔 애니메이션에 대해 알아보도록 하겠습니다.


 

이 글에 쓰인 소스 코드는 Github 에서찾아보실 수 있습니다.

반응형

+ Recent posts