Reputation: 9790
I am having some issues with Swift charts. I have the following Chart
which has RuleMark
. As you can see from the screenshot below the RuleMark
extends the length of the screen. I am attempting to only show the mark below the line. Something like this question is asking. If any further clarity is required let me know. The code is below.
struct Item: Identifiable {
var date: String
var count: Double
var id = UUID()
}
var data: [Item] = [
.init(date: "10AM", count: 5),
.init(date: "12AM", count: 4),
.init(date: "2PM", count: 7),
.init(date: "4PM", count: 2),
.init(date: "6PM", count: 9)
]
struct ContentView: View {
var body: some View {
Chart(data) { item in
LineMark(
x: .value("Date", item.date),
y: .value("Value", item.count)
)
PointMark(
x: .value("Date", item.date),
y: .value("Value", item.count)
)
RuleMark(
x: .value("Value", item.date)
)
}
.chartYAxis(.hidden)
}
}
Upvotes: 1
Views: 654
Reputation: 270770
Assuming the y axis value of the bottom of the plot is known, you can do:
RuleMark(
x: .value("Date", item.date),
yStart: .value("Bottom", 0), // assuming y=0 at the bottom of the chart
yEnd: .value("Value", item.count)
)
Replace 0
with whatever value the y axis has at the very bottom. Note that you can change the y axis' range using the various chartYScale
modifiers.
If the y value of the bottom of the plot is not known (e.g. you are letting SwiftUI automatically decide what scale to use depending on the data), you can use chartBackground
/chartOverlay
to draw the lines with a Path
:
.chartBackground { proxy in
if let frameAnchor = proxy.plotFrame {
GeometryReader { geo in
let frame = geo[frameAnchor]
ForEach(data) { item in
if let point = proxy.position(for: (x: item.date, y: item.count)) {
Path { p in
p.move(to: .init(x: point.x + frame.minX, y: point.y + frame.minY))
p.addLine(to: .init(x: point.x + frame.minX, y: frame.maxY))
}
.stroke(.blue, lineWidth: 1)
}
}
}
}
}
Upvotes: 3