I'm trying to make a Swift Chart where 24 AreaMarks an hour apart on X axis over a day display a vertical gradient.
The gradient is vertical and is essentially [Color.opacity(0.1),Colour,Color.opacity(0.1]
The idea here is where the upper and lower points of each AreaMark are the same or close to each other in the Y axis, the chart essentially displays a line, where they are far apart you get a nice fading vertical gradient.
However, it seems that the .alignsMarkStylesWithPlotArea modifier is always set for AreaMarks even if manually applying it false.
Investigating further, I've learnt that with AreaMarks in a series, Swift Charts seems to only listen to the first foreground style set in. I've created some sample code to demonstrate this.
struct DemoChartView: View {
var body: some View {
Chart {
AreaMark(x: .value("Time", Date().addingTimeInterval(0)), yStart: .value("1", 40), yEnd: .value("2", 60))
.foregroundStyle(LinearGradient(colors: [.pink, .teal], startPoint: .top, endPoint: .bottom))
.alignsMarkStylesWithPlotArea(false)
AreaMark(x: .value("Time", Date().addingTimeInterval(3600)), yStart: .value("1", 44), yEnd: .value("2", 58))
.foregroundStyle(LinearGradient(colors: [.orange, .yellow], startPoint: .top, endPoint: .bottom))
.alignsMarkStylesWithPlotArea(false)
AreaMark(x: .value("Time", Date().addingTimeInterval(03600*2)), yStart: .value("1", 50), yEnd: .value("2", 90))
.foregroundStyle(LinearGradient(colors: [.green, .blue], startPoint: .top, endPoint: .bottom))
.alignsMarkStylesWithPlotArea(false)
}
}
}
Which produces this:
So here, all the different .foregroundStyle LinearGradients are being ignored AND the .alignsMarkStylesWithPlotArea(false) is also ignored - the amount of pink on the first mark is different to the second and third 🤷♂️
Has anyone encountered this. Are AreaMarks the correct choice or are they just not setup to create this type of data display. Thanks
Area marks, or other marks aren't designed for conveying quantitative information via gradient shading. If your data has distinct regions you could use the ForegroundStyle(by:) modifier and follow the example in AreaMark API docs
Another option would be to use a series of gapless RectangleMarks or BarMarks but it would look more like a stepped line not a sloped line. You might also want to experiment with MeshGradient since you have the grid points.