Chart - Last (right most) x axis label not being displayed

I have a swift program that displays a chart using Chart. The code includes an X Axis Scale parameter but for some reason the last value (right most) on the x axis does not display. It should display Aug 2023. In checking the array used for the x axis labels I find that the last value is Aug 2023. I do not know how to overcome this obstacle. Any assistance will be appreciated. Below is a picture of the bottom of the chart and the code.

struct CustomChartView: View {
    
    let vm: SQLDataVM = SQLDataVM.shared

    let closingValues: [TradingDay]
    let fundName: String
    let numYears: Int

    let maxCloseStruct: TradingDay
    let maxClose: Double
    let minCloseStruct: TradingDay
    let minClose: Double
    let yIncrment: Double
    let yAxisValues: [Double]
    
    let minTimeStampStruct: TradingDay
    let minTimeStamp: Date
    var dateComponent = DateComponents()
    let maxTimeStampStruct: TradingDay
    let maxTimeStamp: Date
    var xAxisValues: [Date] = []
    
    init (fundName: String, numYears: Int) {
        self.fundName = fundName
        self.numYears = numYears
        closingValues = self.vm.QueryDatabase(fundName: fundName, numYears: numYears)
        maxCloseStruct = self.closingValues.max(by: { (tradingDay1, tradingDay2) -> Bool in
            return tradingDay1.close < tradingDay2.close
        })!
        maxClose = maxCloseStruct.close
        minCloseStruct = closingValues.min(by: { (tradingDay1, tradingDay2) -> Bool in
            return tradingDay1.close < tradingDay2.close
        })!
        minClose = minCloseStruct.close
        yIncrment = (maxClose - minClose)/4
        yAxisValues = [
            minClose,
            minClose + (1 * yIncrment),
            minClose + (2 * yIncrment),
            minClose + (3 * yIncrment),
            maxClose
        ]
        
        minTimeStampStruct = closingValues.min(by: { (tradingDay1, tradingDay2) -> Bool in
            return tradingDay1.timeStamp < tradingDay2.timeStamp
        })!
        
        minTimeStamp = minTimeStampStruct.timeStamp
        
        maxTimeStampStruct = closingValues.max(by: { (tradingDay1, tradingDay2) -> Bool in
            return tradingDay1.timeStamp < tradingDay2.timeStamp
        })!
        
        maxTimeStamp = maxTimeStampStruct.timeStamp
        
        xAxisValues.append(minTimeStamp)
        for i in 1...11 {
            dateComponent.month = i
            let nextMonth = Calendar.current.date(byAdding: dateComponent, to: minTimeStamp)
            xAxisValues.append(nextMonth!)
        }
        xAxisValues.append(maxTimeStamp)
        print("\(xAxisValues[12])")   // prints 2023-08-04 00:00:00 +0000
    } // end init
    
