Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 4699847a9a | |||
| 6c768ad47e | |||
| 6c612fae18 | |||
| 812e02815f | |||
| c6610f5679 |
Generated
BIN
Binary file not shown.
@@ -7,7 +7,7 @@
|
||||
<key>SwiftUICharts.xcscheme_^#shared#^_</key>
|
||||
<dict>
|
||||
<key>orderHint</key>
|
||||
<integer>0</integer>
|
||||
<integer>3</integer>
|
||||
</dict>
|
||||
</dict>
|
||||
</dict>
|
||||
|
||||
@@ -2,7 +2,9 @@
|
||||
|
||||
Swift package for displaying charts effortlessly.
|
||||
|
||||
**First release of version 2.0 is coming soon! Also iOS 14 WidgetKit support is coming. 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!**
|
||||
**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!**
|
||||
|
||||

|
||||
|
||||
@@ -24,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:
|
||||
|
||||
|
||||
@@ -85,15 +85,13 @@ public struct MultiLineChartView: View {
|
||||
.font(.callout)
|
||||
.foregroundColor(self.colorScheme == .dark ? self.darkModeStyle.legendTextColor : self.style.legendTextColor)
|
||||
}
|
||||
if let rateValue = rateValue {
|
||||
HStack {
|
||||
if (rateValue >= 0){
|
||||
Image(systemName: "arrow.up")
|
||||
}else{
|
||||
Image(systemName: "arrow.down")
|
||||
}
|
||||
Text("\(rateValue)%")
|
||||
HStack {
|
||||
if (rateValue ?? 0 >= 0){
|
||||
Image(systemName: "arrow.up")
|
||||
}else{
|
||||
Image(systemName: "arrow.down")
|
||||
}
|
||||
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!)
|
||||
|
||||
Reference in New Issue
Block a user