What would developers do if Swift never existed?
Act like disgruntled pelicans?
Jokes aside, Swift has become the vital tool of choice for developers for the benefits it brings to the table. And what works even more in Swift’s favor is the regular addition of exciting tools and features. Swift Charts is one such feature that was introduced at WWDC 2022.
Data visualization has always helped simplify complex data sets while enhancing presentation. And now, with the help of Swift Charts, developers can implement the same in their apps.
Introduction to Swift Charts
So, what is Swift Charts? It is a powerful, flexible framework that can create aesthetically pleasing charts using little code. Like SwiftUI, it uses a declarative syntax. Hence, developers familiar with SwiftUI can seamlessly use Swift Charts.
Earlier, developers had to contend with external libraries for creating charts in their apps, but not anymore.
Swift Charts also provides out-of-the-box support for dark mode, device screen sizes, dynamic types, voiceover, audio graphs, localization, and multi-platform support. This exciting framework is available for Xcode 14, while also providing support for iOS 16+, macOS 13+, Mac Catalyst 16+, tvOS 16+, and watchOS 9+.
Exploring Swift Charts
Swift Charts is fun and exciting to use, and it comes with six default chart types called Marks. The six chart types are bar, line, point, area, rule, and rectangle. Additionally, these charts are extensible; hence they can be customized.
Now, let's explore these charts with the help of an example.
Sip n Snacks is an Indian fast food restaurant that serves three types of dishes—dosa, paratha, and chaat. This restaurant is open to customers during morning and evening hours. So, let’s analyze their sales data during the weekdays with the help of charts. This analysis can help the restaurant to plan its staffing and procurement for the week as per the sales trends.
Let’s start by creating all the enum types that would be required:
FoodItemType enum with cases for dosa, paratha, and chaat as food items for sale.
WeekDaysType enum with a case for each day of the week is created.
TimingType enum with cases for morning and evening hours.
ChartType enum with cases for different chart types in Swift Charts.
So, the image below shows the model code we will be implementing.
<script>
struct RestaurantSales: Identifiable {
let weekday: WeekdaysType
let itemSales: [ItemSales]
var id: String {
return weekday.rawValue
}
}
struct ItemSales: Identifiable {
let foodItemName: FoodItemType
let sales: Int
var id: String {
return foodItemName.rawValue
}
}
enum FoodItemType: String {
case Dosa, Paratha, Chaat
}
enum WeekdaysType: String {
case Mon, Tue, Wed, Thu, Fri, Sat, Sun
}
enum TimingType: String {
case Morning, Evening
}
enum ChartType: String {
case Barchart, Linechart, Pointchart, Areachart, Rulechart, Rectanglechart
}
</script>
Code block 1: Model code
Next, we’ll create two data sets for morning and evening hours. For this, we’ll create two constants—morningSales and eveningSales, which are arrays of RestaurantSales.
So, now let’s explore the various types of charts.
Bar charts
The process to create a new chart in Swift starts off by defining a chart block. Additionally, you can also pass a data array within the rounded brackets. In this example, it is an array of RestaurantSales. Since we have to loop through the days of the week, we have to define a ForEach block for the itemSales.
Now, we can create a bar chart with a BarMark block, which will accept x and y coordinates for the graph. In this case, x axis is the days of the week while y axis is the sales numbers.
Since we need to show sales for the various food items, we’re adding a foregroundStyle modifier to the BarMark block with foodItemName. This will show different colors for each food item and Swift will automatically provide the colors for differentiation.
<script>
import SwiftUI
import Charts
struct Barchart: View {
@Binding var timing: TimingType
var data: [RestaurantSales]
var body: some View {
VStack(alignment : .leading) {
Chart(data) { series in
ForEach(series.itemSales) { item in
BarMark(
x: .value("Day", series.weekday.rawValue),
y: .value("Sales", item.sales)
)
.foregroundStyle(by: .value("Food", item.foodItemName.rawValue))
}
}
}
.frame(height: 300)
.padding()
}
}
struct Barchart_Previews: PreviewProvider {
static var previews: some View {
Barchart(timing: .constant(.Morning), data: morningSales)
}
}
</script>
Code block 4: Bar chart code
Image 1: Bar chart iPhone preview
Line, point, and rule charts
Line charts in Swift are similar to bar charts with the only difference being the code block, which is shown as LineMark.
There is also an option to superimpose a point chart on a line chart by using a shorthand modifier to the LineMark code block. In this example, we are also superimposing another chart known as the RuleMark, with which we can represent a straight line in the x or y axes. Here, its being used to indicate a breakeven point in sales on the y axis.
<script>
import SwiftUI
import Charts
struct Linechart: View {
@Binding var timing: TimingType
var data: [RestaurantSales]
var body: some View {
VStack(alignment : .leading) {
Chart(data) { series in
ForEach(series.itemSales) { item in
LineMark(
x: .value("Day", series.weekday.rawValue),
y: .value("Sales", item.sales)
)
.foregroundStyle(by: .value("Food", item.foodItemName.rawValue))
.symbol(by: .value("Food", item.foodItemName.rawValue))
}
RuleMark(
y: .value("Breakeven", 15)
)
}
}
.frame(height: 300)
.padding()
}
}
struct Linechart_Previews: PreviewProvider {
static var previews: some View {
Linechart(timing: .constant(.Morning), data: morningSales)
}
}
</script>
Code block 5: Line chart code with symbol modifier and rule chart overlay
Image 2: Line chart with symbol modifier and rule chart overlay in iPhone preview
Area chart
Like the LineMark, we can also create an area chart with an AreaMark block.
<script>
import SwiftUI
import Charts
struct Areachart: View {
@Binding var timing: TimingType
var data: [RestaurantSales]
var body: some View {
VStack(alignment : .leading) {
Chart(data) { series in
ForEach(series.itemSales) { item in
AreaMark(
x: .value("Day", series.weekday.rawValue),
y: .value("Sales", item.sales)
)
.foregroundStyle(by: .value("Food", item.foodItemName.rawValue))
}
}
}
.frame(height: 300)
.padding()
}
}
struct Areachart_Previews: PreviewProvider {
static var previews: some View {
Areachart(timing: .constant(.Morning), data: morningSales)
}
}
</script>
Code block 6: Area chart code
Image 3: Area chart iPhone preview
Rectangle chart
Like the LineMark, we can also create an area chart with an RectangleMark block.
<script>
import SwiftUI
import Charts
struct Rectanglechart: View {
@Binding var timing: TimingType
var data: [RestaurantSales]
var body: some View {
VStack(alignment : .leading) {
Chart(data) { series in
ForEach(series.itemSales) { item in
RectangleMark(
x: .value("Day", series.weekday.rawValue),
y: .value("Sales", item.sales)
)
.foregroundStyle(by: .value("Food", item.foodItemName.rawValue))
}
}
}
.frame(height: 300)
.padding()
}
}
struct Rectanglechart_Previews: PreviewProvider {
static var previews: some View {
Rectanglechart(timing: .constant(.Morning), data: morningSales)
}
}
</script>
Code block 7: Rectangle chart code
Image 4: Rectangle chart iPhone preview
The beauty of Swift Charts
Now, lets take a look at all the charts on a single screen. This can make the visual differences between the various charts easy to understand. Swift Charts provides us with automatic animations during chart transitions, but we have implemented a custom easeIn animation in this case.
<script>
import SwiftUI
import Charts
struct ContentView: View {
@State var timing: TimingType = .Morning
@State var chartType: ChartType = .Barchart
var data: [RestaurantSales] {
switch timing {
case .Morning:
return morningSales
case .Evening:
return eveningSales
}
}
var body: some View {
VStack(alignment:.leading) {
Text("Select Chart")
.font(.headline)
.fontWeight(.bold)
Picker("Select chart", selection: $chartType.animation(.easeIn)) {
Text("Bar").tag(ChartType.Barchart)
Text("Line").tag(ChartType.Linechart)
Text("Point").tag(ChartType.Pointchart)
Text("Area").tag(ChartType.Areachart)
Text("Rule").tag(ChartType.Rulechart)
Text("Rect").tag(ChartType.Rectanglechart)
}
.pickerStyle(.segmented)
Text("Sip n Snacks")
.font(.headline)
.fontWeight(.bold)
.padding(.top)
Text("Sales analysis")
.font(.subheadline)
.fontWeight(.medium)
Picker("Timing", selection: $timing.animation(.easeIn)) {
Text("Morning").tag(TimingType.Morning)
Text("Evening").tag(TimingType.Evening)
}
.pickerStyle(.segmented)
switch chartType {
case .Barchart:
Barchart(timing: $timing, data: data)
case .Linechart:
Linechart(timing: $timing, data: data)
case .Pointchart:
Pointchart(timing: $timing, data: data)
case .Areachart:
Areachart(timing: $timing, data: data)
case .Rulechart:
Rulechart(timing: $timing, data: data)
case .Rectanglechart:
Rectanglechart(timing: $timing, data: data)
}
Spacer()
}
.padding()
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
</script>
Code block 8: All charts in one screen code
Image 5: Preview for all charts on iPhone
As you can see Swift Charts is fun to use and also adds an interesting feature in iOS apps, which helps enhance user experience.
And that ends the three-part series of our adventures with Swift. So, if you’re looking for an app to be built for iOS, we’d love to hear from you and bounce ideas off together.
Sahil is an iOS engineer who constantly strives to improve his coding skills while exploring Swift programming. He enjoys watching Arsenal play and trying new fast-food joints in his spare time.
Tech Beat is the only tech briefing you need. Understand the latest trends, know how they work for business, and read the opinion of an industry thought leader. All in 5 minutes.
Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.