我正在努力在条形图上叠加一个用户可以点击和拖动以获得更多信息的图标。
我在以前的应用程序中使用了相同的代码(针对数据类型进行了修改),它运行得很好。这让我觉得框架中的某些东西在xcode 14.3中发生了变化。
用户应该能够点击和拖动,并看到数据的酒吧-在这种情况下,简单的年份和数字。
但是,当点击此处图表时,矩形指针的位置不正确,但气泡中报告的数据是正确的。在这种情况下,指针偏离一个条形,但这是巧合-如果有更多的数据点,错误将超过一个条形。
同样奇怪的是,如果我注解掉矩形指针的偏移量,它会消失。如果我将偏移量设置为0.0,它会消失。在这两种情况下,设备上的点击点或模拟器中的光标仍然显示正确的数据。
下面是代码的简化版本:
struct ContentView: View {
@State private var showSelectionBar = false
@State private var offsetX: Double = 0.0
@State private var offsetY = 0.0
@State private var thisSelectedYear = "2010"
@State private var selectedYearGeneration: Double = 0.0
let tempColors: [Color] = [.blue, .green, .yellow, .orange, .red]
var body: some View {
VStack(spacing: 10) {
Text("Some Data")
.font(.title2)
GroupBox {
Chart(Datum.exampleData) { item in
BarMark(
x: .value("Year", String(item.period)),
y: .value("Generation", (item.generation))
)
.foregroundStyle(by: .value("Type", item.type))
}
}//group box
.frame(height: 500)
.padding()
.chartYScale(domain: 0...40)
.chartYAxis {
AxisMarks(
values: stride(
from: 0,
to: 50,
by: 10).map { $0 }
)
}//chart y axis
.chartXAxis {
AxisMarks(position: .bottom, values: .automatic) { value in
if ((value.index % 2) != 0) {
AxisValueLabel() {
if let strValue = value.as(String.self) {
Text(strValue)
.font(.caption)
.rotationEffect(Angle(degrees: 45))
.padding(.top)
}//if let value as string
}//axis value label
}//if
}//axis marks
}//chart x axis
.chartLegend(spacing: 20)
.chartOverlay { pr in
GeometryReader { geoProxy in
Rectangle()
.foregroundStyle(Color.orange.gradient)
.frame(width: 2, height: geoProxy.size.height * 0.95)
.opacity(showSelectionBar ? 1.0 : 0.0)
//this is the line
.offset(x: offsetX)
//above is the line
Capsule()
.foregroundStyle(.blue.gradient)
.frame(width: 160, height: 80)
.overlay {
VStack {
Text(thisSelectedYear)
Text("Generation: \(selectedYearGeneration, specifier: "%.0f")")
}
.foregroundStyle(.white)
}
.opacity(showSelectionBar ? 1.0 : 0)
.offset(x: offsetX - 50, y: offsetY - 100)
Rectangle().fill(.clear).contentShape(Rectangle()).gesture(DragGesture()
.onChanged { value in
if !showSelectionBar {
showSelectionBar = true
}
let origin = geoProxy[pr.plotAreaFrame].origin
let location = CGPoint(
x: value.location.x - origin.x,
y: value.location.y - origin.y
)
print(UIScreen.main.bounds.size.width)
print("location: \(location.x)")
offsetX = location.x
offsetY = location.y
let (year, _) = pr.value(at: location, as: (String, Double).self) ?? ("-", 0)
print("year is" , year)
thisSelectedYear = year
let selectedDatum: Datum = Datum.exampleData.first(where: {
$0.period == Int(thisSelectedYear)
}) ?? Datum.exampleData[0]
selectedYearGeneration = selectedDatum.generation
}//on changed
.onEnded{ _ in
showSelectionBar = false
})//gesture
}//geo proxy
}//overlay
Spacer()
}//v
}//body
}//struct
// MARK: - Datum
struct Datum: Identifiable {
let id = UUID()
let period: Int
let type: String
let generation: Double
static let exampleData: [Datum] = [
Datum(period: 2001, type: "A", generation: 10.0),
Datum(period: 2002, type: "A", generation: 15.0),
Datum(period: 2003, type: "A", generation: 5.0),
Datum(period: 2003, type: "B", generation: 10.0),
Datum(period: 2003, type: "C", generation: 10.0),
Datum(period: 2004, type: "A", generation: 25.0),
Datum(period: 2005, type: "A", generation: 30.0),
Datum(period: 2006, type: "A", generation: 27.0),
Datum(period: 2007, type: "A", generation: 22.0),
Datum(period: 2007, type: "B", generation: 12.0),
Datum(period: 2008, type: "A", generation: 17.0),
Datum(period: 2008, type: "B", generation: 12.0),
Datum(period: 2009, type: "A", generation: 12.0),
Datum(period: 2010, type: "A", generation: 7.0)
]
}//struct
如有任何指导,敬请谅解。
1条答案
按热度按时间i7uq4tfw1#
当在SwiftUI中处理没有做它们应该做的事情的视图时,我的第一个设备是非常低技术的。为事物添加颜色以查看它们是如何布局的。你在代码中看不到的东西,在着色后变得非常明显。
在您测量阻力的
Rectangle()
上,我将.clear
更改为.purple.opacity(0.4)
,这是我看到的:这个问题有点突然出现在你面前。你有一个
Chart
在一个GroupBox
中,周围有一个.frame(height: 500)
,然后是.padding()
。Rectangle()
在这些修饰符之外,因此不受它们的约束,所以它最终是包括填充的总大小,而GroupBox
有一个内部填充,所以它充当一个框架,然后.padding()
增加了更大的差异。所以,你是正确的,因为它与酒吧的大小无关,而是事实上Rectangle()
和Chart()
的大小不一样。要修复它,只需移动
.chartOverlay()
,并且为了统一起见,移动GroupBox的其他图表修改器独立组件。