diff --git a/.swiftpm/xcode/xcuserdata/samuandras.xcuserdatad/xcschemes/xcschememanagement.plist b/.swiftpm/xcode/xcuserdata/samuandras.xcuserdatad/xcschemes/xcschememanagement.plist
new file mode 100644
index 0000000..a0f26bb
--- /dev/null
+++ b/.swiftpm/xcode/xcuserdata/samuandras.xcuserdatad/xcschemes/xcschememanagement.plist
@@ -0,0 +1,14 @@
+
+
+
+
+ SchemeUserState
+
+ SwiftUICharts.xcscheme_^#shared#^_
+
+ orderHint
+ 2
+
+
+
+
diff --git a/Sources/SwiftUICharts/Base/CardView/CardView.swift b/Sources/SwiftUICharts/Base/CardView/CardView.swift
index 9109a2b..e5d7eb3 100644
--- a/Sources/SwiftUICharts/Base/CardView/CardView.swift
+++ b/Sources/SwiftUICharts/Base/CardView/CardView.swift
@@ -26,9 +26,9 @@ public struct CardView: View, ChartBase {
if showShadow {
RoundedRectangle(cornerRadius: 20)
.fill(Color.white)
- .shadow(color: Color.gray, radius: 8)
+ .shadow(color: Color(white: 0.9, opacity: 1), radius: 8)
}
- VStack {
+ VStack (alignment: .leading) {
self.content()
}
.clipShape(RoundedRectangle(cornerRadius: showShadow ? 20 : 0))
diff --git a/Sources/SwiftUICharts/Base/Chart/ChartData.swift b/Sources/SwiftUICharts/Base/Chart/ChartData.swift
index b598975..17b79ee 100644
--- a/Sources/SwiftUICharts/Base/Chart/ChartData.swift
+++ b/Sources/SwiftUICharts/Base/Chart/ChartData.swift
@@ -13,7 +13,8 @@ public class ChartData: ObservableObject {
}
var normalisedPoints: [Double] {
- points.map { $0 / (points.max() ?? 1.0) }
+ let absolutePoints = points.map { abs($0) }
+ return points.map { $0 / (absolutePoints.max() ?? 1.0) }
}
var normalisedRange: Double {
diff --git a/Sources/SwiftUICharts/Base/Extensions/CGPoint+Extension.swift b/Sources/SwiftUICharts/Base/Extensions/CGPoint+Extension.swift
index 363cd2c..31c401d 100644
--- a/Sources/SwiftUICharts/Base/Extensions/CGPoint+Extension.swift
+++ b/Sources/SwiftUICharts/Base/Extensions/CGPoint+Extension.swift
@@ -38,4 +38,10 @@ extension CGPoint {
return CGPoint(x: stepWidth, y: stepHeight)
}
+
+ func denormalize(with geometry: GeometryProxy) -> CGPoint {
+ let width = geometry.frame(in: .local).width
+ let height = geometry.frame(in: .local).height
+ return CGPoint(x: self.x * width, y: self.y * height)
+ }
}
diff --git a/Sources/SwiftUICharts/Base/Grid/ChartGrid.swift b/Sources/SwiftUICharts/Base/Grid/ChartGrid.swift
index ecaf270..eb48a98 100644
--- a/Sources/SwiftUICharts/Base/Grid/ChartGrid.swift
+++ b/Sources/SwiftUICharts/Base/Grid/ChartGrid.swift
@@ -46,7 +46,7 @@ struct DashedLine: View {
var body: some View {
GeometryReader { geometry in
line(frame: geometry.frame(in: .local))
- .stroke(Color(white: 0.3), style: StrokeStyle(lineWidth: 1, lineCap: .round, dash: [5, 10]))
+ .stroke(Color(white: 0.85), style: StrokeStyle(lineWidth: 1, lineCap: .round, dash: [5, 10]))
}
}
}
diff --git a/Sources/SwiftUICharts/Charts/LineChart/Line.swift b/Sources/SwiftUICharts/Charts/LineChart/Line.swift
index 0e9fa34..107367f 100644
--- a/Sources/SwiftUICharts/Charts/LineChart/Line.swift
+++ b/Sources/SwiftUICharts/Charts/LineChart/Line.swift
@@ -13,6 +13,10 @@ public struct Line: View {
@State private var didCellAppear: Bool = false
var curvedLines: Bool = true
+ var path: Path {
+ Path.quadCurvedPathWithPoints(points: chartData.normalisedPoints,
+ step: CGPoint(x: 1.0, y: 1.0))
+ }
/// The content and behavior of the `Line`.
/// Draw the background if showing the full line (?) and the `showBackground` option is set. Above that draw the line, and then the data indicator if the graph is currently being touched.
@@ -31,12 +35,13 @@ public struct Line: View {
style: style,
trimTo: didCellAppear ? 1.0 : 0.0)
.animation(.easeIn)
-// if self.showIndicator {
-// IndicatorPoint()
-// .position(self.getClosestPointOnPath(touchLocation: self.touchLocation))
-// .rotationEffect(.degrees(180), anchor: .center)
-// .rotation3DEffect(.degrees(180), axis: (x: 0, y: 1, z: 0))
-// }
+ if self.showIndicator {
+ IndicatorPoint()
+ .position(self.getClosestPointOnPath(geometry: geometry,
+ touchLocation: self.touchLocation))
+ .rotationEffect(.degrees(180), anchor: .center)
+ .rotation3DEffect(.degrees(180), axis: (x: 0, y: 1, z: 0))
+ }
}
.onAppear {
didCellAppear = true
@@ -49,7 +54,7 @@ public struct Line: View {
.onChanged({ value in
self.touchLocation = value.location
self.showIndicator = true
-// self.getClosestDataPoint(point: self.getClosestPointOnPath(touchLocation: value.location))
+ self.getClosestDataPoint(geometry: geometry, touchLocation: value.location)
self.chartValue.interactionInProgress = true
})
.onEnded({ value in
@@ -64,24 +69,30 @@ public struct Line: View {
// MARK: - Private functions
-//extension Line {
-// /// Calculate point closest to where the user touched
-// /// - Parameter touchLocation: location in view where touched
-// /// - Returns: `CGPoint` of data point on chart
-// private func getClosestPointOnPath(touchLocation: CGPoint) -> CGPoint {
-// let closest = self.path.point(to: touchLocation.x)
-// return closest
-// }
-//
+extension Line {
+ /// Calculate point closest to where the user touched
+ /// - Parameter touchLocation: location in view where touched
+ /// - Returns: `CGPoint` of data point on chart
+ private func getClosestPointOnPath(geometry: GeometryProxy, touchLocation: CGPoint) -> CGPoint {
+ let geometryWidth = geometry.frame(in: .local).width
+ let normalisedTouchLocationX = (touchLocation.x / geometryWidth) * CGFloat(chartData.normalisedPoints.count - 1)
+ let closest = self.path.point(to: normalisedTouchLocationX)
+ var denormClosest = closest.denormalize(with: geometry)
+ denormClosest.x = denormClosest.x / CGFloat(chartData.normalisedPoints.count - 1)
+ denormClosest.y = denormClosest.y / CGFloat(chartData.normalisedRange)
+ return denormClosest
+ }
+
// /// Figure out where closest touch point was
// /// - Parameter point: location of data point on graph, near touch location
-// private func getClosestDataPoint(point: CGPoint) {
-// let index = Int(round((point.x)/step.x))
-// if (index >= 0 && index < self.chartData.data.count){
-// self.chartValue.currentValue = self.chartData.points[index]
-// }
-// }
-//}
+ private func getClosestDataPoint(geometry: GeometryProxy, touchLocation: CGPoint) {
+ let geometryWidth = geometry.frame(in: .local).width
+ let index = Int(round((touchLocation.x / geometryWidth) * CGFloat(chartData.points.count - 1)))
+ if (index >= 0 && index < self.chartData.data.count){
+ self.chartValue.currentValue = self.chartData.points[index]
+ }
+ }
+}
struct Line_Previews: PreviewProvider {
/// Predefined style, black over white, for preview