Intimamente relacionado a esta questão , o código do Gradiente Linear funciona bem, mas está sempre vinculado aos seus dados, por exemplo, este código abaixo, se você tiver uma matriz de frequências cardíacas de 70 a 110, as frequências cardíacas mais baixas serão sempre cinza e as superiores sempre roxo, mas também uma matriz de 90 a 195. Como mapear as paradas para que a cor corresponda à zona de frequência cardíaca? Em outras palavras, as frequências cardíacas de 70 a 110 mostrariam apenas, por exemplo, azul a laranja?
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)
Com a forma como o gradiente linear é aplicado, você precisará transformar dinamicamente os locais de parada em uma faixa diferente.
Suas paradas são configuradas para 0...1, com o intervalo de dados do gráfico esperado de 50...210. Mas como 50...210 não está definido, suas paradas também não deveriam ser.
Como você viu, para que uma parte de um gradiente seja vista no gráfico, sua parada deve estar dentro ou em 0...1. Cores abaixo de 0 ou acima de 1 não serão vistas ou serão apenas parcialmente vistas. O que precisamos fazer é pegar suas paradas e mapeá-las para um intervalo maior que 0...1, com base no máximo e no mínimo das marcas de linha.
Para começar, precisamos tirar seus stops da forma 0...1 e, em vez disso, ter uma representação 50...210. Isso é simplesmente pegar
(210 - 50) * stop_value
(ex: blue_stop = (210 - 50) * 0,16) ~= 75). Optei por arredondar todos os valores para simplificar.Com esses valores, apenas os mapeamos para o intervalo desenhado do seu gráfico. O intervalo sorteado é mínimo_y...máximo_y. Abaixo está uma função que ajudará a mapear de um intervalo para outro.
Agora que temos nossos valores a serem mapeados e uma função para mapeá-los. Podemos gerar dinamicamente as paradas quando carregamos o gráfico. Abaixo está uma função para gerar paradas.
Usando
generateStops
podemos atualizar a visualização original para obter um gradiente que seja sempre preciso em relação aos pontos de dados. Observe que algumas coisas foram alteradas em relação ao original para acomodar o exemplo.