Using Swift Charts on a SwiftUI app
Learn how to use the Swift Charts framework to present charts on a SwiftUI app.
Introduced at WWDC22, Swift Charts allows you to create rich charts in your SwiftUI application. With this framework, developers can represent data in different forms of visualization with just a few lines of code.
This tutorial will explore the Swift Charts framework to plot your data with the available chart views and how to customize them to represent data effectively.
We will begin by defining our data source and from there we will dive into the implementation process, step by step, guiding you through each stage of creating a chart based on your data.
By the end, you will be able to convert raw data into a clear and engaging manner making information easy to understand and interpret for users.
Before we start
To follow this tutorial you need a basic understanding of SwiftUI and be comfortable writing code using the Swift programming language.
Create a new SwiftUI app project on Xcode and follow the steps.
Step 1 - Define the data model
The first step in creating a chart is to identify the data that will be represented. In this case, we will use a model that stores the average weather for each month. This model will help us visualize the temperature variations throughout the year.
Let’s define a data structure that represents the average temperature for each month. Create a structure called AverageTemperature
on a new Swift file.
- Create a new file called
AverageTemperature.swift
; - Create a new struct named
AverageTemperature
that conforms to theIdentifiable
protocol; - Add the properties
month
andtemperature
as variables of the typeString
andDouble
, respectively;
Step 2 - Create the data source
Once we have defined the AverageTemperature
struct, we can create a ViewModel
class to initialize an array to hold the temperature data.
- Create a new file called
ViewModel.swift
; - Create an observable class named
ViewModel
; - Create a new property called
data
as an array ofAvarageTemperature
and populate it;
Step 3 - Chart implementation
Now that we have created a data collection we need to define the type of chart with which we want to represent this data.
To do this, create a new SwiftUI view and import the Charts framework. In the view body, we will add the Chart
view component, which will act as a container for the series of data we want to represent.
For this project, we will use a LineMark
chart.
- The
Chart
view creates a view that displays a chart. It can be composed of any number of data series and individual marks; - Using the
LineMark
chart type we represent our data using a sequence of connected line segments; - In the
LineMark
initializer, we define that the value represented in the X-axis will be themonth
and that the value represented in the Y-axis will be thetemperature
. They were both defined in the first step of the tutorial;
The data used by the chart content is of the type PlottableValue
which takes a label and a value.
In addition to LineMark
Swift Charts support a comprehensive collection of chart structures including PointMark
, AreaMark
, RectangleMark
, and more. Try experimenting with the different visualizations to find the one that best suits your needs.
Customizing charts is crucial for effective data visualization. On Swift Charts we can modify axes, plot area, and the charts themselves to create an appealing and clear chart that communicates our data effectively.
Let’s see how we can further customize our chart to improve the way the data is rendered.
Step 4 - Customizing the X-axis
On our chart, the label on the x-axis represents each month. However, in some cases, the label is too long and we can’t read the text properly.
We can customize this, as well as other aspects of the x-axis, using the chartXAxis(content:)
modifier.
Chart(dataCollection.data) {
...
}
// 1.
.chartXAxis {
// 2.
AxisMarks { value in
// 2a.
AxisValueLabel {
if let month = value.as(String.self) {
Text(month.prefix(3))
}
}
// 2b.
AxisTick(stroke: StrokeStyle(lineWidth: 1))
.foregroundStyle(Color.gray)
// 2c.
AxisGridLine(centered: true).foregroundStyle(.gray)
}
}
.padding()
.frame(height: 200)
- Use the
chartXAxis(content:)
modifier to apply customization to the x-axis of a chart; - Using the
,
AxisMarks
struct we configure the appearance of the chart's axes using visual marks. In this case, we are usingAxisValueLabel
,AxisTick
andletters
marks:AxisValueLabel
: used to display only the first three lettersmonth's
of the month valueAxisTick
: used to display a divider between each labelAxisGridLine
: used to customize the vertical lines of the chart
Step 5 - Customizing the Y-axis
As we did with the X-axis, we can use the chartYAxis(content:)
modifier to customize the marks of the y-axis on the chart. In addition to that, we can also limit the range of y-axis values by employing the .chartYScale(domain:type:)
modifier.
Chart {
...
}
.chartXAxis { ... }
// 1.
.chartYAxis {
AxisMarks { value in
AxisValueLabel {
if let temperature = value.as(Double.self) {
Text("\\(temperature.formatted())°")
}
}
AxisTick(stroke: StrokeStyle(lineWidth: 2))
.foregroundStyle(Color.gray)
AxisGridLine(centered: true, stroke: StrokeStyle(lineWidth: 0.5)).foregroundStyle(.gray)
}
}
// 2.
.chartYScale(domain: 0...35)
.padding()
.frame(height: 200)
- Using the
chartYAxis(content:)
to apply customization to the y-axis of a chart; - Using the
chartYScale(domain:type:)
modifier we're constraining the chart's domain to span from 0 to 35, meaning that the minimum value on the axis will be 0 and the maximum will be 35;
Experiment with changing the range of the domain to see how it affects the plotted chart visually.
Step 6 - Customizing the plot area
We have customized the axes of the chart, now let’s work on customizing how the data is represented in the chart.
We will customize characteristics like the chart’s background, add symbols to each mark, and modify how the line and area marks are plotted.
Chart(dataCollection.data) {
LineMark(
x: .value("Month", $0.month),
y: .value("Total", $0.temperature)
)
// 1.
.symbol {
Circle()
.fill(Color.black.opacity(0.6))
.frame(width: 8)
}
}
.chartXAxis { ... }
.chartYAxis { ... }
.chartYScale(domain: 0...35)
.padding()
.frame(height: 200)
- Using the
.symbol
modifier we can add additional visual information that can improve the readability of our chart data. In this case, we added a circle to theLineMark
chart;
LineMark(
x: .value("Month", $0.month),
y: .value("Total", $0.temperature)
)
.symbol {
Circle()
.fill(Color.black.opacity(0.6))
.frame(width: 8)
}
// 1.
.interpolationMethod(.catmullRom)
- Using the
.interpolationMethod(_:)
modifier we can modify how the chart plots line and area marks. In this case, we used the.catmullRom
interpolation method to make the line smoother;
Chart(dataCollection.data) {
...
}
.chartXAxis { ... }
.chartYAxis { ... }
.chartYScale(domain: 0...35)
// 1.
.chartPlotStyle { plotArea in
plotArea
.background(.mint.opacity(0.03))
.border(.mint)
}
.padding()
.frame(height: 200)
- With the
chartPlotStyle(content:)
modifier we can access the plot area and customize some of its characteristics like the chart’s background or the border;
Step 7 - Adding multiple chart content in a Chart view
Sometimes we want to highlight a specific threshold on our charts. We can do that by combining different chart contents inside the same Chart
view.
Let’s add a RuleMark
in our chart to visualize the months in which the average temperature was higher than 20 degrees.
Chart(dataCollection.data) {
LineMark(
x: .value("Month", $0.month),
y: .value("Total", $0.temperature)
)
.symbol { ... }
.interpolationMethod(.catmullRom)
// 1.
RuleMark(y: .value("Temperature", 20.0))
// 2.
.annotation(alignment: .leading) {
Text("20 degrees").bold()
.foregroundStyle(.secondary)
}
}
- Adding the
RuleMark
view inside theChart
anchored on a value of the Y axis; - You can add a visual annotation to the mark with the
annotation(position:alignment:spacing:content:)
modifier;
Final Result
The Swift Charts framework makes integrating charts on your SwiftUI applications a simple and straightforward process.
Now you are ready to create stunning charts with your data. If you want to go deeper into communicating information with clarity and visual appeal check the following resources from the Human Interface Guidelines.