可拖动的图表选区的不透明度会根据数据点数量而变化
我在拖动时想在一个 SwiftUI Chart 中添加一个矩形。下面的代码可以工作;然而,当我增加 @State private var numbers = (0 ..< 10) 中的点数时,绿色矩形的透明度会降低。 我猜是在彼此叠加绘制了很多矩形。
如何修改代码,使点的数量增加时透明度保持不变?
下面是我的代码(灵感来自:https://swiftwithmajid.com/2023/07/18/mastering-charts-in-swiftui-selection/)
import Charts
import SwiftUI
struct ContentView: View {
@State private var dragStart: Int? = nil
@State private var dragRange: ClosedRange<Int>? = nil
@State private var numbers = (0 ..< 10)
.map { _ in Double.random(in: 0 ... 10) }
var body: some View {
Chart {
ForEach(Array(zip(numbers, numbers.indices)), id: \.0) { number, index in
if let dragRange {
RectangleMark(
xStart: .value("x", dragRange.lowerBound),
xEnd: .value("x", dragRange.upperBound),
yStart: .value("y", 1),
yEnd: .value("y", 9)
)
.foregroundStyle(.green.opacity(0.05))
}
LineMark(
x: .value("Index", index),
y: .value("Value", number)
)
}
}
.chartXSelection(range: $dragRange)
.chartOverlay { chart in
GeometryReader { geometry in
Rectangle()
.fill(Color.clear)
.contentShape(Rectangle())
.gesture(
DragGesture()
.onChanged { value in
guard let plotFrame = chart.plotFrame else {
return
}
let currentX = value.location.x - geometry[plotFrame].origin.x
guard currentX >= 0, currentX < chart.plotSize.width else {
return
}
guard let index = chart.value(atX: currentX, as: Int.self) else {
return
}
if dragStart == nil {
dragRange = nil
dragStart = index
}
guard let startIndex = dragStart else {
return
}
if startIndex <= index {
dragRange = startIndex ... index
} else {
dragRange = index ... startIndex
}
}
.onEnded { _ in
dragStart = nil
}
)
}
}
}
}
解决方案
你只需要把矩形标记移到 ForEach 的外面,这样矩形标记的数量就不会和点的数量一样多。
Chart {
ForEach(Array(zip(numbers, numbers.indices)), id: \.0) { number, index in
LineMark(
x: .value("Index", index),
y: .value("Value", number)
)
}
if let dragRange {
RectangleMark(
xStart: .value("x", dragRange.lowerBound),
xEnd: .value("x", dragRange.upperBound),
yStart: .value("y", 1),
yEnd: .value("y", 9)
)
.foregroundStyle(.green.opacity(0.05))
}
}
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。