SwiftUI Charts - BarMark

SDTCOW·2025년 2월 20일

SwiftUI - Charts

목록 보기
1/3

안녕하세요.
오늘은 SwiftUI Charts 라이브러리 중 막대그래프인 BarMark의 사용법에 대해 적어보려 합니다.

먼저 BarMark는 WWDC 2022에서 소개된 SwiftUI Charts 라이브러리 중 하나로, 막대그래프를 간단하게 구현할 수 있도록 도와줍니다.
이전까지 SwiftUI에서 차트를 그리려면 CoreGraphics, SwiftUI Shape, UIViewRepresentable 등을 활용해야 했지만,
SwiftUI Charts를 사용하면 보다 간결하게 데이터 시각화가 가능합니다.

오늘은 몸무게 변화 데이터를 시각화하는 막대그래프를 만들어보겠습니다.

이번 예제에서는 다음과 같은 기능을 구현할 예정입니다.
1. 일주일 동안의 몸무게 변화 막대그래프
2. 막대그래프 내부에 Text(몸무게) 표시
3. 막대그래프 위에 Text(몸무게) 표시
4. 사용자가 막대그래프를 드래그하면 해당 날짜가 표시

먼저 결과 사진부터 보겠습니다.

  1. 우선, 날짜와 몸무게 데이터를 저장할 구조체(TempData)를 만들겠습니다.
struct TempData {
    let date: Date
    var dateStr: String {
        get {
            let dateFormatter = DateFormatter()
            dateFormatter.dateFormat = "MM-dd"
            
            return dateFormatter.string(from: self.date)
        }
    }
    let weight: Double
}
  • date → Date 타입으로 날짜를 저장
  • dateStr → DateFormatter를 사용해 날짜를 "MM-dd" 형식의 문자열로 변환
  • 몸무게 값 저장
  1. 데이터는 onAppear를 활용해 오늘을 기준으로 7일 전까지 랜덤한 몸무게 값을 생성하여 tempDatas 배열에 저장했습니다.
struct BarChartView: View {
    @State var tempDatas: [TempData] = []
    
    var body: some View {
        VStack {}
        .padding()
        .onAppear {
            let today = Date()
            let calendar = Calendar.current
            tempDatas = (0..<7).compactMap {
                if let date = calendar.date(byAdding: .day, value: -6 + $0, to: today) {
                    return TempData(date: date,
                             weight: Double.random(in: 60...80))
                }
                return nil
            }
        }
    }
}
  • compactMap을 사용하여 옵셔널 Date? 값을 언래핑을 통해 TempData로 변환했습니다.
  1. 이제 준비된 데이터를 기반으로 막대그래프를 그려볼 차례입니다. SwiftUI Charts에서 그래프를 만들려면 Chart {} 블록 안에 BarMark를 추가하면 됩니다.
    각 데이터를 반복하며 그래프를 그릴 수 있도록 ForEach로 tempDatas의 데이터를 순회하면서 BarMark를 추가할겁니다.
Chart {
	// id: 데이터의 unique key 값 여기서는 날짜가 고유한 값이니까 date로 지정
	ForEach(tempDatas, id: \.date) { data in
		BarMark(x: .value("Date", data.dateStr),
        		y: .value("Weight", data.weight))
			.foregroundStyle(Color.green)
	}
}
  • x: .value("Date", data.dateStr) → x축 값으로 날짜(data.dateStr) 지정
  • y: .value("Weight", data.weight) → y축 값으로 몸무게(data.weight) 지정

    💡 .value를 사용하면 SwiftUI Charts가 이 데이터를 숫자로 변환하고, 자동으로 적절한 축을 생성해 줍니다.
    만약 .value 없이 데이터를 직접 x와 y에 할당하려고 하면 차트가 제대로 동작하지 않습니다.

  1. 코드를 합치면 아래와 같습니다.
import SwiftUI
import Charts

struct BarChartView: View {
    @State var tempDatas: [TempData] = []
    
    var body: some View {
        VStack {
            Chart {
                ForEach(tempDatas, id: \.date) { data in
                    BarMark(
                        x: .value("Date", data.dateStr),
                        y: .value("Weight", data.weight)
                    )
                    .foregroundStyle(Color.green)
                }
            }
        }
        .padding()
        .onAppear {
            let today = Date()
            let calendar = Calendar.current
            tempDatas = (0..<7).compactMap {
            	// calendar.date가 Date?의 옵셔널 타입을 리턴하기 때문에 옵셔널 언래핑을 사용했습니다.
                if let date = calendar.date(byAdding: .day, value: -6 + $0, to: today) {
                    return TempData(date: date,
                             weight: Double.random(in: 60...80))
                }
                return nil
            }
        }
    }
}

struct TempData {
    let date: Date
    var dateStr: String {
        get {
            let dateFormatter = DateFormatter()
            dateFormatter.dateFormat = "MM-dd"
            
            return dateFormatter.string(from: self.date)
        }
    }
    let weight: Double
}

이제 일주일 동안의 몸무게 변화를 보여주는 막대그래프를 만들었습니다!
다음 게시글에는 막대 안에 텍스트 추가, 드래그 기능 추가 등을 알아보겠슴다.

감사합니다.

profile
iOS 개발자가 되고싶은 사람

0개의 댓글