Tüm Yazılar
KategoriSwiftUI
Okuma Süresi
16 dk
Yayın Tarihi
2024-05-05
Kelime Sayısı
1.226kelime

Kahveni hazırla - bu içerikli bir makale!

SwiftUI Charts ile Data Visualization

Özet

iOS 16+ Charts framework ile etkileyici grafikler oluşturun. Line, bar, pie chart örnekleri ve custom styling.

  • iOS 16 Swift Charts framework'ü SwiftUI'da native grafik oluşturmayı kolaylaştırır.
  • BarMark, LineMark, AreaMark, PointMark, SectorMark, RuleMark, RectangleMark mark tipleri var.
  • chartOverlay + DragGesture ile interaktif tooltip ve en yakın veri noktası seçimi yapılır.
  • accessibilityLabel/accessibilityValue ile VoiceOver desteği ve dark mode uyumlu renkler eklenir.
SwiftUI Charts ile Data Visualization

Apple'ın iOS 16 ile tanıttığı Swift Charts framework'ü, SwiftUI ile native grafik oluşturmayı inanılmaz kolaylaştırıyor. Bu rehberde, çeşitli chart türlerini ve advanced customization tekniklerini inceleyeceğiz.


İçindekiler


Swift Charts - Chart Turleri Karsilastirmasi

Chart Turu
Mark Tipi
Kullanim Alani
Veri Tipi
Performans
Bar Chart
BarMark
Kategori karsilastirma
Ayrik
Mukemmel
Line Chart
LineMark
Trend analizi, zaman serisi
Surekli
Iyi
Area Chart
AreaMark
Hacim gosterimi
Surekli
Iyi
Point Chart
PointMark
Dagilim, scatter plot
Surekli
Orta
Pie/Donut
SectorMark
Oran gosterimi
Ayrik
Mukemmel
Rule
RuleMark
Referans cizgileri, esik deger
Sabit
Mukemmel
Rectangle
RectangleMark
Heat map, gantt chart
Aralik
Iyi
Not: 1000+ veri noktasi icin LineMark ve AreaMark tercih edin. SectorMark maksimum 7-8 dilim ile en iyi sonucu verir.

Temel Chart Yapısı

swift
1import Charts
2 
3struct SalesData: Identifiable {
4 let id = UUID()
5 let month: String
6 let revenue: Double
7 let category: String
8}
9 
10let salesData: [SalesData] = [
11 SalesData(month: "Oca", revenue: 5000, category: "Elektronik"),
12 SalesData(month: "Şub", revenue: 7500, category: "Elektronik"),
13 SalesData(month: "Mar", revenue: 6200, category: "Elektronik"),
14 SalesData(month: "Oca", revenue: 3000, category: "Giyim"),
15 SalesData(month: "Şub", revenue: 4500, category: "Giyim"),
16 SalesData(month: "Mar", revenue: 3800, category: "Giyim"),
17]
18 
19struct BasicBarChart: View {
20 var body: some View {
21 Chart(salesData) { item in
22 BarMark(
23 x: .value("Ay", item.month),
24 y: .value("Gelir", item.revenue)
25 )
26 .foregroundStyle(by: .value("Kategori", item.category))
27 }
28 .frame(height: 300)
29 .padding()
30 }
31}

Line Chart

