Swift Charts will not display the last x-axis AxisValueLabel with AxisMarks
Asked Answered
S

3

9

I am using the new swift charts framework to display some data. In seeking to manually control the frequency of the x-axis AxisValueLabels, as well as adjust the color, I implemented the following:

.chartXAxis {
    AxisMarks(values: .automatic(desiredCount: 11, roundLowerBound: true, roundUpperBound: true)) { _ in
        AxisGridLine(stroke: .init(lineWidth: 1)).foregroundStyle(Color.orange)
        AxisValueLabel().foregroundStyle(Color.orange).font(.subheadline).offset(x: -10)
    }
}

I would like to show on value for each x-axis value (there are 11 points and it is only showing 10). I have tried countless things and can not get it to show as it should by adjusting the desiredCount parameter. Would appreciate any help in this matter..

import Charts
import Foundation
import SwiftUI

struct FakeData: Codable {
    var questionAndAnswers: [Int: Int]
    var timePerQuestion: [Double]
    var date: Date = .now
}

extension FakeData {
    static let oneFakeInstance = FakeData(questionAndAnswers: [1875: 1875,
                                                               1890: 1890,
                                                               1980: 1980,
                                                               2112: 2112,
                                                               2726: 2726,
                                                               4088: 4088,
                                                               4284: 4284,
                                                               4784: 4784,
                                                               4800: 4800,
                                                               663: 663,
                                                               1098: 1098], timePerQuestion: [
            28.700000000000138,
            11.600000000000165,
            12.00000000000017,
            25.599999999999376,
            11.999999999999318,
            19.19999999999891,
            12.799999999999272,
            7.199999999999605,
            11.699999999999335,
            39.299999999997766, 19.299999999997766
        ])
}

struct CH1: View {
    func convertToShowable(_ QuizquestionAnswers: [Int: Int] = FakeData.oneFakeInstance.questionAndAnswers, _ quizTimes: [Double] = FakeData.oneFakeInstance.timePerQuestion) -> [Int: Double] {
        var time_per_question: [Int: Double] = [:]
        for (index, key_value) in QuizquestionAnswers.enumerated() {
            if key_value.value == key_value.key {
                time_per_question[index] = quizTimes[index]
            }
        }
        return time_per_question
    }
    
    var body: some View {
        ZStack {
            Color.black.edgesIgnoringSafeArea(.all)
        
            VStack {
                Chart {
                    ForEach(convertToShowable().sorted(by: { $0.key < $1.key }), id: \.key) { key, value in
                        BarMark(x: .value("Question", key),
                                y: .value("Time", value))
                            .foregroundStyle(Color.white)
                    }
                }
                .chartYAxis {
                    AxisMarks(values: .automatic) { _ in
                        AxisValueLabel().foregroundStyle(Color.orange).offset(x: 10).font(.subheadline)
                    }
                }
                
                .chartXAxis {
                    AxisMarks(values: .automatic(desiredCount: 11, roundLowerBound: true, roundUpperBound: true)) { _ in
                        AxisGridLine(stroke: .init(lineWidth: 1)).foregroundStyle(Color.orange)
                        AxisValueLabel().foregroundStyle(Color.orange).font(.subheadline).offset(x: -10)
                    }
                }
                
                .frame(width: 350, height: 250)
            }
        }
    }
}

You can see there should be a 10 here, but there is nothing:

enter image description here

Salient answered 28/10, 2022 at 20:19 Comment(0)
M
3

try this to display your 11 points:

 .chartXScale(domain: 0...11)
Mujik answered 28/10, 2022 at 22:59 Comment(0)
S
7

Using AxisMarks(preset: .aligned, values: .. is what you're looking for. Then you can drop the offsets as well.

Solanum answered 2/11, 2022 at 10:46 Comment(0)
M
3

try this to display your 11 points:

 .chartXScale(domain: 0...11)
Mujik answered 28/10, 2022 at 22:59 Comment(0)
G
0

You can declare AxisMarks with preset: .aligned to align the label. Here's an example how I list all values as indices and map that to my items data array

Chart {}
.chartXAxis {
    let values = Array(0..<logs.count)
    AxisMarks(preset: .aligned, position: .bottom, values: values) { value in
        if let log = logs[safe: value.index] {
            AxisValueLabel(multiLabelAlignment: .center) {      
                Text(log.startedAt.formatted(.dateTime.day().month()))
            }
        }
    }
}
Genesis answered 6/8 at 21:15 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.