- Pie Chart Using SwiftUI - Graphs Using SwiftUI - SwiftUI Tutorials(11:27)
- ```swift // // TodayPreviewView.swift // Today_3x3 (iOS) // // Created by kidstyo on 2022/4/19. //
import SwiftUI
/ 今日分析 / struct TodayPreviewView: View { var body: some View { VStack{ ZStack{ HStack{ Button {
} label: {
Image(systemName: "line.horizontal.3")
.resizable()
.frame(width: 20, height: 15)
.foregroundColor(.black)
}
Spacer()
Button {
} label: {
Image(systemName: "bell.fill")
.foregroundColor(.black)
}
}
Text("My Usage")
.fontWeight(.bold)
}
.padding(.top, UIApplication.shared.windows.first?.safeAreaInsets.top)
.padding()
.overlay {
Rectangle().stroke(Color.black.opacity(0.05), lineWidth: 2)
}
// create pie chart
GeometryReader { g in
ZStack{
ForEach(0..<pieData.count){i in
DrawShape(center: CGPoint(x: g.frame(in: .global).width / 2, y: g.frame(in: .global).height / 2), index: i)
// Path{path in // path.move(to: CGPoint(x: UIScreen.main.bounds.width / 2, y: UIScreen.main.bounds.height / 2)) // path.addArc(center: CGPoint(x: UIScreen.main.bounds.width / 2, y: UIScreen.main.bounds.height / 2), radius: 180, startAngle: .zero, endAngle: .init(degrees: 90), clockwise: false) // } // .fill(Color.yellow) } } } .frame(height: 360) .padding(.top, 20) .clipShape(Circle()) .shadow(radius: 8)
// since it is in circle shape so were going to clip it in circle...
// since radius is 180 so circle size will be 360
VStack{
ForEach(pieData){i in
HStack{
Text(i.name)
.frame(width: 100)
// fixed width...
GeometryReader { g in
HStack{
Spacer(minLength: 0)
Rectangle()
.fill(i.color)
.frame(width: getWidth(width: g.frame(in: .global).width, value: i.percent), height: 10)
Text(String(format: "\(i.percent)", "%.0f"))
.fontWeight(.bold)
.padding(.leading, 10)
}
}
}
.padding(.top, 18)
}
}
.padding()
Spacer()
}
.edgesIgnoringSafeArea(.top)
}
func getWidth(width: CGFloat, value : CGFloat) -> CGFloat{
let temp = value / 100
return temp * width
}
}
struct DrawShape: View{ var center: CGPoint var index : Int
var body: some View{
Path{path in
path.move(to: self.center)
path.addArc(center: self.center, radius: 180, startAngle: .init(degrees: from()), endAngle: .init(degrees: to()), clockwise: false)
}
.fill(pieData[index].color)
}
func from() -> Double{
if index <= 0{
return 0
}
var temp : Double = 0
for i in 0...index-1{
temp += Double(pieData[i].percent / 100) * 360
}
return temp
}
func to() -> Double{
var temp : Double = 0
// because we need current degree
for i in 0...index{
temp += Double(pieData[i].percent / 100) * 360
}
return temp
}
}
struct TodayPreviewView_Previews: PreviewProvider { static var previews: some View { TodayPreviewView() } }
// sample data struct Pie : Identifiable{ var id : Int var percent: CGFloat var name: String var color: Color }
var pieData = [ Pie(id: 0, percent: 10, name: “测试”, color: Color.green), Pie(id: 1, percent: 20, name: “墨鱼🦑”, color: Color.red), Pie(id: 2, percent: 15, name: “工作”, color: Color.purple), Pie(id: 3, percent: 50, name: “学习”, color: Color.gray), Pie(id: 4, percent: 5, name: “睡眠”, color: Color.yellow), ] ```