Skip to content
All essays
iOSMarch 27, 202514 min

Swift Charts Complete Guide: Data Visualization

Master Swift Charts for beautiful data visualization. Line charts, bar charts, and custom styles.

Ü
Ümit Uz
Mobile & Full Stack Developer

Swift Charts is Apple's framework for creating beautiful, interactive charts in iOS apps. Learn to visualize data effectively.

Getting Started

Basic Chart Setup

swift
import Charts
import SwiftUI

struct BasicChartView: View {
    let salesData = [
        (month: "Jan", sales: 1200),
        (month: "Feb", sales: 1450),
        (month: "Mar", sales: 1600),
        (month: "Apr", sales: 1350),
        (month: "May", sales: 1800),
        (month: "Jun", sales: 2100)
    ]

    var body: some View {
        Chart {
            ForEach(salesData, id: \.month) { item in
                BarMark(
                    x: .value("Month", item.month),
                    y: .value("Sales", item.sales)
                )
            }
        }
        .frame(height: 300)
        .padding()
    }
}

Line Charts

Simple Line Chart

swift
struct LineChartView: View {
    let data = [
        (day: "Mon", value: 65),
        (day: "Tue", value: 72),
        (day: "Wed", value: 58),
        (day: "Thu", value: 81),
        (day: "Fri", value: 75),
        (day: "Sat", value: 90),
        (day: "Sun", value: 85)
    ]

    var body: some View {
        Chart {
            ForEach(data, id: \.day) { item in
                LineMark(
                    x: .value("Day", item.day),
                    y: .value("Value", item.value)
                )
                .foregroundStyle(.blue)
                .lineStyle(StrokeStyle(lineWidth: 3))
            }
        }
        .frame(height: 300)
        .padding()
    }
}

Area Chart

swift
struct AreaChartView: View {
    let data = [
        (month: "Jan", value: 100),
        (month: "Feb", value: 120),
        (month: "Mar", value: 150),
        (month: "Apr", value: 180),
        (month: "May", value: 200)
    ]

    var body: some View {
        Chart {
            ForEach(data, id: \.month) { item in
                AreaMark(
                    x: .value("Month", item.month),
                    y: .value("Value", item.value)
                )
                .foregroundStyle(
                    LinearGradient(
                        colors: [.blue.opacity(0.5), .blue.opacity(0.1)],
                        startPoint: .top,
                        endPoint: .bottom
                    )
                )
            }
        }
        .frame(height: 300)
    }
}

Bar Charts

Vertical Bar Chart

swift
struct BarChartView: View {
    let data = [
        (category: "A", value: 45),
        (category: "B", value: 78),
        (category: "C", value: 92),
        (category: "D", value: 65),
        (category: "E", value: 83)
    ]

    var body: some View {
        Chart {
            ForEach(data, id: \.category) { item in
                BarMark(
                    x: .value("Category", item.category),
                    y: .value("Value", item.value)
                )
                .foregroundStyle(.blue)
            }
        }
        .frame(height: 300)
    }
}

Grouped Bar Chart

swift
struct GroupedBarChartView: View {
    let data = [
        (month: "Jan", productA: 100, productB: 80),
        (month: "Feb", productA: 120, productB: 95),
        (month: "Mar", productA: 90, productB: 110),
        (month: "Apr", productA: 110, productB: 105)
    ]

    var body: some View {
        Chart {
            ForEach(data, id: \.month) { item in
                BarMark(
                    x: .value("Month", item.month),
                    y: .value("Sales", item.productA)
                )
                .foregroundStyle(.blue)
                .position(by: .value("Product", "A"))

                BarMark(
                    x: .value("Month", item.month),
                    y: .value("Sales", item.productB)
                )
                .foregroundStyle(.green)
                .position(by: .value("Product", "B"))
            }
        }
        .frame(height: 300)
    }
}

Pie Charts

Basic Pie Chart

swift
struct PieChartView: View {
    let data = [
        (category: "Product A", value: 35),
        (category: "Product B", value: 25),
        (category: "Product C", value: 20),
        (category: "Product D", value: 20)
    ]

    var body: some View {
        Chart {
            ForEach(data, id: \.category) { item in
                SectorMark(
                    angle: .value("Value", item.value),
                    innerRadius: .ratio(0.5),
                    angularInset: 2
                )
                .foregroundStyle(by: .value("Category", item.category))
                .cornerRadius(5)
            }
        }
        .frame(height: 300)
        .padding()
    }
}

