Bar Mark Formatting Options

Bar Mark Formatting Options

In this chapter, we’ll explore the various formatting options available for BarMark in Swift Charts. We will learn how to adjust color, size, corner radius, opacity, and more—giving us full control over the look and feel of our charts. These formatting tools not only enhance aesthetics but also help convey meaning more effectively through visual cues.

Coloring the Bars

We can use the foregroundStyle modifier to change the color of bars. Since the foregroundStyle modifier accepts a ShapeStyle type parameter, we can use gradient colors instead of solid colors for our bar charts.

import Charts

struct Workout: Identifiable {
    var id = UUID()
    var day: String
    var minutes: Double
}

extension Workout {
    static let workouts: [Workout] = [
        Workout(day: "Mon", minutes: 32),
        Workout(day: "Tue", minutes: 45),
        Workout(day: "Wed", minutes: 56),
        Workout(day: "Thu", minutes: 15),
        Workout(day: "Fri", minutes: 65),
        Workout(day: "Sat", minutes: 8),
        Workout(day: "Sun", minutes: 10),
    ]
}

struct ChartsExampleView: View {
    var body: some View {
        VStack {
            Text("DevTechie.com")
                .font(.largeTitle)
            Chart(Workout.workouts) { workout in
                BarMark(
                    x: .value("Day", workout.day),
                    y: .value("Min", workout.minutes)
                )
                .foregroundStyle(.indigo.gradient) // bar color
            }
            .frame(height: 200)
        }
    }
}

In this case, all of our bars are colored with the same indigo color, but we can customize that by fetching the color value from the model. To do this, we’ll add a color property inside the Workout model and update the sample data to provide a color for each of the sample entries.

struct Workout: Identifiable {
  var id = UUID()
  var day: String
  var minutes: Double
  var color: Color
}

extension Workout {
  static let workouts: [Workout] = [
    Workout(day: "Mon", minutes: 32, color: .orange),
    Workout(day: "Tue", minutes: 45, color: .red),
    Workout(day: "Wed", minutes: 56, color: .pink),
    Workout(day: "Thu", minutes: 15, color: .mint),
    Workout(day: "Fri", minutes: 65, color: .cyan),
    Workout(day: "Sat", minutes: 8, color: .indigo),
    Workout(day: "Sun", minutes: 10, color: .blue),
  ]
}

Once we’ve added the color property inside the model, we’re ready to use it within the chart.

struct ChartsExampleView: View {
    var body: some View {
        VStack {
            Text("DevTechie.com")
                .font(.largeTitle)
            Chart(Workout.workouts) { workout in
                BarMark(
                    x: .value("Day", workout.day),
                    y: .value("Min", workout.minutes)
                )
                .foregroundStyle(workout.color.gradient)
            }
            .frame(height: 200)
        }
    }
}

#Preview {
  ChartsExampleView()
}

Let’s use the mesh gradients(introduced in WWDC24) for our example.

Creating a mesh gradient involves specifying the width and height of the gradient, positions for each color, and the colors to display. While positions can be specified using SIMD2<Float> for performance, we can also use arrays of X/Y unit positions.

For example, here’s how to create a 2x2 box with four colors:

MeshGradient(width: 2, height: 2, points: [
  [0, 0], [1, 0], [0, 1], [1, 1]
], colors: [workout.color, .purple, .teal, .yellow])

Update the foregroundStyle modifier to include the mesh gradient.

.foregroundStyle(MeshGradient(width: 2, height: 2, points: [
  [0, 0], [1, 0], [0, 1], [1, 1]
], colors: [workout.color, .purple, .teal, .yellow]))

Code should look like this

struct ChartsExampleView: View {
    var body: some View {
        VStack {
            Text("DevTechie.com")
                .font(.largeTitle)
            Chart(Workout.workouts) { workout in
                BarMark(
                    x: .value("Day", workout.day),
                    y: .value("Min", workout.minutes)
                )
                .foregroundStyle(MeshGradient(width: 2, height: 2, points: [
                    [0, 0], [1, 0], [0, 1], [1, 1]
                ], colors: [workout.color, .purple, .teal, .yellow]))
            }
            .frame(height: 200)
        }
    }
}

#Preview {
    ChartsExampleView()
}

The foregroundStyle modifier has another overloaded function that accepts a PlottableValue as a parameter. The Charts framework automatically selects colors for the bars, making them easily distinguishable.

struct ChartsExampleView: View {
    var body: some View {
        VStack {
            Text("DevTechie.com")
                .font(.largeTitle)
            Chart(Workout.workouts) { workout in
                BarMark(
                    x: .value("Day", workout.day),
                    y: .value("Min", workout.minutes)
                )
                .foregroundStyle(by: .value("Day", workout.day))
            }
            .frame(height: 200)
        }
    }
}

If you look closely, you’ll notice a new Legend view has been added to the screen. When you first create a chart with different foreground styles, the chart legends automatically appear. These legends display the names and colors of each data series. The legend text is based on the nominal values of the chart.

ClipShape

The clipShape modifier in Swift Charts can be used to mask a BarMark to a specific shape, effectively clipping the bar to that shape. This allows us to create visually interesting and customized bar charts with non-rectangular shapes.

Let’s try the clipShape modifier to transform BarMarks into rounded rectangle shapes.

import Charts
import SwiftUI

struct Workout: Identifiable {
    var id = UUID()
    var day: String
    var minutes: Double
    var color: Color
}

