.chartXScale not scaling domain of Chart as expected

Hi,

I'm currently wrestling with the .chartXScale(domain:) modifier in order to get my Chart to display correctly. The basics of the Chart look like this.

Chart(measurements, id: \.timestamp) { measurement in
    if let total = measurement.production?.total {
        BarMark(
            x: .value(
                "Timestamp",
                measurement.timestamp,
                unit: .weekOfYear,
                calendar: .current
            ),
            y: .value(
                "Solar production",
                 total
             )
         )
     }
}

As anyone familiar with Charts can see, I sort data into columns based on what week of the year the measurements belong to. Some of them can be null, and when they are, I still want space in the Chart where a BarMark would've been to be taken up, like week number 4 in this example chart (in which I've defaulted all measurements that are null in week 4 to 0, for demonstration purposes):

To achieve that, as I understand, I'm meant to use the .chartXScale(domain:) modifier, but when I apply the following modifier...

.chartXScale(domain: firstDayOfMonth...firstDayOfNextMonth)

... (where the domain is from the first day of the month to the first day of the next month), to the code above, I end up with this weird half step when the last week of measurements are all null:

For reference, here's how the domain dates are set in my minimum reproducible example:

firstDayOfMonth = Calendar.current.date(from: Calendar.current.dateComponents([.year, .month], from: .now))!

firstDayOfNextMonth = Calendar.current.date(byAdding: .month, value: 1, to: firstDayOfMonth)!

Am I misusing this modifier somehow, or is this a bug? Would love some help figuring this out, thanks!

Answered by AppleCare Staff in 794848022

Currently, the bar placement is conditional (non-nil total). Can you make it unconditional, such that nils get mapped to zero values?

Currently, the bar placement is conditional (non-nil total). Can you make it unconditional, such that nils get mapped to zero values?

Currently, the bar placement is conditional (non-nil total). Can you make it unconditional, such that nils get mapped to zero values?

My intention is to differentiate between nil and 0. nil would mean there's data missing, and 0 would mean there technically is data present, the total value of the measurements is just 0.

So if I understand your question correctly, my answer would be: No, sadly not.

Got it, I see what you want. But I'm not sure I understand the full setup. The code on the top uses .weekOfYear and then the domain is not set to week boundaries but to month boundaries, and it's not clear to me how the two relate in your use. Have you a small, single self-contained example with data in place? You can even use tuples in an array like [(date0, value0), ...]

Got it, I see what you want. But I'm not sure I understand the full setup. The code on the top uses .weekOfYear and then the domain is not set to week boundaries but to month boundaries, and it's not clear to me how the two relate in your use. Have you a small, single self-contained example with data in place? You can even use tuples in an array like [(date0, value0), ...]

I apologize if things are not clear. It might simply be because I don't have a full understanding of how I'm supposed to use the modifier. Let me try and break it down.

My data set is an array of one measurement per day in a month (so I have about ~30 entries per array, naturally). This is the reason I try to set the domain of the chart from the first day in a month, to the last day in a month. I figured with that, the Chart would understand the timespan I'm trying to plot (no matter if I sort it all by .weekOfYear or not). Is that not the case? Should I set the domain in some different way when sorting the data by weekOfYear?

I'm not sure I get the last sentence? Tuples for the domain?

I do have an Xcode project with a minimum reproducible example, but I guess I can't share it here directly. Should I file a feedback with it, or share it in some other way?

The easiest thing would be to paste a self-contained piece of code with data that demonstrates the problem, eg. an array of tuples like this:

Chart([(id: 0, time: ..., value: ...), (id: 1, time: ..., value: nil), ...], id: \.id) {
    BarMark(...)...
}.chartXScale(...)

No need for an entire repo, just a minimal, but runnable example that exhibits the issue.

.chartXScale not scaling domain of Chart as expected
 
 
Q