我正在尝试使用 Swift Charts 绘制下面的图表。我无法弄清楚如何根据 Y 值更改线条的颜色。在下图中,Y 的不同范围分配有不同的颜色,线条反映了这一点。
我尝试使用 LineMark 的前景设置线条颜色,但它似乎只采用第一个颜色分配并忽略其上设置的任何其他颜色。
Chart {
ForEach(plotItemSeries) { plotItem in
LineMark(x: .value("XVAL", plotItem.xVal),
y: .value("YVAL", plotItem.yVal))
.foregroundStyle(plotItem.zoneColor) // <== color assigned base on y-val
}
}
我尝试使用前景比例,但它只是将其分成多个系列,就像您所期望的那样。
Chart {
ForEach(plotItemSeries) { plotItem in
LineMark(x: .value("XVAL", plotItem.xVal),
y: .value("YVAL", plotItem.yVal))
.foregroundStyle(by: .value("Zone", plotItem.zoneColorName)) // <== "gray", "blue", etc..
}
}
.chartForegroundStyleScale(["gray": Color("grayCustom"),
"green": Color("greenCustom"),
"blue": Color("blueCustom"),
"orange": Color("orangeCustom"),
"red": Color("redCustom")])
有什么想法如何根据 y 值设置线条的颜色吗?
事实证明
.linearGradient(_ gradient: Gradient, startPoint: UnitPoint, endPoint: UnitPoint) -> LinearGradient
是正确的方法。
Gradient.Stops 映射到 UnitPoint,UnitPoint 映射到所绘制线条的边界框,因此颜色边界 y 值必须转换为单位点值,该值映射到颜色边界的 y 值。
举个简单的例子,如果我们想在 5 的 y-val 下面画蓝色线,上面画绿色线,并且该线是:(0,0) 到 (10,10) 则对应于转换的单位点值点是0.5。
为了获得清晰的颜色过渡,我们只需定义渐变,以便颜色变化的部分太小而无法渲染:
let stops = [
Gradient.Stop(color: .red, location: 0.0),
Gradient.Stop(color: .red, location: 0.5),
Gradient.Stop(color: .green, location: 0.50001),
Gradient.Stop(color: .green, location: 1.0)
]
因此,正确的方法看起来像:
Chart {
ForEach(plotItemSeries) { plotItem in
LineMark(x: .value("XVAL", plotItem.xVal),
y: .value("YVAL", plotItem.yVal))
.foregroundStyle(.linearGradient(Gradient(stops: stops),
startPoint: .bottom,
endPoint: .top))
}
}
你可以尝试一下,这可能就是你想要实现的目标。
Chart {
ForEach(plotItemSeries) { plotItem in
LineMark(x: .value("XVAL", plotItem.xVal),
y: .value("YVAL", plotItem.yVal))
.foregroundStyle(
.linearGradient(
// You can have more colours here depends on your data.
colors: [.blue, .red],
startPoint: .bottom,
endPoint: .top)
)
}
}