Compare commits

..

3 Commits

Author SHA1 Message Date
Andras Samu 94950db4d5 added watchos image 2019-09-30 20:42:30 +02:00
Andras Samu 251a830281 Added watchOS support 2019-09-30 20:41:04 +02:00
Andras Samu b2b0b83b4b fixed style error 2019-09-30 10:31:34 +02:00
9 changed files with 70 additions and 32 deletions
+1 -1
View File
@@ -6,7 +6,7 @@ import PackageDescription
let package = Package(
name: "SwiftUICharts",
platforms: [
.iOS(.v13),
.iOS(.v13),.watchOS(.v6)
],
products: [
// Products define the executables and libraries produced by a package, and make them visible to other packages.
+16 -1
View File
@@ -59,7 +59,6 @@ Customizable:
* background color
* accent color
* second gradient color
* chart form size
* text color
* legend text color
@@ -86,6 +85,22 @@ You can access built-in styles:
![Custom Charts](./showcase5.png "Custom Charts")
### You can customize the size of the chart with a Form object:
**Form**
* `.small`
* `.medium`
* `.large`
* `.detail`
```swift
BarChartView(data: [8,23,54,32,12,37,7,23,43], title: "Title", form: Form.small)
```
### WatchOS support for Bar charts:
![Pie Charts](./watchos1.png "Pie Charts")
## Pie charts
![Pie Charts](./showcase4.png "Pie Charts")
@@ -20,7 +20,7 @@ public struct BarChartRow : View {
GeometryReader { geometry in
HStack(alignment: .bottom, spacing: (geometry.frame(in: .local).width-22)/CGFloat(self.data.count * 3)){
ForEach(0..<self.data.count) { i in
BarChartCell(value: Double(self.data[i])/Double(self.maxValue), index: i, width: Float(geometry.frame(in: .local).width - 22), numberOfDataPoints: self.data.count, accentColor: self.accentColor, secondGradientAccentColor: self.secondGradientAccentColor, touchLocation: self.$touchLocation)
BarChartCell(value: self.normalizedValue(index: i), index: i, width: Float(geometry.frame(in: .local).width - 22), numberOfDataPoints: self.data.count, accentColor: self.accentColor, secondGradientAccentColor: self.secondGradientAccentColor, touchLocation: self.$touchLocation)
.scaleEffect(self.touchLocation > CGFloat(i)/CGFloat(self.data.count) && self.touchLocation < CGFloat(i+1)/CGFloat(self.data.count) ? CGSize(width: 1.4, height: 1.1) : CGSize(width: 1, height: 1), anchor: .bottom)
}
@@ -28,6 +28,10 @@ public struct BarChartRow : View {
.padding([.top, .leading, .trailing], 10)
}
}
func normalizedValue(index: Int) -> Double {
return Double(self.data[index])/Double(self.maxValue)
}
}
#if DEBUG
@@ -13,25 +13,28 @@ public struct BarChartView : View {
public var title: String
public var legend: String?
public var style: ChartStyle
let selectionFeedbackGenerator = UISelectionFeedbackGenerator()
public var formSize:CGSize
// let selectionFeedbackGenerator = UISelectionFeedbackGenerator()
@State private var touchLocation: CGFloat = -1.0
@State private var showValue: Bool = false
@State private var currentValue: Int = 0 {
didSet{
if(oldValue != self.currentValue && self.showValue) {
selectionFeedbackGenerator.selectionChanged()
// selectionFeedbackGenerator.selectionChanged()
HapticFeedback.playSelection()
}
}
}
var isFullWidth:Bool {
return self.style.chartFormSize == Form.large
return self.formSize == Form.large
}
public init(data: [Int], title: String, legend: String? = nil, style: ChartStyle = Styles.barChartStyleOne ){
public init(data: [Int], title: String, legend: String? = nil, style: ChartStyle = Styles.barChartStyleOrangeLight, form: CGSize? = Form.medium){
self.data = data
self.title = title
self.legend = legend
self.style = style
self.formSize = form!
}
public var body: some View {
@@ -51,7 +54,7 @@ public struct BarChartView : View {
.font(.headline)
.foregroundColor(self.style.textColor)
}
if(self.style.chartFormSize == Form.large && self.legend != nil && !showValue) {
if(self.formSize == Form.large && self.legend != nil && !showValue) {
Text(self.legend!)
.font(.callout)
.foregroundColor(self.style.accentColor)
@@ -64,7 +67,7 @@ public struct BarChartView : View {
.foregroundColor(self.style.legendTextColor)
}.padding()
BarChartRow(data: data, accentColor: self.style.accentColor, secondGradientAccentColor: self.style.secondGradientColor, touchLocation: self.$touchLocation)
if self.legend != nil && self.style.chartFormSize == Form.medium {
if self.legend != nil && self.formSize == Form.medium {
Text(self.legend!)
.font(.headline)
.foregroundColor(self.style.legendTextColor)
@@ -72,10 +75,10 @@ public struct BarChartView : View {
}
}
}.frame(minWidth:self.style.chartFormSize.width, maxWidth: self.isFullWidth ? .infinity : self.style.chartFormSize.width, minHeight:self.style.chartFormSize.height, maxHeight:self.style.chartFormSize.height)
}.frame(minWidth:self.formSize.width, maxWidth: self.isFullWidth ? .infinity : self.formSize.width, minHeight:self.formSize.height, maxHeight:self.formSize.height)
.gesture(DragGesture()
.onChanged({ value in
self.touchLocation = value.location.x/self.style.chartFormSize.width
self.touchLocation = value.location.x/self.formSize.width
self.showValue = true
self.currentValue = self.getCurrentValue()
})
@@ -89,7 +92,7 @@ public struct BarChartView : View {
}
func getCurrentValue()-> Int{
let index = max(0,min(self.data.count-1,Int(floor((self.touchLocation*self.style.chartFormSize.width)/(self.style.chartFormSize.width/CGFloat(self.data.count))))))
let index = max(0,min(self.data.count-1,Int(floor((self.touchLocation*self.formSize.width)/(self.formSize.width/CGFloat(self.data.count))))))
print(index)
return self.data[index]
}
+25 -14
View File
@@ -27,8 +27,6 @@ public struct Colors {
public static let GradientLowerBlue:Color = Color(hexString: "#F1F9FF")
public static let DarkPurple:Color = Color(hexString: "#1B205E")
public static let BorderBlue:Color = Color(hexString: "#4EBCFF")
}
public struct Styles {
@@ -36,7 +34,6 @@ public struct Styles {
backgroundColor: Color.white,
accentColor: Colors.OrangeStart,
secondGradientColor: Colors.OrangeEnd,
chartFormSize: Form.medium,
textColor: Color.black,
legendTextColor: Color.gray)
@@ -44,7 +41,6 @@ public struct Styles {
backgroundColor: Color.white,
accentColor: Colors.OrangeStart,
secondGradientColor: Colors.OrangeEnd,
chartFormSize: Form.medium,
textColor: Color.black,
legendTextColor: Color.gray)
@@ -52,7 +48,6 @@ public struct Styles {
backgroundColor: Color.black,
accentColor: Colors.OrangeStart,
secondGradientColor: Colors.OrangeEnd,
chartFormSize: Form.medium,
textColor: Color.white,
legendTextColor: Color.gray)
@@ -60,7 +55,6 @@ public struct Styles {
backgroundColor: Color.white,
accentColor: Colors.GradientNeonBlue,
secondGradientColor: Colors.GradientPurple,
chartFormSize: Form.medium,
textColor: Color.black,
legendTextColor: Color.gray)
@@ -68,7 +62,6 @@ public struct Styles {
backgroundColor: Color.black,
accentColor: Colors.GradientNeonBlue,
secondGradientColor: Colors.GradientPurple,
chartFormSize: Form.medium,
textColor: Color.white,
legendTextColor: Color.gray)
@@ -76,7 +69,6 @@ public struct Styles {
backgroundColor: Color(hexString: "#36534D"), //3B5147, 313D34
accentColor: Color(hexString: "#FFD603"),
secondGradientColor: Color(hexString: "#FFCA04"),
chartFormSize: Form.medium,
textColor: Color.white,
legendTextColor: Color(hexString: "#D2E5E1"))
@@ -84,7 +76,6 @@ public struct Styles {
backgroundColor: Color.white,
accentColor: Color(hexString: "#84A094"), //84A094 , 698378
secondGradientColor: Color(hexString: "#50675D"),
chartFormSize: Form.medium,
textColor: Color.black,
legendTextColor:Color.gray)
@@ -92,31 +83,37 @@ public struct Styles {
backgroundColor: Color.white,
accentColor: Colors.OrangeStart,
secondGradientColor: Colors.OrangeEnd,
chartFormSize: Form.medium,
textColor: Color.black,
legendTextColor: Color.gray)
}
public struct Form {
#if os(watchOS)
public static let small = CGSize(width:120, height:90)
public static let medium = CGSize(width:120, height:160)
public static let large = CGSize(width:180, height:90)
public static let detail = CGSize(width:180, height:160)
#else
public static let small = CGSize(width:180, height:120)
public static let medium = CGSize(width:180, height:240)
public static let large = CGSize(width:360, height:120)
public static let detail = CGSize(width:180, height:120)
#endif
}
public struct ChartStyle {
public var backgroundColor: Color
public var accentColor: Color
public var secondGradientColor: Color
public var chartFormSize: CGSize
public var textColor: Color
public var legendTextColor: Color
public init(backgroundColor: Color, accentColor: Color, secondGradientColor: Color, chartFormSize: CGSize, textColor: Color, legendTextColor: Color){
public init(backgroundColor: Color, accentColor: Color, secondGradientColor: Color, textColor: Color, legendTextColor: Color){
self.backgroundColor = backgroundColor
self.accentColor = accentColor
self.secondGradientColor = secondGradientColor
self.chartFormSize = chartFormSize
self.textColor = textColor
self.legendTextColor = legendTextColor
}
@@ -125,7 +122,6 @@ public struct ChartStyle {
self.backgroundColor = Color.white
self.accentColor = Colors.OrangeStart
self.secondGradientColor = Colors.OrangeEnd
self.chartFormSize = formSize
self.legendTextColor = Color.gray
self.textColor = Color.black
}
@@ -163,3 +159,18 @@ extension Color {
self.init(red: Double(r) / 255, green: Double(g) / 255, blue: Double(b) / 255)
}
}
class HapticFeedback {
#if os(watchOS)
//watchOS implementation
static func playSelection() -> Void {
WKInterfaceDevice.current().play(.click)
}
#else
//iOS implementation
let selectionFeedbackGenerator = UISelectionFeedbackGenerator()
static func playSelection() -> Void {
UISelectionFeedbackGenerator().selectionChanged()
}
#endif
}
@@ -9,28 +9,31 @@
import SwiftUI
public struct LineChartView: View {
let selectionFeedbackGenerator = UISelectionFeedbackGenerator()
// let selectionFeedbackGenerator = UISelectionFeedbackGenerator()
@ObservedObject var data:ChartData
public var title: String
public var legend: String?
public var style: ChartStyle
public var formSize:CGSize
@State private var touchLocation:CGPoint = .zero
@State private var showIndicatorDot: Bool = false
@State private var currentValue: Int = 2 {
didSet{
if (oldValue != self.currentValue && showIndicatorDot) {
selectionFeedbackGenerator.selectionChanged()
// selectionFeedbackGenerator.selectionChanged()
HapticFeedback.playSelection()
}
}
}
let frame = CGSize(width: 180, height: 120)
public init(data: [Int], title: String, legend: String? = nil, style: ChartStyle = Styles.lineChartStyleOne ){
public init(data: [Int], title: String, legend: String? = nil, style: ChartStyle = Styles.lineChartStyleOne, form: CGSize? = Form.medium){
self.data = ChartData(points: data)
self.title = title
self.legend = legend
self.style = style
self.formSize = form!
}
public var body: some View {
@@ -70,7 +73,7 @@ public struct LineChartView: View {
.frame(width: frame.width, height: frame.height)
.clipShape(RoundedRectangle(cornerRadius: 20))
.offset(x: 0, y: 0)
}.frame(width: self.style.chartFormSize.width, height: self.style.chartFormSize.height)
}.frame(width: self.formSize.width, height: self.formSize.height)
}
.gesture(DragGesture()
.onChanged({ value in
@@ -13,11 +13,13 @@ public struct PieChartView : View {
public var title: String
public var legend: String?
public var style: ChartStyle
public init(data: [Int], title: String, legend: String? = nil, style: ChartStyle = Styles.pieChartStyleOne ){
public var formSize:CGSize
public init(data: [Int], title: String, legend: String? = nil, style: ChartStyle = Styles.pieChartStyleOne, form: CGSize? = Form.medium ){
self.data = data
self.title = title
self.legend = legend
self.style = style
self.formSize = form!
}
public var body: some View {
@@ -46,7 +48,7 @@ public struct PieChartView : View {
}
}
}.frame(width: self.style.chartFormSize.width, height: self.style.chartFormSize.height)
}.frame(width: self.formSize.width, height: self.formSize.height)
}
}
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 73 KiB