Mercurial > public > lazybear
changeset 98:b49877856a71
Implement LineView for stock prices
author | Dennis Concepción Martín <66180929+denniscm190@users.noreply.github.com> |
---|---|
date | Sat, 30 Jan 2021 19:43:15 +0100 |
parents | bd35f88e65cd |
children | 3e92dce4b799 |
files | LazyBear.xcodeproj/project.pbxproj LazyBear.xcodeproj/project.xcworkspace/xcuserdata/dennis.xcuserdatad/UserInterfaceState.xcuserstate lazybear/Views/Line.swift lazybear/Views/LineView.swift lazybear/Views/Stock.swift |
diffstat | 5 files changed, 140 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/LazyBear.xcodeproj/project.pbxproj Sat Jan 30 19:34:25 2021 +0100 +++ b/LazyBear.xcodeproj/project.pbxproj Sat Jan 30 19:43:15 2021 +0100 @@ -23,6 +23,8 @@ 95AB4A7D259DCC0C0064C9C1 /* CompanyModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95AB4A7C259DCC0C0064C9C1 /* CompanyModel.swift */; }; 95AB4A90259DD66D0064C9C1 /* CompanyRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95AB4A8F259DD66D0064C9C1 /* CompanyRow.swift */; }; 95AD892425C5D8A200BCE8E4 /* AddWatchlist.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95AD892325C5D8A200BCE8E4 /* AddWatchlist.swift */; }; + 95AD892725C5DF2400BCE8E4 /* LineView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95AD892625C5DF2400BCE8E4 /* LineView.swift */; }; + 95AD892A25C5DF5C00BCE8E4 /* Line.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95AD892925C5DF5C00BCE8E4 /* Line.swift */; }; 95B04EB325212369000AD27F /* LazyBearApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95B04EB225212369000AD27F /* LazyBearApp.swift */; }; 95B04EB525212369000AD27F /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95B04EB425212369000AD27F /* ContentView.swift */; }; 95B04EB72521236A000AD27F /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 95B04EB62521236A000AD27F /* Assets.xcassets */; }; @@ -65,6 +67,8 @@ 95AB4A7C259DCC0C0064C9C1 /* CompanyModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = CompanyModel.swift; path = lazybear/Models/CompanyModel.swift; sourceTree = SOURCE_ROOT; }; 95AB4A8F259DD66D0064C9C1 /* CompanyRow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CompanyRow.swift; sourceTree = "<group>"; }; 95AD892325C5D8A200BCE8E4 /* AddWatchlist.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = AddWatchlist.swift; path = lazybear/Views/AddWatchlist.swift; sourceTree = SOURCE_ROOT; }; + 95AD892625C5DF2400BCE8E4 /* LineView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = LineView.swift; path = lazybear/Views/LineView.swift; sourceTree = SOURCE_ROOT; }; + 95AD892925C5DF5C00BCE8E4 /* Line.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = Line.swift; path = lazybear/Views/Line.swift; sourceTree = SOURCE_ROOT; }; 95B04EAF25212369000AD27F /* LazyBear.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = LazyBear.app; sourceTree = BUILT_PRODUCTS_DIR; }; 95B04EB225212369000AD27F /* LazyBearApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LazyBearApp.swift; sourceTree = "<group>"; }; 95B04EB425212369000AD27F /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = "<group>"; }; @@ -149,6 +153,8 @@ 95AD892325C5D8A200BCE8E4 /* AddWatchlist.swift */, 95F6C30425BAF599003CF389 /* CompanyHeader.swift */, 95F6C30825BAF7C2003CF389 /* DateSelection.swift */, + 95AD892625C5DF2400BCE8E4 /* LineView.swift */, + 95AD892925C5DF5C00BCE8E4 /* Line.swift */, ); path = Views; sourceTree = "<group>"; @@ -301,6 +307,7 @@ 9597CE0125C1DC0A004DDFED /* LogoModifier.swift in Sources */, 954DDF0425C456E800848A4B /* QuoteModel.swift in Sources */, 9597CE0425C1DFE7004DDFED /* LogoPlaceholder.swift in Sources */, + 95AD892725C5DF2400BCE8E4 /* LineView.swift in Sources */, 95FE646B25C30B880052832E /* ApiModel.swift in Sources */, 95F6C30525BAF599003CF389 /* CompanyHeader.swift in Sources */, 95612C512598D48200F7698F /* SearchBar.swift in Sources */, @@ -314,6 +321,7 @@ 95F6C30925BAF7C2003CF389 /* DateSelection.swift in Sources */, 95F6C2F025BAE2ED003CF389 /* Company.swift in Sources */, 95F6F46125C20E63002AC66A /* ListHeader.swift in Sources */, + 95AD892A25C5DF5C00BCE8E4 /* Line.swift in Sources */, 95D1BF4925ADCF7700E5D063 /* Persistence.swift in Sources */, 958B678525C42B2400BF9F89 /* ApiAccess.swift in Sources */, 95E4119225BEC56F00A9C23F /* SuperTitle.swift in Sources */,
Binary file LazyBear.xcodeproj/project.xcworkspace/xcuserdata/dennis.xcuserdatad/UserInterfaceState.xcuserstate has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lazybear/Views/Line.swift Sat Jan 30 19:43:15 2021 +0100 @@ -0,0 +1,76 @@ +// +// Line.swift +// LazyBear +// +// Created by Dennis Concepción Martín on 30/1/21. +// + +import SwiftUI + +struct Line: View { + var data: [(Double)] + @Binding var frame: CGRect + + let padding:CGFloat = 30 + + var stepWidth: CGFloat { + if data.count < 2 { + return 0 + } + return frame.size.width / CGFloat(data.count-1) + } + var stepHeight: CGFloat { + var min: Double? + var max: Double? + let points = self.data + if let minPoint = points.min(), let maxPoint = points.max(), minPoint != maxPoint { + min = minPoint + max = maxPoint + }else { + return 0 + } + if let min = min, let max = max, min != max { + if (min <= 0){ + return (frame.size.height-padding) / CGFloat(max - min) + }else{ + return (frame.size.height-padding) / CGFloat(max + min) + } + } + + return 0 + } + var path: Path { + let points = self.data + return Path.lineChart(points: points, step: CGPoint(x: stepWidth, y: stepHeight)) + } + + public var body: some View { + + ZStack { + + self.path + .stroke(Color.green ,style: StrokeStyle(lineWidth: 3, lineJoin: .round)) + .rotationEffect(.degrees(180), anchor: .center) + .rotation3DEffect(.degrees(180), axis: (x: 0, y: 1, z: 0)) + .drawingGroup() + } + } +} + +extension Path { + + static func lineChart(points:[Double], step:CGPoint) -> Path { + var path = Path() + if (points.count < 2){ + return path + } + guard let offset = points.min() else { return path } + let p1 = CGPoint(x: 0, y: CGFloat(points[0]-offset)*step.y) + path.move(to: p1) + for pointIndex in 1..<points.count { + let p2 = CGPoint(x: step.x * CGFloat(pointIndex), y: step.y*CGFloat(points[pointIndex]-offset)) + path.addLine(to: p2) + } + return path + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lazybear/Views/LineView.swift Sat Jan 30 19:43:15 2021 +0100 @@ -0,0 +1,55 @@ +// +// LineView.swift +// LazyBear +// +// Created by Dennis Concepción Martín on 30/1/21. +// + +import SwiftUI + +struct LineView: View { + var data: [(Double)] + var title: String? + var price: String? + + public init(data: [Double], + title: String? = nil, + price: String? = nil) { + + self.data = data + self.title = title + self.price = price + } + + public var body: some View { + GeometryReader{ geometry in + VStack(alignment: .leading, spacing: 8) { + Group{ + if (self.title != nil){ + Text(self.title!) + .font(.title) + } + if (self.price != nil){ + Text(self.price!) + .font(.body) + .offset(x: 5, y: 0) + } + }.offset(x: 0, y: 0) + ZStack{ + GeometryReader{ reader in + Line(data: self.data, + frame: .constant(CGRect(x: 0, y: 0, width: reader.frame(in: .local).width , height: reader.frame(in: .local).height)) + + ) + .offset(x: 0, y: 0) + } + .frame(width: geometry.frame(in: .local).size.width, height: 200) + .offset(x: 0, y: -100) + + } + .frame(width: geometry.frame(in: .local).size.width, height: 200) + + } + } + } +}