extension Workout {
    static let workouts: [Workout] = [
        Workout(day: "Mon", minutes: 32, color: .orange),
        Workout(day: "Tue", minutes: 45, color: .red),
        Workout(day: "Wed", minutes: 56, color: .pink),
        Workout(day: "Thu", minutes: 15, color: .mint),
        Workout(day: "Fri", minutes: 65, color: .cyan),
        Workout(day: "Sat", minutes: 8, color: .indigo),
        Workout(day: "Sun", minutes: 10, color: .blue),
    ]
}

struct ChartsExampleView: View {
    var body: some View {
        VStack {
            Text("DevTechie.com")
                .font(.largeTitle)
            Chart(Workout.workouts) { workout in
                BarMark(
                    x: .value("Day", workout.day),
                    y: .value("Min", workout.minutes)
                )
                .foregroundStyle(by: .value("Day", workout.day))
                .clipShape(.rect(cornerRadius: 10)) // rounded rect
            }
            .frame(height: 200)
        }
    }
}

#Preview {
    ChartsExampleView()
}


Let’s try out other shapes as well.

Capsule:

struct ChartsExampleView: View {
  var body: some View {
    VStack {
      Text("DevTechie.com")
        .font(.largeTitle)
      Chart(Workout.workouts) { workout in
        BarMark(
          x: .value("Day", workout.day),
          y: .value("Min", workout.minutes)
        )
        .foregroundStyle(by: .value("Day", workout.day))
        .clipShape(.capsule)
      }
      .frame(height: 200)
    }
  }
}

Ellipse:

struct ChartsExampleView: View {
  var body: some View {
    VStack {
      Text("DevTechie.com")
        .font(.largeTitle)
      Chart(Workout.workouts) { workout in
        BarMark(
          x: .value("Day", workout.day),
          y: .value("Min", workout.minutes)
        )
        .foregroundStyle(by: .value("Day", workout.day))
        .clipShape(.ellipse)
      }
      .frame(height: 200)
    }
  }
}

Circle:

struct ChartsExampleView: View {
  var body: some View {
    VStack {
      Text("DevTechie.com")
        .font(.largeTitle)
      Chart(Workout.workouts) { workout in
        BarMark(
          x: .value("Day", workout.day),
          y: .value("Min", workout.minutes)
        )
        .foregroundStyle(by: .value("Day", workout.day))
        .clipShape(.circle)
      }
      .frame(height: 200)
    }
  }
}

Conclusion

Swift Charts gives us an impressive degree of control over the visual styling of BarMark, allowing us to move far beyond basic rectangular bars. In this chapter, we explored how to enhance the appearance of bar charts by customizing color with foregroundStyle, applying mesh gradients for richer visuals, and experimenting with shape clipping to create unique chart designs. Whether we are building charts for fitness data, financial dashboards, or habit tracking, these formatting tools allow us to present information in a way that’s both visually appealing and contextually meaningful.

Mastering Charts Framework in SwiftUI & iOS 18

Buy nowLearn more

Introduction

  • Introduction to Swift Charts
  • Benefits of Using Swift Charts Over Other Libraries
  • Getting Started with Chart view
  • Marks in Swift Charts

Bar Charts using BarMark

  • Bar Chart using BarMark
  • Bar Marks with Dynamic Data
  • Bar Mark Formatting Options
  • Bar Chart Foreground Style Scale
  • Enhance Bar Charts with Annotations
  • Stacked Bar Chart
  • Multi-Series Bar Chart
  • Custom Bar Placement in BarMark

Line Charts using LineMark

  • Creating Line Charts with LineMark
  • Annotating a Line Chart
  • Multi-Series Line Chart

Area Charts using AreaMark

  • Area Charts
  • Multi-Series Area Chart

RectangleMark in Charts Framework

  • Rectangle Mark in SwiftUI

Point Charts using PointMark

  • Point Chart for Scatter Plots

Combined Chart

  • Rule Mark & Combined Chart
  • Range Area Chart
  • Range Chart using BarMark, RectangleMark and RuleMark

SectorMarks for Pie Charts

  • Pie & Donut Charts with SectorMark
  • SwiftUI Pie & Donut Charts Quiz

Vectorized Plots

  • Vectorized Plots in Swift Charts (iOS 18)
  • AreaPlot : Vectorized Plots
  • BarPlot : Vectorized Plots
  • LinePlot : Vectorized Plots
  • PointPlot & RectanglePlot : Vectorized Plots
  • SectorPlot : Vectorized Plots

Chart Configurations

  • ChartPlotStyle, ChartBackground & ChartOverlay Customization
  • Charts Framework Legend
  • Chart Axis Content and Axis Marks
  • Chart Axis Configuration
  • Chart Scale Type
  • Chart Symbol Shape in Charts Framework
  • Align Chart’s Mark style with Chart Plot Area

Chart interactivity

  • Chart Scroll Behavior
  • Pie Chart Interaction with ChartAngleSelection
  • Chart Interaction using ChartOverlay
  • Interactive Line Chart in Swift Charts with ChartProxy and Gesture Overlay
  • Chart Gesture Modifier
  • Empty State Chart : Perfect Blend of LineMark, AreaMark and RuleMark

Animated Charts

  • Animated Bar and Line Charts
  • Animated Reveal Chart
  • Layered Chart Animation
  • Animated Pie Charts

3D Charts - Xcode 26+, iOS, macOS, visionOS, watchOS & iPadOS 26+

  • Chart3D View in Xcode 26+
  • 3D SurfacePlot Xcode 26+