Swift Charts (iOS 16) Pie / Donut Chart

Viewed 69

is it possible to create a Pie / Donut chart using Apple's new Swift Charts framework?

there are images of a pie chart shown in the WWDC videos. Any help or code sample on how to create the pie chart will be much appreciated.

Thanks

2 Answers

Swift Charts does not (yet?) support polar geometry, which is what you need to build pie charts.

I would recommend using a Canvas and drawing the information yourself, something like this:

struct Pie: View {

    @State var slices: [(Double, Color)]

    var body: some View {
        Canvas { context, size in
            let total = slices.reduce(0) { $0 + $1.0 }
            context.translateBy(x: size.width * 0.5, y: size.height * 0.5)
            var pieContext = context
            pieContext.rotate(by: .degrees(-90))
            let radius = min(size.width, size.height) * 0.48
            var startAngle = Angle.zero
            for (value, color) in slices {
                let angle = Angle(degrees: 360 * (value / total))
                let endAngle = startAngle + angle
                let path = Path { p in
                    p.move(to: .zero)
                    p.addArc(center: .zero, radius: radius, startAngle: startAngle, endAngle: endAngle, clockwise: false)
                    p.closeSubpath()
                }
                pieContext.fill(path, with: .color(color))

                startAngle = endAngle
            }
        }
        .aspectRatio(1, contentMode: .fit)
    }
}

struct Pie_Previews: PreviewProvider {
    static var previews: some View {
        Pie(slices: [
            (2, .red),
            (3, .orange),
            (4, .yellow),
            (1, .green),
            (5, .blue),
            (4, .indigo),
            (2, .purple)
        ])
    }
}

enter image description here

To make a donut chart, clip the canvas as the first thing you do in the rendering closure:

let donut = Path { p in
    p.addEllipse(in: CGRect(origin: .zero, size: size))
    p.addEllipse(in: CGRect(x: size.width * 0.25, y: size.height * 0.25, width: size.width * 0.5, height: size.height * 0.5))
}
context.clip(to: donut, style: .init(eoFill: true))

enter image description here

Yes it is possible in Apple's new swift UI by using charts, swiftUI and foundation libraries

Related