플러터:그래프 그리기(fl chart)
개요[편집 | 원본 편집]
Flutter에서 실시간 그래프를 그리기 위해 기본 구조를 정리한 문서.
그래프 라이브러리 선택[편집 | 원본 편집]
| 라이브러리 | 난이도 | 특징 | 공식 문서 링크 |
|---|---|---|---|
| fl_chart | 쉬움 | 가장 인기 많음, 애니메이션 최강 | • Pub.dev: https://pub.dev/packages/fl_chart
• GitHub: https://github.com/imaNNeoFighT/fl_chart |
| charts_flutter (Google) | 중간 | 구글 Material 스타일, 구조 다소 복잡 | • Pub.dev: https://pub.dev/packages/charts_flutter
• GitHub: https://github.com/google/charts |
| syncfusion_flutter_charts | 중간~어려움 | 기업용 기능 최강, 50종 이상 차트 | • 공식 Docs: https://help.syncfusion.com/flutter/charts/overview
• Pub.dev: https://pub.dev/packages/syncfusion_flutter_charts |
| graphic | 어려움 | D3.js 느낌의 선언형 그래프 | • Pub.dev: https://pub.dev/packages/graphic
• GitHub: https://github.com/entronad/graphic |
| bezier_chart | 쉬움 | 간단한 곡선 차트 | • Pub.dev: https://pub.dev/packages/bezier_chart
• GitHub: https://github.com/aeyrium/bezier-chart |
| 기타(sparkline 등) | 쉬움 | 작은 미니차트용 | • charts_sparkline: https://pub.dev/packages/charts_sparkline |
fl_chart를 이용한 실시간 그래프 구조[편집 | 원본 편집]
슬라이더 값이 변경될 때마다 그래프에 표시되는 데이터 리스트를 업데이트하는 방식이 일반적이다.
흐름[편집 | 원본 편집]
- 슬라이더 변경 → onChanged 호출
- 데이터 리스트에 새로운 값 push
- 상태 업데이트
- fl_chart가 리빌드되면서 새로운 그래프 출력
그래프 위젯 기본 구조[편집 | 원본 편집]
LineChart(
LineChartData(
lineBarsData: [
LineChartBarData(
spots: dataPoints,
isCurved: true,
barWidth: 3,
),
],
),
)
LineChartBarData 안의 속성들[편집 | 원본 편집]
| 속성 | 설명 | 비고 |
|---|---|---|
| gradient | 그래프 선의 색상이 그라데이션을 이루게끔.
왼쪽, 오른쪽 색을 순서대로 넣는다. |
gradient: LinearGradient(
colors: [Colors.blue, Colors.purple], ) |
| gridData | 눈금선 관련 | // ★ 그리드(눈금선) 제거
gridData: const FlGridData(show: false), |
| titlesData | 축 관련 | // ★ 축 글자 없애기
titlesData: const FlTitlesData( leftTitles: AxisTitles( sideTitles: SideTitles(showTitles: false), ), rightTitles: AxisTitles( sideTitles: SideTitles(showTitles: false), ), topTitles: AxisTitles( sideTitles: SideTitles(showTitles: false), ), bottomTitles: AxisTitles( sideTitles: SideTitles(showTitles: false), ), ), |
이외 점 크기, 축, 테두리 등 다양한 방식으로 꾸밀 수 있음.
fl_chart는 기본값이 “모든 축 표시 + 기본 그리드”라서 꾸미지 않으면 좀 투박함;
전체 구성 예시[편집 | 원본 편집]
https://dartpad.dev/에서 한번에 확인 가능하다.
import 'package:flutter/material.dart';
import 'package:fl_chart/fl_chart.dart';
void main() {
runApp(const GraphApp());
}
class GraphApp extends StatelessWidget {
const GraphApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
home: GraphPage(),
debugShowCheckedModeBanner: false,
);
}
}
class GraphPage extends StatefulWidget {
@override
_GraphPageState createState() => _GraphPageState();
}
class _GraphPageState extends State<GraphPage> {
double sliderValue = 50;
int time = 0;
List<FlSpot> dataPoints = [FlSpot(0, 50)]; // 처음에 점 하나를 찍어야 에러가 안남.
void _updateValue(double v) {
setState(() {
sliderValue = v;
time++;
dataPoints.add(FlSpot(time.toDouble(), v));
// 오래되면 그래프가 너무 길어지므로 50개까지만 유지
if (dataPoints.length > 50) {
dataPoints.removeAt(0);
}
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text("실시간 그래프 예제")),
body: Column(
children: [
// 그래프 영역
Expanded(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: LineChart(
LineChartData(
minY: 0,
maxY: 100,
lineBarsData: [
LineChartBarData(
spots: dataPoints,
isCurved: true,
barWidth: 3,
dotData: const FlDotData(show: false),
),
],
),
),
),
),
// 슬라이더
Padding(
padding: const EdgeInsets.all(16.0),
child: Slider(
min: 0,
max: 100,
value: sliderValue,
divisions: 20,
label: sliderValue.toStringAsFixed(0),
onChanged: _updateValue,
),
),
],
),
);
}
}
실시간 그래프 구현 시 팁[편집 | 원본 편집]
- 데이터가 너무 많아지면 성능이 떨어질 수 있으므로 일정 개수 이상 시 앞부분 제거
- UI 안정성을 위해 그래프 업데이트 주기를 제한할 수도 있음 (예: 100ms마다 적용)