swift
1struct StockData: Identifiable {
2 let id = UUID()
3 let date: Date
4 let price: Double
5}
6 
7struct LineChartView: View {
8 let data: [StockData]
9 @State private var selectedData: StockData?
10
11 var body: some View {
12 Chart {
13 ForEach(data) { item in
14 LineMark(
15 x: .value("Tarih", item.date),
16 y: .value("Fiyat", item.price)
17 )
18 .interpolationMethod(.catmullRom)
19 .foregroundStyle(
20 .linearGradient(
21 colors: [.blue, .purple],
22 startPoint: .leading,
23 endPoint: .trailing
24 )
25 )
26
27 AreaMark(
28 x: .value("Tarih", item.date),
29 y: .value("Fiyat", item.price)
30 )
31 .foregroundStyle(
32 .linearGradient(
33 colors: [.blue.opacity(0.3), .clear],
34 startPoint: .top,
35 endPoint: .bottom
36 )
37 )
38 }
39
40 if let selected = selectedData {
41 RuleMark(x: .value("Seçili", selected.date))
42 .foregroundStyle(.gray.opacity(0.5))
43 .lineStyle(StrokeStyle(dash: [5, 5]))
44 .annotation(position: .top) {
45 VStack {
46 Text(selected.date, format: .dateTime.day().month())
47 Text("₺\(selected.price, specifier: "%.2f")")
48 .bold()
49 }
50 .padding(8)
51 .background(.ultraThinMaterial)
52 .cornerRadius(8)
53 }
54 }
55 }
56 .chartXAxis {
57 AxisMarks(values: .stride(by: .day, count: 7)) { value in
58 AxisValueLabel(format: .dateTime.day().month())
59 }
60 }
61 .chartYAxis {
62 AxisMarks(position: .leading) { value in
63 AxisGridLine()
64 AxisValueLabel {
65 if let price = value.as(Double.self) {
66 Text("₺\(price, specifier: "%.0f")")
67 }
68 }
69 }
70 }
71 .chartOverlay { proxy in
72 GeometryReader { geometry in
73 Rectangle()
74 .fill(.clear)
75 .contentShape(Rectangle())
76 .gesture(
77 DragGesture()
78 .onChanged { value in
79 let x = value.location.x - geometry[proxy.plotAreaFrame].origin.x
80 if let date: Date = proxy.value(atX: x) {
81 selectedData = data.min(by: {
82 abs($0.date.timeIntervalSince(date)) < abs($1.date.timeIntervalSince(date))
83 })
84 }
85 }
86 .onEnded { _ in
87 selectedData = nil
88 }
89 )
90 }
91 }
92 .frame(height: 300)
93 }
94}

Pie Chart (Donut)

swift
1struct ExpenseCategory: Identifiable {
2 let id = UUID()
3 let name: String
4 let amount: Double
5 let color: Color
6}
7 
8struct DonutChartView: View {
9 let expenses: [ExpenseCategory] = [
10 ExpenseCategory(name: "Kira", amount: 5000, color: .blue),
11 ExpenseCategory(name: "Market", amount: 2500, color: .green),
12 ExpenseCategory(name: "Ulaşım", amount: 1500, color: .orange),
13 ExpenseCategory(name: "Eğlence", amount: 1000, color: .purple),
14 ExpenseCategory(name: "Diğer", amount: 800, color: .gray),
15 ]
16
17 var body: some View {
18 Chart(expenses) { expense in
19 SectorMark(
20 angle: .value("Tutar", expense.amount),
21 innerRadius: .ratio(0.6),
22 angularInset: 2
23 )
24 .foregroundStyle(expense.color)
25 .cornerRadius(5)
26 .annotation(position: .overlay) {
27 Text(expense.name)
28 .font(.caption)
29 .foregroundColor(.white)
30 }
31 }
32 .frame(height: 300)
33 }
34}

Interactive Charts

swift
1struct InteractiveChartView: View {
2 @State private var selectedCategory: String?
3 @State private var rawSelectedDate: Date?
4
5 var body: some View {
6 Chart {
7 ForEach(salesData) { item in
8 BarMark(
9 x: .value("Ay", item.month),
10 y: .value("Gelir", item.revenue)
11 )
12 .foregroundStyle(by: .value("Kategori", item.category))
13 .opacity(selectedCategory == nil || selectedCategory == item.category ? 1 : 0.3)
14 }
15 }
16 .chartLegend(position: .bottom, spacing: 20)
17 .chartForegroundStyleScale([
18 "Elektronik": Color.blue,
19 "Giyim": Color.pink
20 ])
21 .chartXSelection(value: $rawSelectedDate)
22 .animation(.easeInOut, value: selectedCategory)
23 }
24}

Custom Annotations

swift
1struct AnnotatedChartView: View {
2 var body: some View {
3 Chart {
4 ForEach(data) { item in
5 PointMark(
6 x: .value("X", item.x),
7 y: .value("Y", item.y)
8 )
9 .symbolSize(100)
10 .annotation(position: .top) {
11 Text("\(item.y, specifier: "%.1f")")
12 .font(.caption2)
13 .foregroundColor(.secondary)
14 }
15 }
16 }
17 }
18}

