Skip to content

Mastering Charts: Mark Styling (SwiftUI)

A SwiftUI guide for coding agents. Also covers swift charts bar color, rounded bar corners chart, dashed line chart style, chart annotation label, grouped bars position by, catmullrom interpolation.

Swift Charts marks (AreaMark, BarMark, LineMark, PointMark, RectangleMark, RuleMark) take familiar view modifiers. Styling a chart is mostly the modifiers you already know, applied to marks.

Color, Shape, and Grouping

foregroundStyle accepts any ShapeStyle, opacity sets the alpha, clipShape reshapes a bar, and position(by:) splits a category into side-by-side bars instead of the default vertical stack. A custom enum plots once it conforms to Plottable.

extension Gender: Plottable {
  var primitivePlottable: String { rawValue }
}

Chart {
  ForEach(stats, id: \.city) { stat in
    BarMark(
      x: .value("City", stat.city),
      y: .value("Population", stat.population)
    )
    .foregroundStyle(by: .value("Gender", stat.gender))
    .clipShape(RoundedRectangle(cornerRadius: 16))
    .position(by: .value("Gender", stat.gender))
  }
}

foregroundStyle(by:) also makes the framework generate a legend automatically.

Line Styling

lineStyle takes a StrokeStyle, so dashed lines are one argument. interpolationMethod(.catmullRom) curves the line instead of drawing straight segments. A RuleMark draws a threshold line across the plot.

Chart {
  RuleMark(y: .value("Limit", 50))

  ForEach(Array(numbers.enumerated()), id: \.offset) { index, value in
    LineMark(x: .value("Index", index), y: .value("Value", value))
      .interpolationMethod(.catmullRom)
      .lineStyle(StrokeStyle(lineWidth: 1, dash: [2]))

    PointMark(x: .value("Index", index), y: .value("Value", value))
  }
}

Annotations Are SwiftUI Views

Every mark takes an annotation modifier with a ViewBuilder, placing a real view next to the data point. Position, alignment, and spacing are parameters.

BarMark(
  x: .value("City", stat.city),
  y: .value("Population", stat.population)
)
.annotation(position: .bottom, alignment: .trailing, spacing: 16) {
  Text(verbatim: stat.population.formatted())
    .font(.caption)
}

Annotations can sit above, below, or overlay the mark. Use them sparingly, or the chart drowns in labels.

Use this guidance in your coding agent

Install the Better Design MCP once. Your agent then loads this page with one call.

get-swiftui-guide({ topic: "swiftui-mastering-charts-mark-styling" })
claude mcp add --scope user better-design --transport http https://better-design.com/api/mcp --header "Authorization: Bearer <YOUR_API_KEY>"
Browse related design systems