    var body: some View {
        
        HStack(alignment: .center) {
            VStack(alignment: .center) {
                Chart(closingValues, id:\.id) {
                    LineMark(
                        x: .value("Date", $0.timeStamp, unit: .day),
                        y: .value("Closing", $0.close)
                    )
                    .foregroundStyle(.blue)
                } // end chart
                .frame(width: 1000, height: 700, alignment: .center)

                .chartXAxisLabel(position: .bottom, alignment: .center, spacing: 15) {
                    Text("Date")
                        .font(.custom("Arial", size: 20))
                }
                .chartYAxisLabel(position: .leading, alignment: .center, spacing: 20) {
                    Text("Closing Value")
                        .font(.custom("Arial", size: 20))
                }
                
                .chartXAxis {
                    AxisMarks(values: xAxisValues) { value in
                        if let date = value.as(Date.self) {
                            AxisValueLabel(horizontalSpacing: -14, verticalSpacing: 10) {
                                VStack(alignment: .leading) {
                                    Text(ChartMonthFormatter.string(from: date))
                                        .font(.custom("Arial", size: 14))
                                    Text(ChartYearFormatter.string(from: date))
                                        .font(.custom("Arial", size: 14))
                                } // end v stack
                            } // end axis label
                        } // end if statement
                        AxisGridLine(centered: true, stroke: StrokeStyle(lineWidth: 1))
                            .foregroundStyle(Color.black)
                        AxisTick(centered: true, length: 0, stroke: .none)
                    }
                } // end chart x axis
                .chartXScale(domain: [xAxisValues[0], xAxisValues[12]])
                                
                .chartYAxis {
                    AxisMarks(position: .leading, values: yAxisValues) { value in
                        AxisGridLine(centered: true, stroke: StrokeStyle(lineWidth: 1))
                            .foregroundStyle(Color.black)
                        AxisTick(centered: true, length: 0, stroke: .none)
                        AxisValueLabel(horizontalSpacing: 10) {
                            if let yAxisValue = value.as(Double.self) {
                                let stringValue = String(format: "$%.02f", yAxisValue)
                                Text(stringValue)
                                    .font(.custom("Arial", size: 14))
                            }
                        }
                    }
                }
                .chartYScale(domain: [minClose, maxClose])
                
                .chartPlotStyle { plotArea in
                    plotArea.background(.white.opacity(0.9))
                        .border(.black, width: 1)
                } // end chart plot style
                
            } // end v stack
            .frame(width: 1200, height: 900, alignment: .center)
        } // end h stack
    } // end some view
}

Accepted Reply

After some additional research, it turns out that there are several preset styles for the Axis Marks. The aligned style is what I needed. I added that preset to the Axis Marks contained in .chartXAxis section of code. Problem solved. Below is a pic of the updated x axis labels and the updated code for .chartXAxis.

    .chartXAxis {
        AxisMarks(preset: .aligned,  values: xAxisValues) { value in
            if let date = value.as(Date.self) {
                AxisValueLabel(horizontalSpacing: -14, verticalSpacing: 10) {
                    VStack(alignment: .leading) {
                        Text(ChartMonthFormatter.string(from: date))
                            .font(.custom("Arial", size: 14))
                        Text(ChartYearFormatter.string(from: date))
                            .font(.custom("Arial", size: 14))
                    } // end v stack
                } // end axis label
            } // end if statement
            AxisGridLine(centered: true, stroke: StrokeStyle(lineWidth: 1))
                .foregroundStyle(Color.black)
            AxisTick(centered: true, length: 0, stroke: .none)
        }
    } // end chart x axis
    .chartXScale(domain: [xAxisValues[0], xAxisValues[12]])

Replies

I would check this line:

                .chartXScale(domain: [xAxisValues[0], xAxisValues[12]])

I guess, with this format, it considers an open Range.

You should specify as a closed Range.

If this may help: https://stackoverflow.com/questions/73235363/how-to-configure-axes-and-set-explicit-axis-start-and-end-points-on-a-line-chart

After some additional research, it turns out that there are several preset styles for the Axis Marks. The aligned style is what I needed. I added that preset to the Axis Marks contained in .chartXAxis section of code. Problem solved. Below is a pic of the updated x axis labels and the updated code for .chartXAxis.

    .chartXAxis {
        AxisMarks(preset: .aligned,  values: xAxisValues) { value in
            if let date = value.as(Date.self) {
                AxisValueLabel(horizontalSpacing: -14, verticalSpacing: 10) {
                    VStack(alignment: .leading) {
                        Text(ChartMonthFormatter.string(from: date))
                            .font(.custom("Arial", size: 14))
                        Text(ChartYearFormatter.string(from: date))
                            .font(.custom("Arial", size: 14))
                    } // end v stack
                } // end axis label
            } // end if statement
            AxisGridLine(centered: true, stroke: StrokeStyle(lineWidth: 1))
                .foregroundStyle(Color.black)
            AxisTick(centered: true, length: 0, stroke: .none)
        }
    } // end chart x axis
    .chartXScale(domain: [xAxisValues[0], xAxisValues[12]])