foregroundStyle(_:)
修饰符:
private let symbols = ["circle", "square", "triangle", "diamond", "pentagon"]
private let styles: [Color] = [ .blue, .green, .orange, .purple, .red, .cyan, .yellow ]
// Swift Charts just cycles through the above choices, resulting in 35 (7x5) unique combinations
private struct StandardChart: View {
func chartPoint(x: Int, y: Double, series: Int) -> some ChartContent {
LineMark(
x: .value("Day", x),
y: .value("Total", y),
series: .value("Series", "Series \(series + 1)")
)
.symbol(by: .value("Series", "Series \(series + 1)"))
.foregroundStyle(by: .value("Series", "Series \(series + 1)"))
}
var body: some View {
Chart {
ForEach(0..<8, id: \.self) { index in
chartPoint(x: 0, y: 0, series: index)
chartPoint(x: 1, y: 0.75 * Double(index), series: index)
chartPoint(x: 2, y: Double(index), series: index)
}
}
}
}
private struct ReproducedChart: View {
func chartPoint(x: Int, y: Double, series: Int) -> some ChartContent {
LineMark(
x: .value("Day", x),
y: .value("Total", y),
series: .value("Series", "Series \(series + 1)")
)
.symbol {
Image(systemName: symbols[series % 5])
.font(.system(size: 7))
.fontWeight(.black)
}
.foregroundStyle(styles[series % 7])
}
var body: some View {
VStack {
Chart {
ForEach(0..<8, id: \.self) { index in
chartPoint(x: 0, y: 0, series: index)
chartPoint(x: 1, y: 0.75 * Double(index), series: index)
chartPoint(x: 2, y: Double(index), series: index)
}
}
}
}
}
// Best viewed in landscape mode
struct ContentView: View {
var body: some View {
HStack {
VStack {
Text("Standard")
StandardChart()
}
.padding()
VStack {
Text("Reproduced")
ReproducedChart()
}
.padding()
}
}
}
在:
我的代码即将接近,但看起来与默认值不完全相同。以下是我在图表的复制版本中注意到的差异:
情节线侵占了符号的内部。
符号没有捡起颜色。图表没有出现传奇
ReproducedChart
Image(systemName:)
BasicChartSymbolShape
asterisk
,
circle
,cross
,diamond
,pentagon
,
plus
,
square
,
triangle
。使用
BasicChartSymbolShape
,而不是SFSymbols将解决问题中的前三个问题。 ie用private let symbols = ["circle", ...]
替换为private let symbols: [BasicChartSymbolShape] = [.circle, ...]
,然后用symbol {...}
替换为ReproducedChart
。
缺少图表传奇的最后一期更加微妙。事实证明,即使我对我指定的系列始终如一地对所有内容进行了样式,但Swift图表也许并不合理地假设我将在“系列1”等的所有标记中使用正确的符号。 API不能保证我的正确选择。因此,传说中的任何信息都不能来自诸如
.symbol(symbols[series % 5])
和
symbol(_:)
之类的API,而我们必须使用
foregroundStyle(_:)
和。这些API保证将在同一系列中的所有元素中应用一致的样式。
但是,似乎我们又回到了对造型选择的控制权!但是,我们可以重新控制使用图表API中的各种修饰符做出的选择,这些选择以formforegroundStyle(by:)
表命名。在这种情况下,最直接的一种似乎是
chart*Scale(...)
chartSymbolScale(_:)
,我发现形式的修饰符是,也就是说,所有以他们的论点为论点的修饰符都是非常脆弱的。如果我在视图中使用了多个这样的修饰符,我什至无法获得XCode来编译代码。
我建议的替代方法是使用将映射函数作为参数的修饰符之一。在此示例中,这意味着使用
Chart {
// ...
}
.chartSymbolScale([
"Series 1": .circle,
// ...
"Series 8": .triangle
])
和
chart*Scale(_:)
提供为每个系列提供适当样式选择的映射功能。在进行上述建议的更改之后,我们最终得到了此代码:
_ mapping: KeyValuePairs<DataValue, S>
以下结果:
现在我要做的就是更改映射函数返回的样式chartSymbolScale(mapping:)
和
chartForegroundStyleScale(mapping:)
,我将获得与默认值一致的结果!