DEV Community

Andrea Sunny
Andrea Sunny

Posted on

Customizing SwiftUI Charts: Axis Lines, Styles, and Real-World Examples for iOS 16

If you’ve ever needed to turn app data into something users can quickly understand - with no messy setup or external dependencies - Apple’s Charts framework for SwiftUI (iOS 16+) is a game changer. Whether you’re tracking user stats, showing growth, or summarizing key metrics, visually rich charts are now a native part of your iOS app’s UI toolkit.

Below, I’ll break down what I learned about SwiftUI Charts after experimenting with real code and reading some excellent resources (linked below), focusing on practical usage and how you can customize things like axis lines and marks. You’ll be able to get useful visuals running fast - without leaning on third-party chart libraries.

Why Use SwiftUI Charts?

  • No extra dependencies: Charts is built right into the SwiftUI ecosystem (iOS 16+).
  • Modern, smooth UI: Native SwiftUI look and feel, automatic light/dark styling.
  • Quick to implement: Declarative syntax, highly customizable.
  • First-class axes and marks: Control axis lines, labels, gridlines, and bar/line/sector mark styles directly in code.

In short: For most in-app data viz needs, this removes a ton of friction compared to older UIKit-based (or external) solutions.

Getting Started: Import and Setup

  1. Make sure your project targets iOS 16+ and uses SwiftUI (Xcode 14+ required).
  2. Wherever you want to use charts, import the framework:
import Charts
Enter fullscreen mode Exit fullscreen mode

That’s it - no SPM/CocoaPods, just native Swift.

Example 1: Building a Simple Bar Chart

Bar charts are the best starting point for comparing categories (like monthly sales or feature adoption). You specify data points using BarMark and SwiftUI handles the layout.

struct BarChartView: View {
    var body: some View {
        Chart {
            BarMark(x: .value("Month", "Jan"), y: .value("Sales", 20))
            BarMark(x: .value("Month", "Feb"), y: .value("Sales", 30))
            BarMark(x: .value("Month", "Mar"), y: .value("Sales", 45))
        }
        .frame(height: 250)
        .padding()
    }
}
Enter fullscreen mode Exit fullscreen mode
  • Chart is the container for your data.
  • Each BarMark represents a bar (with x and y values).
  • Layout, scaling, and axis rendering are handled automatically.

You can swap in real data from arrays, databases, or APIs.

Example 2: Line Charts for Trends

For visualizing time series or progress data, use LineMark.

struct TrendLineChart: View {
    let data = [(day: "Mon", value: 120), (day: "Tue", value: 135), (day: "Wed", value: 110)]
    var body: some View {
        Chart(data, id: \ .day) { item in
            LineMark(
                x: .value("Day", item.day),
                y: .value("Value", item.value)
            )
            .foregroundStyle(.blue)
            .lineStyle(StrokeStyle(lineWidth: 2))

            PointMark(
                x: .value("Day", item.day),
                y: .value("Value", item.value)
            )
            .foregroundStyle(.blue)
        }
        .frame(height: 240)
        .padding()
    }
}
Enter fullscreen mode Exit fullscreen mode
  • Add both LineMark (for the trend) and PointMark (for data dots)
  • Useful for performance, growth, or analytics dashboards

Example 3: Pie Chart (with SectorMark)

Pie charts aren’t always the best for exact values, but are great for showing proportions.

struct PopulationPieChart: View {
    struct Country { let name: String; let population: Int }
    let data = [
        Country(name: "India", population: 1428),
        Country(name: "China", population: 1412),
        Country(name: "USA", population: 339)
    ]
    var body: some View {
        Chart(data, id: \ .name) { country in
            SectorMark(angle: .value("Population", country.population))
                .foregroundStyle(by: .value("Country", country.name))
        }
        .frame(height: 300)
        .padding()
    }
}
Enter fullscreen mode Exit fullscreen mode

Example 4: Scatter Plot

Ideal for finding correlations or outliers between two continuous variables.

struct ScatterPlot: View {
    struct DataPoint { let hours: Double; let score: Double }
    let data = [DataPoint(hours: 1, score: 85), DataPoint(hours: 2.5, score: 93)]
    var body: some View {
        Chart(data, id: \ .hours) { dp in
            PointMark(x: .value("Study Hours", dp.hours), y: .value("Score", dp.score))
        }
        .frame(height: 200)
        .padding()
    }
}
Enter fullscreen mode Exit fullscreen mode

Customizing Axes and Visual Style

The real power of SwiftUI charts comes from customizing axes and marks to fit your app design. This is where the keywords like swiftui charts axisline enter the picture. Let’s look at a bar chart with axis tweaks and better colors:

Chart(data, id: \ .x) { item in
    BarMark(
        x: .value("Month", item.x),
        y: .value("Sales", item.y)
    )
    .foregroundStyle(Color.red)
    .clipShape(RoundedRectangle(cornerRadius: 4)) // rounded bars
    .annotation(position: .overlay) {
         Rectangle().stroke(Color.black, lineWidth: 1)
    }
}
.chartXAxis {
    AxisMarks { _ in AxisGridLine(); AxisValueLabel().font(.system(size: 12)) }
    AxisLine() // Draws the axis line explicitly
}
.chartYAxis {
    AxisMarks { _ in AxisGridLine(); AxisValueLabel().font(.system(size: 12)) }
    AxisLine()
}
.frame(height: 250)
.padding()
Enter fullscreen mode Exit fullscreen mode

Customizations shown above:

  • Bar color & shape: foregroundStyle and clipShape
  • Bar outlines: Add a black stroke for clarity
  • Axis labels/font: Change with .chartXAxis/.chartYAxis and AxisValueLabel()
  • Axis lines: Drawn explicitly with AxisLine()
  • Grid lines: Shown by AxisGridLine()

Where You'll Use These Patterns

  • Dashboards: Business analytics, admin panels
  • Fitness/Activity apps: Progress, goals
  • Personal finance/budgeting tools
  • Learning/tracking apps: Anything that summarizes change over time

If you need to summarize data quickly, this API is hard to beat for speed and cleanliness.

What Developers Often Get Wrong

Even though SwiftUI charts are straightforward, a few practical mistakes crop up:

  • Forgetting to set a frame: The chart won’t show up unless you use .frame(height: ...)!
  • Mismatching data IDs: Always provide a unique id: if your data isn’t simple - especially for animated or dynamic charts.
  • Ignoring data type mismatches: X-axis and Y-axis values must match expected types. Check string vs. numeric mismatches.
  • Skipping accessibility/labels: Charts can be unreadable for assistive tech if you skip annotation or neglect labels.
  • Over-customizing early: Resist the urge to over-stylize before your base chart works - debug raw visuals first.
  • Axis line confusion: If you want axis lines visible, you need to declare them directly (AxisLine()). By default, they may not render as expected.

Key Takeaways

  • SwiftUI Charts (iOS 16+) makes native data viz fast and modern - great for most in-app charts.
  • Import the Charts library and get started immediately - no setup overhead.
  • You can build bar, line, pie, and scatter charts easily, and style them using colorful, branded, or accessible themes.
  • Axis customization (lines, grids, label styles) brings polish - use features like AxisLine(), AxisValueLabel(), and .chartXAxis/.chartYAxis.
  • Avoid common mistakes by always specifying chart frame, unique data IDs, and type-matching axis values.
  • For deeper detail or more examples: the Appxiom guide is a great reference that helped clarify the API for me.

You can now visualize insights natively, with clarity, and without third-party cruft.

Happy charting!

Top comments (0)