Search code examples
swiftswiftuiswiftcharts

Adjusting axes placement and line using Swift's Charts library


I've the following code, I would like to modify it to change the placement and display of axes, as outlined below.

Chart generation (Playground)

import SwiftUI
import Charts
import PlaygroundSupport

struct BarChartExample: View {
    let data = [
        ("A", "Z", 5),
        ("A", "Z", 5),
        ("B", "Z", 10),
        ("C", "Y", 7),
        ("D", "Y", 3),
        ("E", "Y", 12),
        ("B", "Y", 10),
        ("C", "X", 7),
        ("D", "X", 3),
        ("E", "X", 12)
    ]

    var body: some View {
        Chart {
            ForEach(data, id: \.0) { item in
                BarMark(
                    x: .value("Category", item.0),
                    y: .value("Value", item.2),
                    stacking: .standard
                )
                .foregroundStyle(by: .value("Category", item.1))
            }
        }
        .chartXAxis {
            AxisMarks {
                AxisTick(centered: true, length: 10, 
                         stroke: StrokeStyle(lineWidth: 2))
                AxisValueLabel()
            }
        }
        .frame(width: 300, height: 200)
        .padding()
    }
}

// Present the view in the Live View window
PlaygroundPage.current.setLiveView(BarChartExample())

Results

Initial Chart

Desired outcome

Chart with changes

  • I would like to move y-axis to left hand side
    • Including scales
  • Modify colour of axes and show them as white thick lines (consistently with the provided visual)

I've tried playing with AxisGridLine and AxisTick but I can't arrive at the desired result.


Solution

  • try using

    .chartYAxis {
        AxisMarks(position: .leading) 
    }
    

    EDIT-1:

    Here is a possible approach to display the X and Y axis lines as shown in your picture, using chartPlotStyle with overlay. You will have to adjust the colors.

    struct ContentView: View {
        var body: some View {
            BarChartExample()
        }
    }
    
    struct BarChartExample: View {
        let data = [
            ("A", "Z", 5),
            ("A", "Z", 5),
            ("B", "Z", 10),
            ("C", "Y", 7),
            ("D", "Y", 3),
            ("E", "Y", 12),
            ("B", "Y", 10),
            ("C", "X", 7),
            ("D", "X", 3),
            ("E", "X", 12)
        ]
    
        var body: some View {
            Chart {
                ForEach(data, id: \.0) { item in
                    BarMark(
                        x: .value("Category", item.0),
                        y: .value("Value", item.2),
                        stacking: .standard
                    )
                    .foregroundStyle(by: .value("Category", item.1))
                }
            }
            
            // the axis lines
            .chartPlotStyle { plotArea in
                plotArea
                    .overlay(alignment: .bottom) {
                        Rectangle()
                            .fill(.red)
                            .frame(height: 8)
                    }
                    .overlay(alignment: .leading) {
                        Rectangle()
                            .fill(.red)
                            .frame(width: 8)
                    }
            }
    
            .chartYAxis {
                AxisMarks(position: .leading)
            }
    
            .padding()
        }
    }