获取SwiftUI中标记的前景样式

问题描述 投票:0回答:1

我想构建一个应用程序,并且想知道如何获取快速用于图表中标记的 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
    )
  )
}
ios swift swiftui charts swiftui-charts
1个回答
0
投票

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

输出:

enter image description here


请注意,为绘制图表而自动生成的颜色可能不适合文本。例如,它与文本背景的对比度可能很小。如果在编译时已知扇区数量(即不同产品的数量),我建议为每个产品选择您自己的颜色:

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)
            }
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.