Advanced Features

Multi-Line Chart

swift
struct MultiLineChartView: View {
    let data = [
        (month: "Jan", productA: 100, productB: 80),
        (month: "Feb", productA: 120, productB: 95),
        (month: "Mar", productA: 90, productB: 110),
        (month: "Apr", productA: 110, productB: 105)
    ]

    var body: some View {
        Chart {
            ForEach(data, id: \.month) { item in
                LineMark(
                    x: .value("Month", item.month),
                    y: .value("Sales", item.productA)
                )
                .foregroundStyle(.blue)
                .lineStyle(StrokeStyle(lineWidth: 3))
                .symbol(by: .value("Product", "A"))

                LineMark(
                    x: .value("Month", item.month),
                    y: .value("Sales", item.productB)
                )
                .foregroundStyle(.green)
                .lineStyle(StrokeStyle(lineWidth: 3))
                .symbol(by: .value("Product", "B"))
            }
        }
        .frame(height: 300)
        .chartLegend(position: .top)
    }
}

Custom Chart Styling

swift
struct CustomChartView: View {
    let data = [
        (day: "Mon", value: 65),
        (day: "Tue", value: 72),
        (day: "Wed", value: 58),
        (day: "Thu", value: 81),
        (day: "Fri", value: 75)
    ]

    var body: some View {
        Chart {
            ForEach(data, id: \.day) { item in
                BarMark(
                    x: .value("Day", item.day),
                    y: .value("Value", item.value)
                )
                .foregroundStyle(
                    item.value > 70 ? .green : .orange
                )
                .cornerRadius(5)
            }
        }
        .chartYAxis {
            AxisMarks(position: .leading)
        }
        .chartXAxis {
            AxisMarks(position: .bottom)
        }
        .frame(height: 300)
    }
}

Interactive Charts

Drill-Down Chart

swift
struct InteractiveChartView: View {
    @State private var selectedItem: (String, Int)?

    let data = [
        (month: "Jan", sales: 1200),
        (month: "Feb", sales: 1450),
        (month: "Mar", sales: 1600)
    ]

    var body: some View {
        VStack {
            Chart {
                ForEach(data, id: \.month) { item in
                    BarMark(
                        x: .value("Month", item.month),
                        y: .value("Sales", item.sales)
                    )
                    .foregroundStyle(
                        selectedItem?.0 == item.month ? .blue : .gray.opacity(0.5)
                    )
                }
            }
            .chartAngleSelection(value: $selectedItem)
            .frame(height: 300)

            if let selected = selectedItem {
                Text("Selected: \(selected.0) - Sales: \(selected.1)")
                    .font(.headline)
            }
        }
        .padding()
    }
}

Real-Time Charts

Live Data Chart

swift
struct LiveDataChartView: View {
    @State private var data: [(timestamp: Date, value: Double)] = []
    @State private var timer: Timer?

    var body: some View {
        Chart {
            ForEach(data, id: \.timestamp) { item in
                LineMark(
                    x: .value("Time", item.timestamp),
                    y: .value("Value", item.value)
                )
                .foregroundStyle(.blue)
                .lineStyle(StrokeStyle(lineWidth: 2))
            }
        }
        .frame(height: 300)
        .onAppear {
            startUpdating()
        }
        .onDisappear {
            stopUpdating()
        }
    }

    private func startUpdating() {
        timer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { _ in
            let newValue = Double.random(in: 0...100)
            data.append((timestamp: Date(), value: newValue))

            if data.count > 60 {
                data.removeFirst()
            }
        }
    }

    private func stopUpdating() {
        timer?.invalidate()
        timer = nil
    }
}

Best Practices

  1. 1Data clarity: Keep data simple and clear
  2. 2Color choice: Use accessible colors
  3. 3Interactivity: Add meaningful interactions
  4. 4Performance: Optimize for large datasets
  5. 5Responsiveness: Handle different screen sizes
  6. 6Accessibility: Add VoiceOver support
  7. 7Labels: Provide clear labels and legends
  8. 8Updates: Update data efficiently

Swift Charts makes data visualization beautiful and easy!

Related essays

Next essay
Swift Speech Recognition: Voice Control Implementation