SwiftUI - Drawing a Pie Chart



A pie chart is a circular graph used to display data in circular form. This graph is divided into various slices, where each slice represents a category of data and the size represents the quantity or percentage of that category. The pie chart is commonly used to display data in a very simple form so that the user can easily compare the different parts of the whole chart. The pie chart contains the following components −

  • Slice: It represent a category pf data.
  • Labels: It labeled each slice with percentage value and category name.
  • Legend: It explains what each slice represents.
Drawing Pie Chart

SwiftUI does not provide any built-in method to create pie charts directly. So we will create a pie chart using the addArc()method and Zstack. Where Zstack is used to create different coloured slices and the addArc() method is used to calculate the starting and ending points according to the specified radius and angles, it will then create a curve in between these points and after that insert the curve in the path to create the desired shape.

Syntax

Following is the syntax−

func addArc(center: CGPoint, radius: CGFloat, startAngle: Angle, endAngle: Angle, clockwise: Bool, transform: CGAffineTransform = .identity)

Parameters

This function takes the following parameters −

  • center: The coordinates of this parameter represent the center of the arc.
  • radius: The coordinates of this parameter represent the radius of the arc.
  • startAngle: It represents the angle of the starting point of the arc. It calculates from the positive x-axis.
  • endAngle: It represents the angle of endpoint of the arc. It calculates from the positive x-axis.
  • clockwise: If the value of this parameter is set to true, then the arc will created from clockwise. Otherwise, the arc will created counterclockwise.
  • transform: It is used to apply transform to the arc before adding to the path. By default, it is set to identity transform.

Drawing Pie Chart

Now we will start drawing a pie chart. So for that, we will use the following problem statement. Suppose Mohan conducts a survey about favorite vegetables among 100 people and the results are −

  • Potato: 40%
  • Peas: 30%
  • Tomato: 20%
  • Green Chilly: 10%

Now we will create a pie chart of this survey. According to the data, a pie chart will contain four slices of four different colors, where each color represents each vegetable such as Potato representing the orange color, peas representing green color, tomatoes representing red color and green chillies representing blue color. So the following SwiftUI program will create a pie chart using the addArch() method and Zstack.

import SwiftUI

struct ContentView: View {
   var body: some View {
      ZStack {            
         Path { 
		    aPath in
               aPath.move(to: CGPoint(x: 200, y: 200))
               aPath.addArc(center: CGPoint(x: 200, y: 200), radius: 100, startAngle: Angle(degrees: -90.0), endAngle: Angle(degrees: 54.0), clockwise: false)
         }.fill(Color.orange)
            
         Path { 
            aPath in
               aPath.move(to: CGPoint(x: 200, y: 200))
               aPath.addArc(center: CGPoint(x: 200, y: 200), radius: 100, startAngle: Angle(degrees: 54.0), endAngle: Angle(degrees: 162.0), clockwise: false)
         }.fill(Color.green)            
         Path { 
		    aPath in
               aPath.move(to: CGPoint(x: 200, y: 200))
               aPath.addArc(center: CGPoint(x: 200, y: 200), radius: 100, startAngle: Angle(degrees: 162.0), endAngle: Angle(degrees: 234.0), clockwise: false)
         }.fill(Color.blue)
            
         Path { 
		    aPath in
               aPath.move(to: CGPoint(x: 200, y: 200))
               aPath.addArc(center: CGPoint(x: 200, y: 200), radius: 100, startAngle: Angle(degrees: 234.0), endAngle: Angle(degrees: 270.0), clockwise: false)
         }.fill(Color.red)
      }
   }
}

#Preview {
   ContentView()
}

Output

Drawing Pie Chart

We can customize our pie chart to make it more attractive. So we add borders and shadows on each slice. Also, add a label in a slice.

import SwiftUI

struct ContentView: View {
   var body: some View {
      ZStack {
         Path {
		    aPath in
               aPath.move(to: CGPoint(x: 200, y: 200))
               aPath.addArc(center: .init(x: 200, y: 200), radius: 100, startAngle: Angle(degrees: -90), endAngle: Angle(degrees: 54), clockwise: false)
         }.fill(Color.orange).overlay(
            Path { 
               aPath in
                  aPath.move(to: CGPoint(x: 200, y: 200))
                  aPath.addArc(center: .init(x: 200, y: 200), radius: 100, startAngle: Angle(degrees: -90), endAngle: Angle(degrees: 54), clockwise: false)
            }.stroke(Color.black, lineWidth: 2).overlay(Text("40%")
               .bold().foregroundColor(.white).offset(x: 50, y: -190)))
            
            Path { 
			   aPath in
                  aPath.move(to: CGPoint(x: 200, y: 200))
                  aPath.addArc(center: .init(x: 200, y: 200), radius: 100, startAngle: Angle(degrees: 54), endAngle: Angle(degrees: 162), clockwise: false)
            }.fill(Color.green).overlay(
               Path { 
			      aPath in
                     aPath.move(to: CGPoint(x: 200, y: 200))
                     aPath.addArc(center: .init(x: 200, y: 200), radius: 100, startAngle: Angle(degrees: 54), endAngle: Angle(degrees: 162), clockwise: false)
               }.stroke(Color.black, lineWidth: 2)
            )
            
            Path { aPath in
                aPath.move(to: CGPoint(x: 200, y: 200))
                aPath.addArc(center: .init(x: 200, y: 200), radius: 100, startAngle: Angle(degrees: 162), endAngle: Angle(degrees: 234), clockwise: false)
            }
            .fill(Color.blue)
            .overlay(
                Path { aPath in
                    aPath.move(to: CGPoint(x: 200, y: 200))
                    aPath.addArc(center: .init(x: 200, y: 200), radius: 100, startAngle: Angle(degrees: 162), endAngle: Angle(degrees: 234), clockwise: false)
                }.stroke(Color.black, lineWidth: 2))
                Path { 
				   aPath in
                      aPath.move(to: CGPoint(x: 200, y: 200))
                      aPath.addArc(center: .init(x: 200, y: 200), radius: 100, startAngle: Angle(degrees: 234), endAngle: Angle(degrees: 270), clockwise: false)
                }.fill(Color.red).overlay(
                Path { 
                   aPath in
                      aPath.move(to: CGPoint(x: 200, y: 200))
                      aPath.addArc(center: .init(x: 200, y: 200), radius: 100, startAngle: Angle(degrees: 234), endAngle: Angle(degrees: 270), clockwise: false)
                }.stroke(Color.black, lineWidth: 2))
        
      }.shadow(radius: 10)
   }
}

#Preview {
   ContentView()
}

Output

Drawing Pie Chart
Advertisements