SwiftUI에서 그래프와 차트 만들기: 데이터 시각화

작성일 :

SwiftUI에서 그래프와 차트 만들기: 데이터 시각화

SwiftUI는 Apple 플랫폼에서 사용자 인터페이스(UI)를 쉽게 만들 수 있는 프레임워크입니다. 데이터 시각화는 앱 개발에서 점점 더 중요한 역할을 하고 있습니다. 이 글에서는 SwiftUI를 사용하여 그래프와 차트를 만들어 데이터를 시각화하는 방법을 자세히 탐구하겠습니다.

기본 차트 만들기

SwiftUI에서 차트를 만들기 위해서는 우선 @State@Binding 등의 속성을 이용하여 데이터를 관리할 수 있어야 합니다. 기본적인 라인 차트를 만드는 예제를 통해 시작해보겠습니다.

swift
import SwiftUI

struct LineChartView: View {
    @State private var dataPoints: [Double] = [1, 3, 2, 5, 4]
    
    var body: some View {
        GeometryReader { geometry in
            Path { path in
                let width = geometry.size.width
                let height = geometry.size.height
                guard dataPoints.count > 1 else { return }
                let step = width / CGFloat(dataPoints.count - 1)
                path.move(to: CGPoint(x: 0, y: height - CGFloat(dataPoints[0]) * height))
                for index in 1..<dataPoints.count {
                    path.addLine(to: CGPoint(x: CGFloat(index) * step, y: height - CGFloat(dataPoints[index]) * height))
                }
            }
            .stroke(Color.blue, lineWidth: 2)
        }
        .padding()
    }
}

이 코드에서는 dataPoints 배열을 이용해 데이터 셋을 정의하고, Path를 이용해 점들을 이어서 라인 차트를 그립니다. GeometryReader를 사용하여 차트가 그려질 영역의 크기를 동적으로 받아오는 것도 중요합니다.

막대 차트 만들기

막대 차트는 데이터를 시각화하는 또 다른 유용한 방법입니다. 막대 차트를 생성하기 위해서는 사각형(사각 막대)을 그려야 합니다.

swift
import SwiftUI

struct BarChartView: View {
    var dataPoints: [Double]
    
    var body: some View {
        GeometryReader { geometry in
            HStack(alignment: .bottom, spacing: 2) {
                ForEach(0..<dataPoints.count, id: \.self) { index in
                    Rectangle()
                        .fill(Color.green)
                        .frame(width: (geometry.size.width / CGFloat(dataPoints.count)) * 0.8, height: CGFloat(dataPoints[index]) * geometry.size.height)
                }
            }
        }
        .padding()
    }
}

여기서는 HStack을 사용하여 막대를 수평으로 배치하고 Rectangle을 이용해 막대를 그립니다. 막대의 높이는 dataPoints의 값에 비례하도록 설정하였습니다.

원형 차트 만들기

원형 차트, 특히 파이 차트는 구성 요소들의 비율을 시각화할 때 유용합니다. 이는 각도의 합이 360도를 넘지 않게 설정해줘야 합니다.

swift
import SwiftUI

struct PieChartView: View {
    var dataPoints: [Double]
    var colors: [Color]
    
    var total: Double {
        dataPoints.reduce(0, +)
    }
    
    var body: some View {
        GeometryReader { geometry in
            ZStack {
                ForEach(0..<dataPoints.count, id: \.self) { index in
                    let startAngle = self.angle(for: Array(dataPoints.prefix(index)).reduce(0, +), in: geometry.size)
                    let endAngle = self.angle(for: dataPoints[index], in: geometry.size) + startAngle
                    Path { path in
                        path.move(to: CGPoint(x: geometry.size.width / 2, y: geometry.size.height / 2))
                        path.addArc(center: .init(x: geometry.size.width / 2, y: geometry.size.height / 2), radius: geometry.size.width / 2, startAngle: startAngle, endAngle: endAngle, clockwise: false)
                    }
                    .fill(self.colors[index % self.colors.count])
                }
            }
        }
        .aspectRatio(1, contentMode: .fit)
        .padding()
    }
    
    func angle(for value: Double, in size: CGSize) -> Angle {
        return .degrees((value / total) * 360.0)
    }
}

이 코드는 각 데이터 포인트의 비율을 계산하여 파이 차트를 그립니다. PathaddArc를 사용하여 각 조각을 그리며, fill 메서드를 통해 색을 채웁니다.

데이터 업데이트 반영하기

실시간으로 데이터가 변경될 때 차트를 업데이트해야 할 경우, @StateCombine 프레임워크를 사용할 수 있습니다.

swift
import SwiftUI
import Combine

class DataModel: ObservableObject {
    @Published var dataPoints: [Double] = [1, 3, 2, 5, 4]

    func updateData() {
        // 데이터를 갱신하는 로직
    }
}

struct LineChartWithUpdates: View {
    @ObservedObject var dataModel = DataModel()

    var body: some View {
        LineChartView(dataPoints: dataModel.dataPoints)
            .onAppear {
                Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { _ in
                    self.dataModel.updateData()
                }
            }
    }
}

이 예제에서는 ObservableObject를 채택한 DataModel 클래스를 생성하고, @Published 속성을 사용하여 데이터가 변경될 때 뷰가 업데이트되도록 했습니다. Timer를 통해 주기적으로 데이터를 갱신하는 방법도 포함되었습니다.

결론

SwiftUI를 이용하면 그래프와 차트를 손쉽게 만들고 데이터를 시각화할 수 있습니다. 이번 글에서는 라인 차트, 막대 차트, 원형 차트를 만드는 방법을 탐구했으며, 실시간 데이터 업데이트를 반영하는 방법도 소개했습니다. 이러한 기법을 활용하여 더욱 직관적이고 데이터 중심적인 애플리케이션을 개발해 보세요.