与这个问题密切相关的是,线性梯度代码运行良好,但它总是与其数据相关联,因此例如下面的代码,如果您有一系列从 70 到 110 的心率,则较低的心率始终为灰色,较高的心率始终为灰色紫色,但 90 到 195 的数组也是如此。如何映射停靠点以使颜色与心率区域相对应?换句话说,心率从 70-110 只会显示蓝色到橙色?
Chart {
ForEach(smoothHeartRatesEMA(customHeartRates, decayFactor: 0.3)) { heartRate in
LineMark(
x: .value("Sample Time", heartRate.startDate, unit: .nanosecond), //changed these to .nanosecond to fix Nike Run Club bug (some how Nike Run Club gets more frequent HR samples than other apps?)
y: .value("Heart Rate", heartRate.doubleValue)
)
.lineStyle(StrokeStyle(lineWidth: 3.0))
.foregroundStyle(
.linearGradient(
stops: [
.init(color: Color.gray, location: 0.0),
.init(color: TrackerConstants.AppleFitnessBlue, location: 0.16),
.init(color: TrackerConstants.AppleFitnessYellow, location: 0.33),
.init(color: TrackerConstants.AppleFitnessOrange, location: 0.5),
.init(color: TrackerConstants.AppleFitnessRed, location: 0.66),
.init(color: TrackerConstants.AppleFitnessPurple, location: 1.0) //how do I get these to allign with a range of e.g. 170-210. I.e. if no heart rate is above 170bpm, the line is never purple?
],
startPoint: .bottom,
endPoint: .top)
)
}
}
.chartYScale(domain: 50...210)
通过应用线性渐变的方式,您将需要动态地将停止位置转换到不同的范围。
您的止损设置为 0...1,预期图形数据范围为 50...210。但由于 50...210 并不是一成不变的,因此您的止损也不应该是一成不变的。
正如您所看到的,要在图表上看到渐变的一部分,其停止点必须在 0...1 之内或之上。低于 0 或高于 1 的颜色要么根本看不到,要么只看到部分。我们需要做的是根据线标记的最大值和最小值,将您的止损点映射到大于 0...1 的范围。
首先,我们需要将止损点从 0...1 形式中去掉,改为 50...210 表示形式。这只是简单地取
(210 - 50) * stop_value
(例如:blue_stop = (210 - 50) * 0.16) ~= 75)。为了简单起见,我选择对所有值进行四舍五入。有了这些值,我们只需将它们映射到图表的绘制范围即可。绘制的范围是minimum_y...maximum_y。下面的函数可以帮助将地图从一个范围映射到另一个范围。
现在我们有了要映射的值,以及映射它们的函数。当我们加载图表时,我们可以动态生成止损点。下面是生成止损的函数。
使用
generateStops
我们可以更新原始视图以获得始终准确于数据点的梯度。请注意,为了适应该示例,某些内容已从原始内容中更改。