Chart Accessibility ve Dark Mode

Chart'larinizin tum kullanicilar icin erisilebilir olmasi ve dark mode'da dogru gorunmesi cok onemlidir. Apple'in accessibility API'lari ile chart verilerini VoiceOver kullanicilarina da sunabilirsiniz.

Accessible Chart Ornegi

swift
1struct AccessibleBarChart: View {
2 let data: [SalesData]
3 
4 var body: some View {
5 Chart(data) { item in
6 BarMark(
7 x: .value("Ay", item.month),
8 y: .value("Gelir", item.revenue)
9 )
10 .foregroundStyle(by: .value("Kategori", item.category))
11 .accessibilityLabel("\(item.category)")
12 .accessibilityValue("\(item.month): \(Int(item.revenue)) TL")
13 }
14 .chartForegroundStyleScale([
15 "Elektronik": Color.blue,
16 "Giyim": Color.pink
17 ])
18 // Dark mode uyumlu renkler
19 .chartPlotStyle { plotArea in
20 plotArea
21 .background(Color(.systemBackground).opacity(0.5))
22 .border(Color(.separator), width: 0.5)
23 }
24 .frame(height: 300)
25 }
26}

Dark Mode Uyumlu Renk Paleti

swift
1extension Color {
2 // Chart icin adaptive renkler
3 static let chartPrimary = Color("ChartPrimary") // Assets'te tanimli
4 static let chartSecondary = Color("ChartSecondary")
5 
6 // Programmatic adaptive renkler
7 static func adaptiveChartColor(light: Color, dark: Color) -> Color {
8 // SwiftUI otomatik olarak colorScheme'e gore secer
9 return Color(uiColor: UIColor { traitCollection in
10 traitCollection.userInterfaceStyle == .dark
11 ? UIColor(dark)
12 : UIColor(light)
13 })
14 }
15}
16 
17// Kullanim
18struct ThemedChart: View {
19 @Environment(\.colorScheme) var colorScheme
20 
21 var body: some View {
22 Chart(data) { item in
23 BarMark(
24 x: .value("Ay", item.month),
25 y: .value("Gelir", item.revenue)
26 )
27 .foregroundStyle(
28 colorScheme == .dark
29 ? Color.cyan.gradient
30 : Color.blue.gradient
31 )
32 }
33 }
34}
VoiceOver kullanicilari icin accessibilityChartDescriptor protokolunu kullanarak chart'inizin genel bir ozetini de sunabilirsiniz. Bu, gorme engelli kullanicilarin veri trendlerini anlamasini saglar.

Sonuç

Swift Charts, iOS uygulamalarında veri görselleştirmeyi inanılmaz kolaylaştırıyor. Declarative syntax, SwiftUI entegrasyonu ve zengin customization seçenekleri ile profesyonel grafikler oluşturabilirsiniz.

Easter Egg

Gizli bir bilgi buldun!

Bu bölümde gizli bir bilgi var. Keşfetmek ister misin?

Okuyucu Ödülü

Tebrikler! Bu yazıyı sonuna kadar okuduğun için sana özel bir hediyem var:

ALTIN İPUCU

Bu yazının en değerli bilgisi

Bu ipucu, yazının en önemli çıkarımını içeriyor.

Etiketler

#SwiftUI#Charts#Data Visualization#iOS#Swift Charts
Muhittin Çamdalı

Muhittin Çamdalı

Lead Mobile Engineer

12+ yıllık deneyime sahip Lead Mobile Engineer. Swift, SwiftUI, Kotlin ve Flutter ile iOS, Android ve cross-platform mimarilerde uzman. Performanslı ve kullanıcı dostu mobil uygulamalar geliştiriyorum.

iOS Geliştirme Haberleri

Haftalık Swift tips, SwiftUI tricks ve iOS best practices. Spam yok, sadece değerli içerik.

Onay e-postasındaki bağlantıyı açıp “Aboneliğimi onayla” düğmesine bastığında aboneliğin başlar. Bültende açılma/tıklama istatistikleri tutulur; dilediğin an tek tıkla ayrılabilirsin. Gizlilik

Paylaş

İlgili İçerik