Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: Creating a data structure which propagets changes in data to the charts #114

Merged
merged 2 commits into from
Jun 21, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions Sources/SwiftUICharts/Base/Chart/AnyChartType.swift
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
import SwiftUI

struct AnyChartType: ChartType {
private let chartMaker: (ChartType.Configuration, ChartType.Style) -> AnyView
private let chartMaker: (ChartType.Data, ChartType.Style) -> AnyView

init<S: ChartType>(_ type: S) {
self.chartMaker = type.makeTypeErasedBody
}

func makeChart(configuration: ChartType.Configuration, style: ChartType.Style) -> AnyView {
self.chartMaker(configuration, style)
func makeChart(data: ChartType.Data, style: ChartType.Style) -> AnyView {
self.chartMaker(data, style)
}
}

fileprivate extension ChartType {
func makeTypeErasedBody(configuration: ChartType.Configuration, style: ChartType.Style) -> AnyView {
AnyView(makeChart(configuration: configuration, style: style))
func makeTypeErasedBody(data: ChartType.Data, style: ChartType.Style) -> AnyView {
AnyView(makeChart(data: data, style: style))
}
}
9 changes: 9 additions & 0 deletions Sources/SwiftUICharts/Base/Chart/ChartData.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import SwiftUI

public class ChartData: ObservableObject {
@Published public var data: [Double] = []

public init(_ data: [Double]) {
self.data = data
}
}
4 changes: 2 additions & 2 deletions Sources/SwiftUICharts/Base/Chart/ChartType.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import SwiftUI
public protocol ChartType {
associatedtype Body: View

func makeChart(configuration: Self.Configuration, style: Self.Style) -> Self.Body
func makeChart(data: Self.Data, style: Self.Style) -> Self.Body

typealias Configuration = ChartTypeConfiguration
typealias Data = ChartData
typealias Style = ChartStyle
}
5 changes: 0 additions & 5 deletions Sources/SwiftUICharts/Base/Chart/ChartTypeConfiguration.swift

This file was deleted.

16 changes: 11 additions & 5 deletions Sources/SwiftUICharts/Base/ChartView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,21 @@ public struct ChartView: View {
@Environment(\.chartType) private var chartType
@Environment(\.chartStyle) private var chartStyle

private var configuration: ChartTypeConfiguration
private var data: ChartData

public init(data: ChartData) {
self.data = data
}

public var body: some View {
self.chartType.makeChart(configuration: configuration, style: chartStyle)
self.chartType.makeChart(data: data, style: chartStyle)
}
}

extension ChartView {
public init(data: [Double]) {
self.configuration = ChartTypeConfiguration(data: data)
}
// public init(data: [Double]) {
// self.configuration = ChartTypeConfiguration(data: data)
// }


}
10 changes: 5 additions & 5 deletions Sources/SwiftUICharts/Charts/BarChart/BarChart.swift
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import SwiftUI

public struct BarChart: ChartType {
public func makeChart(configuration: Self.Configuration, style: Self.Style) -> some View {
BarChartRow(data: configuration.data, style: style)
public func makeChart(data: Self.Data, style: Self.Style) -> some View {
BarChartRow(chartData: data, style: style)
}
public init() {}
}
Expand All @@ -11,17 +11,17 @@ struct BarChart_Previews: PreviewProvider {
static var previews: some View {
Group {
BarChart().makeChart(
configuration: .init(data: [0]),
data: .init([0]),
style: .init(backgroundColor: .white, foregroundColor: ColorGradient.redBlack))
Group {
BarChart().makeChart(
configuration: .init(data: [1, 2, 3, 5, 1]),
data: .init([1, 2, 3, 5, 1]),
style: .init(backgroundColor: .white, foregroundColor: ColorGradient.redBlack))
}.environment(\.colorScheme, .light)

Group {
BarChart().makeChart(
configuration: .init(data: [1, 2, 3]),
data: .init([1, 2, 3]),
style: .init(backgroundColor: .white, foregroundColor: ColorGradient.redBlack))
}.environment(\.colorScheme, .dark)

Expand Down
64 changes: 41 additions & 23 deletions Sources/SwiftUICharts/Charts/BarChart/BarChartCell.swift
Original file line number Diff line number Diff line change
@@ -1,49 +1,67 @@
import SwiftUI

public struct BarChartCell: View {
@State var value: Double
@State var index: Int = 0
@State var width: Float
@State var numberOfDataPoints: Int
var value: Double
var index: Int = 0
var width: Float
var numberOfDataPoints: Int
var gradientColor: ColorGradient
var touchLocation: CGFloat

var cellWidth: Double {
return Double(width)/(Double(numberOfDataPoints) * 1.5)
}

@State var scaleValue: Double = 0
@Binding var touchLocation: CGFloat

@State var firstDisplay: Bool = true

public init( value: Double,
index: Int = 0,
width: Float,
numberOfDataPoints: Int,
gradientColor: ColorGradient,
touchLocation: CGFloat) {
self.value = value
self.index = index
self.width = width
self.numberOfDataPoints = numberOfDataPoints
self.gradientColor = gradientColor
self.touchLocation = touchLocation
}

public var body: some View {
ZStack {
RoundedRectangle(cornerRadius: 4)
.fill(gradientColor.linearGradient(from: .bottom, to: .top))
}
.frame(width: CGFloat(self.cellWidth))
.scaleEffect(CGSize(width: 1, height: self.scaleValue), anchor: .bottom)
.onAppear {
self.scaleValue = self.value
}
.animation(Animation.spring().delay(self.touchLocation < 0 ? Double(self.index) * 0.04 : 0))
}
.frame(width: CGFloat(self.cellWidth))
.scaleEffect(CGSize(width: 1, height: self.firstDisplay ? 0.0 : self.value), anchor: .bottom)
.onAppear {
self.firstDisplay = false
}
.onDisappear {
self.firstDisplay = true
}
.transition(.slide)
.animation(Animation.spring().delay(self.touchLocation < 0 || !firstDisplay ? Double(self.index) * 0.04 : 0))
}
}

struct BarChartCell_Previews: PreviewProvider {
static var previews: some View {
Group {
BarChartCell(value: 0, width: 50, numberOfDataPoints: 1, gradientColor: ColorGradient.greenRed, touchLocation: .constant(CGFloat()))
Group {
BarChartCell(value: 1, width: 50, numberOfDataPoints: 1, gradientColor: ColorGradient.greenRed, touchLocation: .constant(CGFloat()))
BarChartCell(value: 1, width: 50, numberOfDataPoints: 1, gradientColor: ColorGradient.whiteBlack, touchLocation: .constant(CGFloat()))
BarChartCell(value: 1, width: 50, numberOfDataPoints: 1, gradientColor: ColorGradient(.purple), touchLocation: .constant(CGFloat()))
BarChartCell(value: 0, width: 50, numberOfDataPoints: 1, gradientColor: ColorGradient.greenRed, touchLocation: CGFloat())

BarChartCell(value: 1, width: 50, numberOfDataPoints: 1, gradientColor: ColorGradient.greenRed, touchLocation: CGFloat())
BarChartCell(value: 1, width: 50, numberOfDataPoints: 1, gradientColor: ColorGradient.whiteBlack, touchLocation: CGFloat())
BarChartCell(value: 1, width: 50, numberOfDataPoints: 1, gradientColor: ColorGradient(.purple), touchLocation: CGFloat())
}

Group {
BarChartCell(value: 1, width: 50, numberOfDataPoints: 1, gradientColor: ColorGradient.greenRed, touchLocation: .constant(CGFloat()))
BarChartCell(value: 1, width: 50, numberOfDataPoints: 1, gradientColor: ColorGradient.whiteBlack, touchLocation: .constant(CGFloat()))
BarChartCell(value: 1, width: 50, numberOfDataPoints: 1, gradientColor: ColorGradient(.purple), touchLocation: .constant(CGFloat()))
BarChartCell(value: 1, width: 50, numberOfDataPoints: 1, gradientColor: ColorGradient.greenRed, touchLocation: CGFloat())
BarChartCell(value: 1, width: 50, numberOfDataPoints: 1, gradientColor: ColorGradient.whiteBlack, touchLocation: CGFloat())
BarChartCell(value: 1, width: 50, numberOfDataPoints: 1, gradientColor: ColorGradient(.purple), touchLocation: CGFloat())
}.environment(\.colorScheme, .dark)
}

}
}
77 changes: 39 additions & 38 deletions Sources/SwiftUICharts/Charts/BarChart/BarChartRow.swift
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import SwiftUI

public struct BarChartRow: View {
@State var data: [Double] = []
@ObservedObject var chartData: ChartData
@State var touchLocation: CGFloat = -1.0

enum Constant {
Expand All @@ -11,7 +11,7 @@ public struct BarChartRow: View {
var style: ChartStyle

var maxValue: Double {
guard let max = data.max() else {
guard let max = chartData.data.max() else {
return 1
}
return max != 0 ? max : 1
Expand All @@ -20,18 +20,18 @@ public struct BarChartRow: View {
public var body: some View {
GeometryReader { geometry in
HStack(alignment: .bottom,
spacing: (geometry.frame(in: .local).width - Constant.spacing) / CGFloat(self.data.count * 3)) {
ForEach(0..<self.data.count, id: \.self) { index in
BarChartCell(value: self.normalizedValue(index: index),
index: index,
width: Float(geometry.frame(in: .local).width - Constant.spacing),
numberOfDataPoints: self.data.count,
gradientColor: self.style.foregroundColor.rotate(for: index),
touchLocation: self.$touchLocation)
.scaleEffect(self.getScaleSize(touchLocation: self.touchLocation, index: index), anchor: .bottom)
.animation(.spring())

}
spacing: (geometry.frame(in: .local).width - Constant.spacing) / CGFloat(self.chartData.data.count * 3)) {
ForEach(0..<self.chartData.data.count, id: \.self) { index in
BarChartCell(value: self.normalizedValue(index: index),
index: index,
width: Float(geometry.frame(in: .local).width - Constant.spacing),
numberOfDataPoints: self.chartData.data.count,
gradientColor: self.style.foregroundColor.rotate(for: index),
touchLocation: self.touchLocation)
.scaleEffect(self.getScaleSize(touchLocation: self.touchLocation, index: index), anchor: .bottom)
.animation(Animation.easeIn(duration: 0.2))
}
// .drawingGroup()
}
.padding([.top, .leading, .trailing], 10)
.gesture(DragGesture()
Expand All @@ -46,37 +46,38 @@ public struct BarChartRow: View {
}

func normalizedValue(index: Int) -> Double {
return Double(data[index])/Double(maxValue)
print(chartData.data[index])
return Double(chartData.data[index])/Double(maxValue)
}

func getScaleSize(touchLocation: CGFloat, index: Int) -> CGSize {
if touchLocation > CGFloat(index)/CGFloat(self.data.count) &&
touchLocation < CGFloat(index+1)/CGFloat(self.data.count) {
if touchLocation > CGFloat(index)/CGFloat(chartData.data.count) &&
touchLocation < CGFloat(index+1)/CGFloat(chartData.data.count) {
return CGSize(width: 1.4, height: 1.1)
}
return CGSize(width: 1, height: 1)
}

}

struct BarChartRow_Previews: PreviewProvider {
static var previews: some View {
Group {
BarChartRow(data: [0], style: styleGreenRed)
Group {
BarChartRow(data: [1, 2, 3], style: styleGreenRed)
BarChartRow(data: [1, 2, 3], style: styleGreenRedWhiteBlack)
}
Group {
BarChartRow(data: [1, 2, 3], style: styleGreenRed)
BarChartRow(data: [1, 2, 3], style: styleGreenRedWhiteBlack)
}.environment(\.colorScheme, .dark)
}
}
}

private let styleGreenRed = ChartStyle(backgroundColor: .white, foregroundColor: .greenRed)

private let styleGreenRedWhiteBlack = ChartStyle(
backgroundColor: ColorGradient.init(.white),
foregroundColor: [ColorGradient.redBlack, ColorGradient.whiteBlack])
//struct BarChartRow_Previews: PreviewProvider {
// static var previews: some View {
// Group {
// BarChartRow(data: [0], style: styleGreenRed)
// Group {
// BarChartRow(data: [1, 2, 3], style: styleGreenRed)
// BarChartRow(data: [1, 2, 3], style: styleGreenRedWhiteBlack)
// }
// Group {
// BarChartRow(data: [1, 2, 3], style: styleGreenRed)
// BarChartRow(data: [1, 2, 3], style: styleGreenRedWhiteBlack)
// }.environment(\.colorScheme, .dark)
// }
// }
//}
//
//private let styleGreenRed = ChartStyle(backgroundColor: .white, foregroundColor: .greenRed)
//
//private let styleGreenRedWhiteBlack = ChartStyle(
// backgroundColor: ColorGradient.init(.white),
// foregroundColor: [ColorGradient.redBlack, ColorGradient.whiteBlack])
13 changes: 7 additions & 6 deletions Sources/SwiftUICharts/Charts/LineChart/Line.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import SwiftUI

public struct Line: View {
@State var frame: CGRect = .zero
@State var data: [Double]
@ObservedObject var chartData: ChartData

var style: ChartStyle

@State var showIndicator: Bool = false
Expand All @@ -11,11 +12,11 @@ public struct Line: View {
@State var showBackground: Bool = true
var curvedLines: Bool = true
var step: CGPoint {
return CGPoint.getStep(frame: frame, data: data)
return CGPoint.getStep(frame: frame, data: chartData.data)
}

var path: Path {
let points = data
let points = chartData.data

if curvedLines {
return Path.quadCurvedPathWithPoints(points: points,
Expand All @@ -27,7 +28,7 @@ public struct Line: View {
}

var closedPath: Path {
let points = data
let points = chartData.data

if curvedLines {
return Path.quadClosedCurvedPathWithPoints(points: points,
Expand Down Expand Up @@ -109,8 +110,8 @@ extension Line {
struct Line_Previews: PreviewProvider {
static var previews: some View {
Group {
Line(data: [1, 2, 3, 1, 2, 5, 7], style: blackLineStyle)
Line(data: [1, 2, 3, 1, 2, 5, 7], style: redLineStyle)
Line(chartData: ChartData([8, 23, 32, 7, 23, 43]), style: blackLineStyle)
Line(chartData: ChartData([8, 23, 32, 7, 23, 43]), style: redLineStyle)
}
}
}
Expand Down
10 changes: 5 additions & 5 deletions Sources/SwiftUICharts/Charts/LineChart/LineChart.swift
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import SwiftUI

public struct LineChart: ChartType {
public func makeChart(configuration: Self.Configuration, style: Self.Style) -> some View {
Line(data: configuration.data, style: style)
public func makeChart(data: Self.Data, style: Self.Style) -> some View {
Line(chartData: data, style: style)
}

public init() {}
Expand All @@ -12,17 +12,17 @@ struct LineChart_Previews: PreviewProvider {
static var previews: some View {
Group {
LineChart().makeChart(
configuration: .init(data: [0]),
data: .init([0]),
style: .init(backgroundColor: .white, foregroundColor: ColorGradient(.black)))
Group {
LineChart().makeChart(
configuration: .init(data: [1, 2, 3, 5, 1]),
data: .init([1, 2, 3, 5, 1]),
style: .init(backgroundColor: .white, foregroundColor: ColorGradient(.black)))
}.environment(\.colorScheme, .light)

Group {
LineChart().makeChart(
configuration: .init(data: [1, 2, 3]),
data: .init([1, 2, 3]),
style: .init(backgroundColor: .white, foregroundColor: ColorGradient.redBlack))
}.environment(\.colorScheme, .dark)

Expand Down
Loading