[flutter/dart] bar graph 만들기

yevvon·2024년 1월 10일
0

flutter

목록 보기
8/12

오늘 최종 결과물은

이렇게 생겼습니다.

우선 그래프에 사용될 데이터 클래스를 하나 만들어주어야 합니다.

저는 individual_bar.dart 파일에 x축과 y 축을 만들어 주었습니다.

class IndividualBar{
  final int x;
  final double y;

  IndividualBar({
    required this.x,
    required this.y,
  });
}

다음으로 사용될 데이터를

graph_data.dart 파일에 데이터 값을 넣어줬습니다.

class BarData{
  final double mon;
  final double tue;
  final double wed;
  final double thu;
  final double fri;
  final double sat;
  final double sun;

  BarData({
    required this.mon,
    required this.tue,
    required this.wed,
    required this.thu,
    required this.fri,
    required this.sat,
    required this.sun,
  });

  List<IndividualBar> barData = [];
  void initializeBarData(){
    barData = [
      IndividualBar(x: 0, y: mon),
      IndividualBar(x: 1, y: tue),
      IndividualBar(x: 2, y: wed),
      IndividualBar(x: 3, y: thu),
      IndividualBar(x: 4, y: fri),
      IndividualBar(x: 5, y: sat),
      IndividualBar(x: 6, y: sun),
    ];
  }

}

내용은 간단하게 일주일로 해주었습니다.

이제 그래프 틀을 짜주어야 하는데

pubspec.yaml 파일에

fl_chart: ^0.60.0

패키지 하나 다운 받아주세요

BarChart(BarChartData(
      maxY: 250,
      minY: 0,
      gridData: FlGridData(show: true), 
      borderData: FlBorderData(show: true), 
      titlesData: FlTitlesData(
          show: true,
          topTitles: AxisTitles(sideTitles: SideTitles(showTitles: true)), 
          leftTitles: AxisTitles(sideTitles: SideTitles(showTitles: true)), 
          rightTitles: AxisTitles(sideTitles: SideTitles(showTitles: true)), 
          bottomTitles: AxisTitles(
              sideTitles: SideTitles(
                  showTitles: true, getTitlesWidget: getBottomTitles))), 
      barGroups: myBarData.barData
          .map((data) => BarChartGroupData(x: data.x, barRods: [
                BarChartRodData(
                  toY: data.y,
                  color: Colors.grey[800],
                  width: 25,
                  borderRadius: BorderRadius.circular(4),
                ),
              ]))
          .toList(),
    ));

gridData: FlGridData(show: true)

- 그래프에서 격자를 나타내 줍니다.


borderData: FlBorderData(show: true)

- 그래프의 바깥 테두리를 나타내줍니다.


FlTitlesData

- 데이터 값을 나타낼 수 있습니다.

- show: true, => 데이터를 나타낼지 선택해 주시면 됩니다. 
  만약 false로 할 경우에는 아래 내용을 따로 설정할 필요는 없습니다.


topTitles: AxisTitles(sideTitles: SideTitles(showTitles: true))

- 그래프 상단에 값을 표시할 여부를 설정합니다. 
  상단에는 0부터 설정된 값까지 인덱스 번호가 표시됩니다.


leftTitles: AxisTitles(sideTitles: SideTitles(showTitles: true))

- y 축에 나타나는 값이 왼쪽에 나타나게 합니다.


rightTitles: AxisTitles(sideTitles: SideTitles(showTitles: true))

- y 축에 나타나는 값이 오른쪽에 나타나게 합니다.


bottomTitles: AxisTitles(sideTitles: SideTitles(showTitles: true, getTitlesWidget: getBottomTitles))

- 그래프 하단에 표시할 내용입니다. 표시 내용은 위젯으로 따로 만들어 주었습니다.


왼쪽은 모두 true로 했을 때 화면이고 오른쪽은 모두 false로 했을 때 화면입니다.

이제 하단에 표시될 위젯을 만들어 주겠습니다.

