Compare commits

...

8 Commits

Author SHA1 Message Date
Andras Samu 4699847a9a Fixed missing self in piechartrow 2020-08-01 11:50:22 +02:00
Lebron 6c768ad47e created interaction for PieChart (#147) 2020-08-01 11:32:52 +02:00
Abdullah Alhaider 6c612fae18 Fix typo (#144) 2020-07-26 09:21:03 +02:00
Andras Samu 812e02815f Update README.md 2020-07-25 20:07:09 +02:00
Andras Samu c6610f5679 Fixed control flow error 2020-07-05 11:02:56 +02:00
Andras Samu 47052674f5 Builded with xcode 12 2020-06-28 14:52:46 +02:00
Andras Samu a36c1db2f8 Update README.md 2020-06-27 14:50:41 +02:00
Roderic Campbell ca19dd578c Cleanup the explicitly unwrapped parameters which had a default value… (#123)
* Cleanup the explicitly unwrapped parameters which had a default value anyway

* Remove print statement
2020-06-27 09:27:55 +02:00
9 changed files with 115 additions and 24 deletions
@@ -7,7 +7,7 @@
<key>SwiftUICharts.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>1</integer>
<integer>3</integer>
</dict>
</dict>
</dict>
+5 -1
View File
@@ -2,6 +2,10 @@
Swift package for displaying charts effortlessly.
**V2 Beta 1 is released, if you would like to try it out you can find a [demo project here](https://github.com/AppPear/ChartViewV2Demo)**
**iOS 14 WidgetKit support is coming. In V2 I will update current charts and possibly extend with some new chart types to provide the best support for building informative and beautiful widgets for the new home screen 🥳 Stay tuned!**
![SwiftUI Charts](./Resources/showcase1.gif "SwiftUI Charts")
### Note:
@@ -22,7 +26,7 @@ Join our Slack channel for day to day conversation and more insights:
It requires iOS 13 and Xcode 11!
In Xcode got to `File -> Swift Packages -> Add Package Dependency` and paste inthe repo's url: `https://github.com/AppPear/ChartView`
In Xcode go to `File -> Swift Packages -> Add Package Dependency` and paste in the repo's url: `https://github.com/AppPear/ChartView`
### Usage:
@@ -34,7 +34,6 @@ public struct Line: View {
if minDataValue != nil && maxDataValue != nil {
min = minDataValue!
max = maxDataValue!
print(min,max)
}else if let minPoint = points.min(), let maxPoint = points.max(), minPoint != maxPoint {
min = minPoint
max = maxPoint
@@ -14,7 +14,7 @@ public struct MultiLineChartView: View {
public var legend: String?
public var style: ChartStyle
public var darkModeStyle: ChartStyle
public var formSize:CGSize
public var formSize: CGSize
public var dropShadow: Bool
public var valueSpecifier:String
@@ -44,27 +44,27 @@ public struct MultiLineChartView: View {
}
var frame = CGSize(width: 180, height: 120)
private var rateValue: Int
private var rateValue: Int?
public init(data: [([Double], GradientColor)],
title: String,
legend: String? = nil,
style: ChartStyle = Styles.lineChartStyleOne,
form: CGSize? = ChartForm.medium,
rateValue: Int? = 14,
dropShadow: Bool? = true,
valueSpecifier: String? = "%.1f") {
form: CGSize = ChartForm.medium,
rateValue: Int? = nil,
dropShadow: Bool = true,
valueSpecifier: String = "%.1f") {
self.data = data.map({ MultiLineChartData(points: $0.0, gradient: $0.1)})
self.title = title
self.legend = legend
self.style = style
self.darkModeStyle = style.darkModeStyle != nil ? style.darkModeStyle! : Styles.lineViewDarkMode
self.formSize = form!
self.formSize = form
frame = CGSize(width: self.formSize.width, height: self.formSize.height/2)
self.rateValue = rateValue!
self.dropShadow = dropShadow!
self.valueSpecifier = valueSpecifier!
self.rateValue = rateValue
self.dropShadow = dropShadow
self.valueSpecifier = valueSpecifier
}
public var body: some View {
@@ -86,12 +86,12 @@ public struct MultiLineChartView: View {
.foregroundColor(self.colorScheme == .dark ? self.darkModeStyle.legendTextColor : self.style.legendTextColor)
}
HStack {
if (self.rateValue >= 0){
if (rateValue ?? 0 >= 0){
Image(systemName: "arrow.up")
}else{
Image(systemName: "arrow.down")
}
Text("\(self.rateValue)%")
Text("\(rateValue ?? 0)%")
}
}
.transition(.opacity)
@@ -0,0 +1,41 @@
//
// File.swift
//
//
// Created by on 2020/7/30.
//
import SwiftUI
func isPointInCircle(point: CGPoint, circleRect: CGRect) -> Bool {
let r = min(circleRect.width, circleRect.height) / 2
let center = CGPoint(x: circleRect.midX, y: circleRect.midY)
let dx = point.x - center.x
let dy = point.y - center.y
let distance = sqrt(dx * dx + dy * dy)
return distance <= r
}
func degree(for point: CGPoint, inCircleRect circleRect: CGRect) -> Double {
let center = CGPoint(x: circleRect.midX, y: circleRect.midY)
let dx = point.x - center.x
let dy = point.y - center.y
let acuteDegree = Double(atan(dy / dx)) * (180 / .pi)
let isInBottomRight = dx >= 0 && dy >= 0
let isInBottomLeft = dx <= 0 && dy >= 0
let isInTopLeft = dx <= 0 && dy <= 0
let isInTopRight = dx >= 0 && dy <= 0
if isInBottomRight {
return acuteDegree
} else if isInBottomLeft {
return 180 - abs(acuteDegree)
} else if isInTopLeft {
return 180 + abs(acuteDegree)
} else if isInTopRight {
return 360 - abs(acuteDegree)
}
return 0
}
@@ -25,13 +25,42 @@ public struct PieChartRow : View {
}
return tempSlices
}
@Binding var showValue: Bool
@Binding var currentValue: Double
@State private var currentTouchedIndex = -1 {
didSet {
if oldValue != currentTouchedIndex {
showValue = currentTouchedIndex != -1
currentValue = showValue ? slices[currentTouchedIndex].value : 0
}
}
}
public var body: some View {
GeometryReader { geometry in
ZStack{
ForEach(0..<self.slices.count){ i in
PieChartCell(rect: geometry.frame(in: .local), startDeg: self.slices[i].startDeg, endDeg: self.slices[i].endDeg, index: i, backgroundColor: self.backgroundColor,accentColor: self.accentColor)
.scaleEffect(self.currentTouchedIndex == i ? 1.1 : 1)
.animation(Animation.spring())
}
}
.gesture(DragGesture()
.onChanged({ value in
let rect = geometry.frame(in: .local)
let isTouchInPie = isPointInCircle(point: value.location, circleRect: rect)
if isTouchInPie {
let touchDegree = degree(for: value.location, inCircleRect: rect)
self.currentTouchedIndex = self.slices.firstIndex(where: { $0.startDeg < touchDegree && $0.endDeg > touchDegree }) ?? -1
} else {
self.currentTouchedIndex = -1
}
})
.onEnded({ value in
self.currentTouchedIndex = -1
}))
}
}
}
@@ -40,10 +69,11 @@ public struct PieChartRow : View {
struct PieChartRow_Previews : PreviewProvider {
static var previews: some View {
Group {
PieChartRow(data:[8,23,54,32,12,37,7,23,43], backgroundColor: Color(red: 252.0/255.0, green: 236.0/255.0, blue: 234.0/255.0), accentColor: Color(red: 225.0/255.0, green: 97.0/255.0, blue: 76.0/255.0)).frame(width: 100, height: 100)
PieChartRow(data:[0], backgroundColor: Color(red: 252.0/255.0, green: 236.0/255.0, blue: 234.0/255.0), accentColor: Color(red: 225.0/255.0, green: 97.0/255.0, blue: 76.0/255.0)).frame(width: 100, height: 100)
PieChartRow(data:[8,23,54,32,12,37,7,23,43], backgroundColor: Color(red: 252.0/255.0, green: 236.0/255.0, blue: 234.0/255.0), accentColor: Color(red: 225.0/255.0, green: 97.0/255.0, blue: 76.0/255.0), showValue: Binding.constant(false), currentValue: Binding.constant(0))
.frame(width: 100, height: 100)
PieChartRow(data:[0], backgroundColor: Color(red: 252.0/255.0, green: 236.0/255.0, blue: 234.0/255.0), accentColor: Color(red: 225.0/255.0, green: 97.0/255.0, blue: 76.0/255.0), showValue: Binding.constant(false), currentValue: Binding.constant(0))
.frame(width: 100, height: 100)
}
}
}
#endif
@@ -15,8 +15,18 @@ public struct PieChartView : View {
public var style: ChartStyle
public var formSize:CGSize
public var dropShadow: Bool
public init(data: [Double], title: String, legend: String? = nil, style: ChartStyle = Styles.pieChartStyleOne, form: CGSize? = ChartForm.medium, dropShadow: Bool? = true){
public var valueSpecifier:String
@State private var showValue = false
@State private var currentValue: Double = 0 {
didSet{
if(oldValue != self.currentValue && self.showValue) {
HapticFeedback.playSelection()
}
}
}
public init(data: [Double], title: String, legend: String? = nil, style: ChartStyle = Styles.pieChartStyleOne, form: CGSize? = ChartForm.medium, dropShadow: Bool? = true, valueSpecifier: String? = "%.1f"){
self.data = data
self.title = title
self.legend = legend
@@ -26,6 +36,7 @@ public struct PieChartView : View {
self.formSize = ChartForm.extraLarge
}
self.dropShadow = dropShadow!
self.valueSpecifier = valueSpecifier!
}
public var body: some View {
@@ -36,15 +47,21 @@ public struct PieChartView : View {
.shadow(color: self.style.dropShadowColor, radius: self.dropShadow ? 12 : 0)
VStack(alignment: .leading){
HStack{
Text(self.title)
.font(.headline)
.foregroundColor(self.style.textColor)
if(!showValue){
Text(self.title)
.font(.headline)
.foregroundColor(self.style.textColor)
}else{
Text("\(self.currentValue, specifier: self.valueSpecifier)")
.font(.headline)
.foregroundColor(self.style.textColor)
}
Spacer()
Image(systemName: "chart.pie.fill")
.imageScale(.large)
.foregroundColor(self.style.legendTextColor)
}.padding()
PieChartRow(data: data, backgroundColor: self.style.backgroundColor, accentColor: self.style.accentColor)
PieChartRow(data: data, backgroundColor: self.style.backgroundColor, accentColor: self.style.accentColor, showValue: $showValue, currentValue: $currentValue)
.foregroundColor(self.style.accentColor).padding(self.legend != nil ? 0 : 12).offset(y:self.legend != nil ? 0 : -10)
if(self.legend != nil) {
Text(self.legend!)