ios - 使折线图渐变颜色从线到底部 - SwiftUI
问题描述
我正在尝试使折线图显示从线条和向下的渐变颜色,但我似乎无法让它只从线条开始。相反,它只是填充给定帧中的整个背景。
我有这个 -图表电流
但我想要这个 -图表想要
import SwiftUI
struct Graph: View {
var body: some View {
ZStack{
LineGraph(dataPoints: [1, 0.8, 0.7, 0.5, 0.7, 0.4, 0.5, 0.6, 0.8, 0.4, 0.3, 0.4, 0.5, 0.7, 0.6, 1])
.stroke(Color(#colorLiteral(red: 0.2784313725, green: 0.2901960784, blue: 0.9568627451, alpha: 1)), lineWidth: 2)
}
.frame(width: 124, height: 90, alignment: .center)
.background(LinearGradient(gradient: Gradient(colors: [Color(#colorLiteral(red: 0.4901960784, green: 0.5058823529, blue: 0.9803921569, alpha: 1)), Color(#colorLiteral(red: 1, green: 1, blue: 1, alpha: 1))]), startPoint: .top, endPoint: .bottom))
}
}
struct LineGraph: Shape {
var dataPoints: [CGFloat]
func path(in rect: CGRect) -> Path {
func point(at ix: Int) -> CGPoint {
let point = dataPoints[ix]
let x = rect.width * CGFloat(ix) / CGFloat(dataPoints.count - 1)
let y = (1 - point) * rect.height
return CGPoint(x: x, y: y)
}
return Path { p in
guard dataPoints.count > 1 else {return}
let start = dataPoints[0]
p.move(to: CGPoint(x: 0, y: (1 - start) * rect.height))
for index in dataPoints.indices {
p.addLine(to: point(at: index))
}
}
}
}
谢谢 :-)
解决方案
这是可能的解决方案 - 对裁剪的背景使用相同的图形(我们需要封闭路径)和描边线的另一个变体。
使用 Xcode 12.4 / iOS 14.4 准备
struct Graph: View {
let dataPoints: [CGFloat] = [1, 0.8, 0.7, 0.5, 0.7, 0.4, 0.5, 0.6, 0.8, 0.4, 0.3, 0.4, 0.5, 0.7, 0.6, 1]
var body: some View {
ZStack{
LinearGradient(gradient:
Gradient(colors: [Color(#colorLiteral(red: 0.4901960784, green: 0.5058823529, blue: 0.9803921569, alpha: 1)), Color(#colorLiteral(red: 1, green: 1, blue: 1, alpha: 1))]), startPoint: .top, endPoint: .bottom)
.clipShape(LineGraph(dataPoints: dataPoints, closed: true)) // << !!
LineGraph(dataPoints: dataPoints)
.stroke(Color(#colorLiteral(red: 0.2784313725, green: 0.2901960784, blue: 0.9568627451, alpha: 1)), lineWidth: 2)
}
.frame(width: 124, height: 90, alignment: .center)
}
}
struct LineGraph: Shape {
var dataPoints: [CGFloat]
var closed = false // << indicator for variants !!
func path(in rect: CGRect) -> Path {
func point(at ix: Int) -> CGPoint {
let point = dataPoints[ix]
let x = rect.width * CGFloat(ix) / CGFloat(dataPoints.count - 1)
let y = (1 - point) * rect.height
return CGPoint(x: x, y: y)
}
return Path { p in
guard dataPoints.count > 1 else {return}
let start = dataPoints[0]
p.move(to: CGPoint(x: 0, y: (1 - start) * rect.height))
for index in dataPoints.indices {
p.addLine(to: point(at: index))
}
if closed { // << variant for clipping !!
p.addLine(to: CGPoint(x: rect.maxX, y: rect.maxY))
p.addLine(to: CGPoint(x: rect.minX, y: rect.maxY))
p.closeSubpath()
}
}
}
}
推荐阅读
- javascript - 使用 fetch 的 POST 请求不起作用
- c# - Apache Ignite.NET 服务中的依赖注入
- android - 应用程序仅在连接到笔记本电脑的设备上运行
- arrays - 如何在bash中嵌套变量和循环子变量
- python - 在 Python 中为 OpenCV BoundryBox 设置自定义 RoI
- ruby-on-rails - 在 Rails 中控制公共文件响应代码
- c# - 与 ef 对话和可定制的 asp.net 类库
- google-app-engine - AppEngine 日志不接受上下文
- https - Gitbook API 返回 HTTP 代码 429
- python - Python Pandas:高效地为切片赋值