我想构建一个应用程序,并且想知道如何获取快速用于图表中标记的 foregroundStyle,因此我可以在图表旁边放置一段文本,内容类似于“您花费了 x 金额以及您所选择的类别”。花费最多的是 x 类别,前景色与图表(圆环图)上的颜色相匹配,我有这个代码,谢谢,如果我犯了拼写错误,抱歉英语不是我的第一语言。
我尝试使用与前景样式相同的样式,但它不起作用,因为我认为该函数是为图表值定义的,我也尝试在网上查找它,但我没有找到任何东西
Chart(data) { product in
SectorMark(
angle: .value(
Text(verbatim: product.title),
animate ? product.ammount: 0
),
innerRadius: .ratio(0.618),
angularInset: 2
)
.cornerRadius(5)
.foregroundStyle(
by: .value(
Text(verbatim: product.title),
product.title
)
)
}
ChartProxy
提供了一种为您提供前景色的方法,给定可绘制值 - foregroundStyle(for:)
。由于这需要 ChartProxy
,因此您需要将文本放入 chartOverlay
或 chartBackground
。
这是一个完整的示例:
struct Product: Hashable {
let title: String
let amount: Int
}
let products = [
Product(title: "Product A", amount: 1),
Product(title: "Product B", amount: 2),
Product(title: "Product C", amount: 3),
Product(title: "Product D", amount: 4),
]
struct ContentView: View {
var body: some View {
Chart(products, id: \.title) { product in
SectorMark(
angle: .value("Amount", product.amount),
innerRadius: .ratio(0.618),
angularInset: 2
)
.foregroundStyle(by: .value("Title", product.title))
}
.chartPlotStyle {
$0
.frame(height: 200)
.padding(.bottom, 40)
}
.chartLegend(position: .top, alignment: .center)
.chartOverlay(alignment: .bottom) { proxy in
if let mostAbundantProduct = products.max(by: { $0.amount < $1.amount }),
let foregroundStyle = proxy.foregroundStyle(for: mostAbundantProduct.title) {
Text("The most abundant product is \(mostAbundantProduct.title)")
.foregroundStyle(foregroundStyle)
}
}
.padding()
}
}
我在图表底部添加了文字“最丰富的产品是......”。这可能会与图表图例或图表本身相交,因此我使用
.chartLegend
将图例移至图表顶部,并在 padding
中添加了一些底部 chartPlotStyle
。
输出:
请注意,为绘制图表而自动生成的颜色可能不适合文本。例如,它与文本背景的对比度可能很小。如果在编译时已知扇区数量(即不同产品的数量),我建议为每个产品选择您自己的颜色:
let productColors: [String: Color] = [
"Product A": Color.red,
"Product B": Color.green,
"Product C": Color.blue,
"Product D": Color.purple,
]
chartForegroundStyleScale
将这些颜色应用到图表。
struct ContentView: View {
var body: some View {
VStack {
Chart(products, id: \.title) { product in
SectorMark(
angle: .value("Amount", product.amount),
innerRadius: .ratio(0.618),
angularInset: 2
)
.foregroundStyle(by: .value("Title", product.title))
}
.chartForegroundStyleScale {
productColors[$0] ?? .clear
}
.chartPlotStyle {
$0.frame(height: 200)
}
.padding()
if let mostAbundantProduct = products.max(by: { $0.amount < $1.amount }) {
Text("The most abundant product is \(mostAbundantProduct.title)")
.foregroundStyle(productColors[mostAbundantProduct.title] ?? .clear)
}
}
}
}