...
본문 바로가기

iOS

SwiftUI - Charts 기본 라이브러리 사용해보기

 

목차

     

     

    차트를 그리고싶어서 해당 기본 라이브러리를 사용해보았다. 

    iOS 16부터 가능하다고 한다. ( macOS도 13부터 가능하다고한다..! )

     

     

    Developer 문서에보면 굉장히 쉽게 사용할 수 있게 되어있다.

     

     

    기본적인 바 차트

     

     

    각 바마다 스택으로도 보여줄수 있음 😧

    https://developer.apple.com/documentation/charts/creating-a-chart-using-swift-charts#Explore-additional-data-properties

     

     

     

    요렇게 각 부서마다 날짜별로 이익률을 한번에 같이 보여줄 수도 있다.... 😧

    https://developer.apple.com/documentation/charts/chart#Controlling-data-series-inside-a-chart

     

     

     

    간단 코드 

    이 링크에서 예제코드가 있다. 굉장히 간단하여 대충 어떤 느낌인지 알수있다. 

     

     

    코드는 간단해보인다. 차트를 보여주려면 데이터가 필요하니, 

    데이터 타입과, 차트를 그려주는 뷰로. 

    각 Cube, Sphere, Pyramid 장난감이 있고, 개수가 있다. 그걸 바차트로 그린 코드

    struct ToyShape: Identifiable {
        var type: String
        var count: Double
        var id = UUID()
    }
    
    
    struct ContentView: View {
        
        var data: [ToyShape] = [
            .init(type: "Cube", count: 5),
            .init(type: "Sphere", count: 4),
            .init(type: "Pyramid", count: 4)
        ]
        
        var body: some View {
            Chart {
                ForEach(data) { shape in
                    BarMark(
                        x: .value("Shape Type", shape.type),
                        y: .value("Total Count", shape.count)
                    )
                    .foregroundStyle(.red)
                }
            }
        }
    }
    
    
    struct ContentView_Previews: PreviewProvider {
        static var previews: some View {
            ContentView()
        }
    }

     

     

    실행결과 

     

     

    그래프 -  ChartContent  

     

    보면, Chart안에 그래프는 mark 로 의미되는 것 같다.

    mark는 여러종류가 있다. BarMark, LineMark, PlotMark.... 등등

     

    각 mark들은 ChartContent 프로토콜을 채택하고있다. 

    ( 즉, ChartContent를 채택하는 mark는 Chart안에서 그려질 수 있다라고 보면 될듯. )

     

    ChartContent를 채택하는 mark들은 다양한 moeidifers들을 사용할 수 있다. ( .foregroundStyle )

     

     

    오...그러면, 각 바마다 색을 지정할수있구나!  

     

    struct ToyShape: Identifiable {
        var type: String
        var count: Double
        var id = UUID()
        var color: Color
    }
    
    
    struct ContentView: View {
        
        var data: [ToyShape] = [
            .init(type: "Cube", count: 5, color: .red),
            .init(type: "Sphere", count: 4, color: .blue),
            .init(type: "Pyramid", count: 4, color: .yellow)
        ]
        
        var body: some View {
            Chart {
                ForEach(data) { shape in
                    BarMark(
                        x: .value("Shape Type", shape.type),
                        y: .value("Total Count", shape.count)
                    )
                    .foregroundStyle(shape.color)
                }
            }
        }
    }

     

    😧

     

     

    데이터 타입 -  PlottableValue,  Plottable

     

    각 mark들이 보여줄 데이터는  PlottableValue 타입이여야한다. 

    BarMark 이니셜라이즈할때 보면, x, y가 각각 타입이 PlottableValue<Plottable> 로 되어있다. 

     

    PlottableValue타입은 간단하게 static func value 로 이니셜라이즈 가능하다.

    ( 그러므로, 위에 코드에서 x, y 값에 .value로 간단하게 초기화가능했던것. )

     

     

    PlottableValue타입에서, data는 Plottable 을 채택해야 한다.

     

    Plottable은 기본 타입인, Double, Date, String 이면 바로 사용 가능하다. 

    ( 그러므로 위에서  ToyShape 타입에서 사용한 프로퍼티들이 바로 사용이 가능했던 것 ) 

     

    그러므로, Plottable 채택하는 커스텀타입으로 사용할수도 있다. 

     

    바차트의 x를 구분하는 모양을 enum으로 바꿔서 아래처럼 적용해볼 수도 있겠다. 

     

    enum ToyType: String, Plottable {
        case cube = "큐브"
        case sphere = "구"
        case pyramid = "피라미드"
    }
    
    struct ToyShape: Identifiable {
        var color: String
        var type: ToyType
        var count: Double
        var id = UUID()
    }
    
    
    struct ContentView: View {
        var stackedBarData: [ToyShape] = [
            .init(color: "Green", type: .cube, count: 2),
            .init(color: "Green", type: .sphere, count: 0),
            .init(color: "Green", type: .pyramid, count: 1),
            .init(color: "Purple", type: .cube, count: 1),
            .init(color: "Purple", type: .sphere, count: 1),
            .init(color: "Purple", type: .pyramid, count: 1),
            .init(color: "Pink", type: .cube, count: 1),
            .init(color: "Pink", type: .sphere, count: 2),
            .init(color: "Pink", type: .pyramid, count: 0),
            .init(color: "Yellow", type: .cube, count: 1),
            .init(color: "Yellow", type: .sphere, count: 1),
            .init(color: "Yellow", type: .pyramid, count: 2)
        ]
    
        var body: some View {
            Chart {
                ForEach(stackedBarData) { shape in
                    BarMark(
                        x: .value("Shape Type", shape.type),
                        y: .value("Total Count", shape.count)
                    )
                    .foregroundStyle(by: .value("Shape Color", shape.color))
                }
            }
            .chartForegroundStyleScale([
                "Green": .green, "Purple": .purple, "Pink": .pink, "Yellow": .yellow
            ])
    
        }
    }