Widget getBottomTitles(double value, TitleMeta meta) {
    Widget text;
    switch (value.toInt()) {
      case 0:
        text = Text("MON");
        break;
      case 1:
        text = Text("TUE");
        break;
      case 2:
        text = Text("WED");
        break;
      case 3:
        text = Text("THU");
        break;
      case 4:
        text = Text("FRI");
        break;
      case 5:
        text = Text("SAT");
        break;
      case 6:
        text = Text("SUN");
        break;
      default:
        text = Text(" ");
        break;
    }

    return SideTitleWidget(axisSide: meta.axisSide, child: text);
  }

마지막으로 그래프가 표시될 화면만 구성해 주면 됩니다.

class _GraphpageState extends State<Graphpage> {
  List<double> count = [200, 190, 150, 80, 50, 40, 5];

  @override
  Widget build(BuildContext context) {
    return Center(
      child: Container(
        padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
        child: SizedBox(
            width: 400,
            child: Column(
              children: [
                SizedBox(
                  height: 400,
                  child:  MyBarGraph(
                    count: count,
                  ),
                ),
              ],
            ),
          ),
      ),
    );
  }
}

count 리스트에 값을 넣어주었습니다. 리스트에서 값을 바꾸면 그래프에서의 y 축 값이 바뀌게 됩니다.

그리고 만들어둔 그래프를 불러와주기만 하면 됩니다.

SizedBox의 height의 값을 바꾸면서 원하는 그래프의 길이를 설정해 주시면 됩니다.

숫자가 작아지면 그래프의 간격이 좁아지고 숫자가 커지면 그래프의 간격이 늘어나게 됩니다.

높이 400인 경우와 높이 250인 경우입니다.

최종 결과물

전체코드

graph.dart

import 'package:flutter/material.dart';
import 'graph_data.dart';
import 'package:fl_chart/fl_chart.dart';

class MyBarGraph extends StatelessWidget {
  final List count;
  const MyBarGraph({
    super.key,
    required this.count,
  });

  @override
  Widget build(BuildContext context) {
    BarData myBarData = BarData(
      mon: count[0],
      tue: count[1],
      wed: count[2],
      thu: count[3],
      fri: count[4],
      sat: count[5],
      sun: count[6],
    );
    myBarData.initializeBarData();

    return BarChart(BarChartData(
      maxY: 250,
      minY: 0,
      gridData: FlGridData(show: false),
      borderData: FlBorderData(show: true), 
      titlesData: FlTitlesData(
          show: true,
          topTitles: AxisTitles(sideTitles: SideTitles(showTitles: false)),
          leftTitles: AxisTitles(sideTitles: SideTitles(showTitles: true)), 
          rightTitles: AxisTitles(sideTitles: SideTitles(showTitles: false)), 
          bottomTitles: AxisTitles(
              sideTitles: SideTitles(
                  showTitles: true, getTitlesWidget: getBottomTitles))), 
      barGroups: myBarData.barData
          .map((data) => BarChartGroupData(x: data.x, barRods: [
                BarChartRodData(
                  toY: data.y,
                  color: Colors.grey[800],
                  width: 25,
                  borderRadius: BorderRadius.circular(4),
                ),
              ]))
          .toList(),
    ));

  }

  Widget getBottomTitles(double value, TitleMeta meta) {
    Widget text;
    switch (value.toInt()) {
      case 0:
        text = Text("MON");
        break;
      case 1:
        text = Text("TUE");
        break;
      case 2:
        text = Text("WED");
        break;
      case 3:
        text = Text("THU");
        break;
      case 4:
        text = Text("FRI");
        break;
      case 5:
        text = Text("SAT");
        break;
      case 6:
        text = Text("SUN");
        break;
      default:
        text = Text(" ");
        break;
    }

    return SideTitleWidget(axisSide: meta.axisSide, child: text);
  }
}

다른 파일은 위에 있는 내용이 전체코드입니다.

0개의 댓글

관련 채용 정보