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
64 changes: 64 additions & 0 deletions .swiftlint.yml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
disabled_rules:
- explicit_acl
- trailing_whitespace
- force_cast
- unused_closure_parameter
- multiple_closures_with_trailing_closure
opt_in_rules:
- anyobject_protocol
- array_init
- attributes
- collection_alignment
- colon
- conditional_returns_on_newline
- convenience_type
- empty_count
- empty_string
- empty_collection_literal
- enum_case_associated_values_count
- function_default_parameter_at_end
- fatal_error_message
- file_name
- first_where
- modifier_order
- toggle_bool
- unused_private_declaration
- yoda_condition
excluded:
- Carthage
- Pods
- SwiftLint/Common/3rdPartyLib
identifier_name:
excluded:
- a
- b
- c
- i
- id
- t
- to
- x
- y
line_length:
warning: 150
error: 200
ignores_function_declarations: true
ignores_comments: true
ignores_urls: true
function_body_length:
warning: 300
error: 500
function_parameter_count:
warning: 6
error: 8
type_body_length:
warning: 300
error: 400
file_length:
warning: 500
error: 1200
ignore_comment_only_lines: true
cyclomatic_complexity:
warning: 15
error: 21
reporter: "xcode"
6 changes: 3 additions & 3 deletions Package.swift
Original file line numberDiff line numberDiff line change
Expand Up@@ -6,13 +6,13 @@ import PackageDescription
let package = Package(
name: "SwiftUICharts",
platforms: [
.iOS(.v13),.watchOS(.v6)
.iOS(.v13),.watchOS(.v6)
],
products: [
// Products define the executables and libraries produced by a package, and make them visible to other packages.
.library(
name: "SwiftUICharts",
targets: ["SwiftUICharts"]),
targets: ["SwiftUICharts"])
],
dependencies: [
// Dependencies declare other packages that this package depends on.
Expand All@@ -26,6 +26,6 @@ let package = Package(
dependencies: []),
.testTarget(
name: "SwiftUIChartsTests",
dependencies: ["SwiftUICharts"]),
dependencies: ["SwiftUICharts"])
]
)
16 changes: 16 additions & 0 deletions Sources/SwiftUICharts/Base/Extensions/CGRect+Extension.swift
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
//
// CGRect+Extension.swift
// SwiftUICharts
//
// Created by Nicolas Savoini on 2020-05-24.
//

import Foundation
import SwiftUI

extension CGRect {
// Return the coordinate for a rectangle center
public var mid: CGPoint {
return CGPoint(x: self.midX, y: self.midY)
}
}
12 changes: 6 additions & 6 deletions Sources/SwiftUICharts/Base/Extensions/Color+Extension.swift
Original file line numberDiff line numberDiff line change
Expand Up@@ -5,17 +5,17 @@ extension Color {
let hex = hexString.trimmingCharacters(in: CharacterSet.alphanumerics.inverted)
var int = UInt64()
Scanner(string: hex).scanHexInt64(&int)
let r, g, b: UInt64
let red, green, blue: UInt64
switch hex.count {
case 3: // RGB (12-bit)
(r, g, b) = ((int >> 8) * 17, (int >> 4 & 0xF) * 17, (int & 0xF) * 17)
(red, green, blue) = ((int >> 8) * 17, (int >> 4 & 0xF) * 17, (int & 0xF) * 17)
case 6: // RGB (24-bit)
(r, g, b) = (int >> 16, int >> 8 & 0xFF, int & 0xFF)
(red, green, blue) = (int >> 16, int >> 8 & 0xFF, int & 0xFF)
case 8: // ARGB (32-bit)
(r, g, b) = (int >> 16 & 0xFF, int >> 8 & 0xFF, int & 0xFF)
(red, green, blue) = (int >> 16 & 0xFF, int >> 8 & 0xFF, int & 0xFF)
default:
(r, g, b) = (0, 0, 0)
(red, green, blue) = (0, 0, 0)
}
self.init(red: Double(r) / 255, green: Double(g) / 255, blue: Double(b) / 255)
self.init(red: Double(red) / 255, green: Double(green) / 255, blue: Double(blue) / 255)
}
}
21 changes: 19 additions & 2 deletions Sources/SwiftUICharts/Base/Style/ChartStyle.swift
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,28 @@
import SwiftUI

public struct ChartStyle {
public let backgroundColor: Color
public let foregroundColor: ColorGradient

public let backgroundColor: ColorGradient
public let foregroundColor: [ColorGradient]

public init(backgroundColor: Color, foregroundColor: [ColorGradient]) {
self.backgroundColor = ColorGradient.init(backgroundColor)
self.foregroundColor = foregroundColor
}

public init(backgroundColor: Color, foregroundColor: ColorGradient) {
self.backgroundColor = ColorGradient.init(backgroundColor)
self.foregroundColor = [foregroundColor]
}

public init(backgroundColor: ColorGradient, foregroundColor: ColorGradient) {
self.backgroundColor = backgroundColor
self.foregroundColor = [foregroundColor]
}

public init(backgroundColor: ColorGradient, foregroundColor: [ColorGradient]) {
self.backgroundColor = backgroundColor
self.foregroundColor = foregroundColor
}

}
23 changes: 23 additions & 0 deletions Sources/SwiftUICharts/Base/Style/ColorGradient.swift
Original file line numberDiff line numberDiff line change
Expand Up@@ -4,6 +4,11 @@ public struct ColorGradient {
public let startColor: Color
public let endColor: Color

public init(_ color: Color) {
self.startColor = color
self.endColor = color
}

public init (_ startColor: Color, _ endColor: Color) {
self.startColor = startColor
self.endColor = endColor
Expand All@@ -13,3 +18,21 @@ public struct ColorGradient {
return Gradient(colors: [startColor, endColor])
}
}

extension ColorGradient {
/// Convenience method to return a LinearGradient from the ColorGradient
/// - Parameters:
/// - startPoint: starting point
/// - endPoint: ending point
/// - Returns: a Linear gradient
public func linearGradient(from startPoint: UnitPoint, to endPoint: UnitPoint) -> LinearGradient {
return LinearGradient(gradient: self.gradient, startPoint: startPoint, endPoint: endPoint)
}
}

extension ColorGradient {
public static let orangeBright = ColorGradient(ChartColors.orangeBright)
public static let redBlack = ColorGradient(.red, .black)
public static let greenRed = ColorGradient(.green, .red)
public static let whiteBlack = ColorGradient(.white, .black)
}
22 changes: 20 additions & 2 deletions Sources/SwiftUICharts/Charts/BarChart/BarChart.swift
Original file line numberDiff line numberDiff line change
Expand Up@@ -2,8 +2,26 @@ import SwiftUI

public struct BarChart: ChartType {
public func makeChart(configuration: Self.Configuration, style: Self.Style) -> some View {
BarChartRow(data: configuration.data, gradientColor: style.foregroundColor)
BarChartRow(data: configuration.data, style: style)
}

public init() {}
}

struct BarChart_Previews: PreviewProvider {
static var previews: some View {
Group {
Group {
BarChart().makeChart(
configuration: .init(data: [1, 2, 3, 5, 1]),
style: .init(backgroundColor: .white, foregroundColor: ColorGradient.redBlack))
}.environment(\.colorScheme, .light)

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

}
}
}
26 changes: 23 additions & 3 deletions Sources/SwiftUICharts/Charts/BarChart/BarChartCell.swift
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
import SwiftUI

public struct BarChartCell: View {
public struct BarChartCell: View {
@State var value: Double
@State var index: Int = 0
@State var width: Float
Expand All@@ -13,16 +13,36 @@ public struct BarChartCell : View {

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

public var body: some View {
ZStack {
RoundedRectangle(cornerRadius: 4)
.fill(LinearGradient(gradient: gradientColor.gradient, startPoint: .bottom, endPoint: .top))
.fill(gradientColor.linearGradient(from: .bottom, to: .top))
}
.frame(width: CGFloat(self.cellWidth))
.scaleEffect(CGSize(width: 1, height: self.scaleValue), anchor: .bottom)
.onAppear(){
.onAppear{
self.scaleValue = self.value
}
.animation(Animation.spring().delay(self.touchLocation < 0 ? Double(self.index) * 0.04 : 0))
}
}

struct BarChartCell_Previews: PreviewProvider {
static var previews: some View {
Group {
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()))
}

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()))
}.environment(\.colorScheme, .dark)
}

}
}
37 changes: 30 additions & 7 deletions Sources/SwiftUICharts/Charts/BarChart/BarChartRow.swift
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
import SwiftUI

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

enum Constant {
static let spacing: CGFloat = 16.0
}

var gradientColor: ColorGradient
var style: ChartStyle

var maxValue: Double {
data.max() ?? 0
}
Expand All@@ -17,14 +18,14 @@ public struct BarChartRow : 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) { i in
BarChartCell(value: self.normalizedValue(index: i),
index: i,
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.gradientColor,
gradientColor: self.style.foregroundColor.rotate(for: index),
touchLocation: self.$touchLocation)
.scaleEffect(self.getScaleSize(touchLocation: self.touchLocation, index: i), anchor: .bottom)
.scaleEffect(self.getScaleSize(touchLocation: self.touchLocation, index: index), anchor: .bottom)
.animation(.spring())

}
Expand DownExpand Up@@ -52,4 +53,26 @@ public struct BarChartRow : View {
}
return CGSize(width: 1, height: 1)
}

}

struct BarChartRow_Previews: PreviewProvider {
static var previews: some View {
Group {
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])
18 changes: 15 additions & 3 deletions Sources/SwiftUICharts/Charts/LineChart/Line.swift
Original file line numberDiff line numberDiff line change
Expand Up@@ -3,7 +3,7 @@ import SwiftUI
public struct Line: View {
@State var frame: CGRect = .zero
@State var data: [Double]
var gradientColor: ColorGradient
var style: ChartStyle

@State var showIndicator: Bool = false
@State var touchLocation: CGPoint = .zero
Expand DownExpand Up@@ -79,7 +79,7 @@ extension Line {

private func getBackgroundPathView() -> some View {
self.closedPath
.fill(LinearGradient(gradient: gradientColor.gradient, startPoint: .bottom, endPoint: .top))
.fill(style.backgroundColor.linearGradient(from: .bottom, to: .top))
.rotationEffect(.degrees(180), anchor: .center)
.rotation3DEffect(.degrees(180), axis: (x: 0, y: 1, z: 0))
.transition(.opacity)
Expand All@@ -89,7 +89,7 @@ extension Line {
private func getLinePathView() -> some View {
self.path
.trim(from: 0, to: self.showFull ? 1:0)
.stroke(LinearGradient(gradient: gradientColor.gradient,
.stroke(LinearGradient(gradient: style.foregroundColor.first?.gradient ?? ColorGradient.orangeBright.gradient,
startPoint: .leading,
endPoint: .trailing),
style: StrokeStyle(lineWidth: 3, lineJoin: .round))
Expand All@@ -105,3 +105,15 @@ extension Line {
.drawingGroup()
}
}

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)
}
}
}

private let blackLineStyle = ChartStyle(backgroundColor: ColorGradient(.white), foregroundColor: ColorGradient(.black))
private let redLineStyle = ChartStyle(backgroundColor: .whiteBlack, foregroundColor: ColorGradient(.red))
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content
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
64 changes: 64 additions & 0 deletions .swiftlint.yml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
disabled_rules:
- explicit_acl
- trailing_whitespace
- force_cast
- unused_closure_parameter
- multiple_closures_with_trailing_closure
opt_in_rules:
- anyobject_protocol
- array_init
- attributes
- collection_alignment
- colon
- conditional_returns_on_newline
- convenience_type
- empty_count
- empty_string
- empty_collection_literal
- enum_case_associated_values_count
- function_default_parameter_at_end
- fatal_error_message
- file_name
- first_where
- modifier_order
- toggle_bool
- unused_private_declaration
- yoda_condition
excluded:
- Carthage
- Pods
- SwiftLint/Common/3rdPartyLib
identifier_name:
excluded:
- a
- b
- c
- i
- id
- t
- to
- x
- y
line_length:
warning: 150
error: 200
ignores_function_declarations: true
ignores_comments: true
ignores_urls: true
function_body_length:
warning: 300
error: 500
function_parameter_count:
warning: 6
error: 8
type_body_length:
warning: 300
error: 400
file_length:
warning: 500
error: 1200
ignore_comment_only_lines: true
cyclomatic_complexity:
warning: 15
error: 21
reporter: "xcode"
6 changes: 3 additions & 3 deletions Package.swift
Original file line numberDiff line numberDiff line change
Expand Up@@ -6,13 +6,13 @@ import PackageDescription
let package = Package(
name: "SwiftUICharts",
platforms: [
.iOS(.v13),.watchOS(.v6)
.iOS(.v13),.watchOS(.v6)
],
products: [
// Products define the executables and libraries produced by a package, and make them visible to other packages.
.library(
name: "SwiftUICharts",
targets: ["SwiftUICharts"]),
targets: ["SwiftUICharts"])
],
dependencies: [
// Dependencies declare other packages that this package depends on.
Expand All@@ -26,6 +26,6 @@ let package = Package(
dependencies: []),
.testTarget(
name: "SwiftUIChartsTests",
dependencies: ["SwiftUICharts"]),
dependencies: ["SwiftUICharts"])
]
)
16 changes: 16 additions & 0 deletions Sources/SwiftUICharts/Base/Extensions/CGRect+Extension.swift
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
//
// CGRect+Extension.swift
// SwiftUICharts
//
// Created by Nicolas Savoini on 2020-05-24.
//

import Foundation
import SwiftUI

extension CGRect {
// Return the coordinate for a rectangle center
public var mid: CGPoint {
return CGPoint(x: self.midX, y: self.midY)
}
}
12 changes: 6 additions & 6 deletions Sources/SwiftUICharts/Base/Extensions/Color+Extension.swift
Original file line numberDiff line numberDiff line change
Expand Up@@ -5,17 +5,17 @@ extension Color {
let hex = hexString.trimmingCharacters(in: CharacterSet.alphanumerics.inverted)
var int = UInt64()
Scanner(string: hex).scanHexInt64(&int)
let r, g, b: UInt64
let red, green, blue: UInt64
switch hex.count {
case 3: // RGB (12-bit)
(r, g, b) = ((int >> 8) * 17, (int >> 4 & 0xF) * 17, (int & 0xF) * 17)
(red, green, blue) = ((int >> 8) * 17, (int >> 4 & 0xF) * 17, (int & 0xF) * 17)
case 6: // RGB (24-bit)
(r, g, b) = (int >> 16, int >> 8 & 0xFF, int & 0xFF)
(red, green, blue) = (int >> 16, int >> 8 & 0xFF, int & 0xFF)
case 8: // ARGB (32-bit)
(r, g, b) = (int >> 16 & 0xFF, int >> 8 & 0xFF, int & 0xFF)
(red, green, blue) = (int >> 16 & 0xFF, int >> 8 & 0xFF, int & 0xFF)
default:
(r, g, b) = (0, 0, 0)
(red, green, blue) = (0, 0, 0)
}
self.init(red: Double(r) / 255, green: Double(g) / 255, blue: Double(b) / 255)
self.init(red: Double(red) / 255, green: Double(green) / 255, blue: Double(blue) / 255)
}
}
21 changes: 19 additions & 2 deletions Sources/SwiftUICharts/Base/Style/ChartStyle.swift
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,28 @@
import SwiftUI

public struct ChartStyle {
public let backgroundColor: Color
public let foregroundColor: ColorGradient

public let backgroundColor: ColorGradient
public let foregroundColor: [ColorGradient]

public init(backgroundColor: Color, foregroundColor: [ColorGradient]) {
self.backgroundColor = ColorGradient.init(backgroundColor)
self.foregroundColor = foregroundColor
}

public init(backgroundColor: Color, foregroundColor: ColorGradient) {
self.backgroundColor = ColorGradient.init(backgroundColor)
self.foregroundColor = [foregroundColor]
}

public init(backgroundColor: ColorGradient, foregroundColor: ColorGradient) {
self.backgroundColor = backgroundColor
self.foregroundColor = [foregroundColor]
}

public init(backgroundColor: ColorGradient, foregroundColor: [ColorGradient]) {
self.backgroundColor = backgroundColor
self.foregroundColor = foregroundColor
}

}
23 changes: 23 additions & 0 deletions Sources/SwiftUICharts/Base/Style/ColorGradient.swift
Original file line numberDiff line numberDiff line change
Expand Up@@ -4,6 +4,11 @@ public struct ColorGradient {
public let startColor: Color
public let endColor: Color

public init(_ color: Color) {
self.startColor = color
self.endColor = color
}

public init (_ startColor: Color, _ endColor: Color) {
self.startColor = startColor
self.endColor = endColor
Expand All@@ -13,3 +18,21 @@ public struct ColorGradient {
return Gradient(colors: [startColor, endColor])
}
}

extension ColorGradient {
/// Convenience method to return a LinearGradient from the ColorGradient
/// - Parameters:
/// - startPoint: starting point
/// - endPoint: ending point
/// - Returns: a Linear gradient
public func linearGradient(from startPoint: UnitPoint, to endPoint: UnitPoint) -> LinearGradient {
return LinearGradient(gradient: self.gradient, startPoint: startPoint, endPoint: endPoint)
}
}

extension ColorGradient {
public static let orangeBright = ColorGradient(ChartColors.orangeBright)
public static let redBlack = ColorGradient(.red, .black)
public static let greenRed = ColorGradient(.green, .red)
public static let whiteBlack = ColorGradient(.white, .black)
}
22 changes: 20 additions & 2 deletions Sources/SwiftUICharts/Charts/BarChart/BarChart.swift
Original file line numberDiff line numberDiff line change
Expand Up@@ -2,8 +2,26 @@ import SwiftUI

public struct BarChart: ChartType {
public func makeChart(configuration: Self.Configuration, style: Self.Style) -> some View {
BarChartRow(data: configuration.data, gradientColor: style.foregroundColor)
BarChartRow(data: configuration.data, style: style)
}

public init() {}
}

struct BarChart_Previews: PreviewProvider {
static var previews: some View {
Group {
Group {
BarChart().makeChart(
configuration: .init(data: [1, 2, 3, 5, 1]),
style: .init(backgroundColor: .white, foregroundColor: ColorGradient.redBlack))
}.environment(\.colorScheme, .light)

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

}
}
}
26 changes: 23 additions & 3 deletions Sources/SwiftUICharts/Charts/BarChart/BarChartCell.swift
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
import SwiftUI

public struct BarChartCell: View {
public struct BarChartCell: View {
@State var value: Double
@State var index: Int = 0
@State var width: Float
Expand All@@ -13,16 +13,36 @@ public struct BarChartCell : View {

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

public var body: some View {
ZStack {
RoundedRectangle(cornerRadius: 4)
.fill(LinearGradient(gradient: gradientColor.gradient, startPoint: .bottom, endPoint: .top))
.fill(gradientColor.linearGradient(from: .bottom, to: .top))
}
.frame(width: CGFloat(self.cellWidth))
.scaleEffect(CGSize(width: 1, height: self.scaleValue), anchor: .bottom)
.onAppear(){
.onAppear{
self.scaleValue = self.value
}
.animation(Animation.spring().delay(self.touchLocation < 0 ? Double(self.index) * 0.04 : 0))
}
}

struct BarChartCell_Previews: PreviewProvider {
static var previews: some View {
Group {
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()))
}

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()))
}.environment(\.colorScheme, .dark)
}

}
}
37 changes: 30 additions & 7 deletions Sources/SwiftUICharts/Charts/BarChart/BarChartRow.swift
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
import SwiftUI

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

enum Constant {
static let spacing: CGFloat = 16.0
}

var gradientColor: ColorGradient
var style: ChartStyle

var maxValue: Double {
data.max() ?? 0
}
Expand All@@ -17,14 +18,14 @@ public struct BarChartRow : 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) { i in
BarChartCell(value: self.normalizedValue(index: i),
index: i,
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.gradientColor,
gradientColor: self.style.foregroundColor.rotate(for: index),
touchLocation: self.$touchLocation)
.scaleEffect(self.getScaleSize(touchLocation: self.touchLocation, index: i), anchor: .bottom)
.scaleEffect(self.getScaleSize(touchLocation: self.touchLocation, index: index), anchor: .bottom)
.animation(.spring())

}
Expand DownExpand Up@@ -52,4 +53,26 @@ public struct BarChartRow : View {
}
return CGSize(width: 1, height: 1)
}

}

struct BarChartRow_Previews: PreviewProvider {
static var previews: some View {
Group {
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])
18 changes: 15 additions & 3 deletions Sources/SwiftUICharts/Charts/LineChart/Line.swift
Original file line numberDiff line numberDiff line change
Expand Up@@ -3,7 +3,7 @@ import SwiftUI
public struct Line: View {
@State var frame: CGRect = .zero
@State var data: [Double]
var gradientColor: ColorGradient
var style: ChartStyle

@State var showIndicator: Bool = false
@State var touchLocation: CGPoint = .zero
Expand DownExpand Up@@ -79,7 +79,7 @@ extension Line {

private func getBackgroundPathView() -> some View {
self.closedPath
.fill(LinearGradient(gradient: gradientColor.gradient, startPoint: .bottom, endPoint: .top))
.fill(style.backgroundColor.linearGradient(from: .bottom, to: .top))
.rotationEffect(.degrees(180), anchor: .center)
.rotation3DEffect(.degrees(180), axis: (x: 0, y: 1, z: 0))
.transition(.opacity)
Expand All@@ -89,7 +89,7 @@ extension Line {
private func getLinePathView() -> some View {
self.path
.trim(from: 0, to: self.showFull ? 1:0)
.stroke(LinearGradient(gradient: gradientColor.gradient,
.stroke(LinearGradient(gradient: style.foregroundColor.first?.gradient ?? ColorGradient.orangeBright.gradient,
startPoint: .leading,
endPoint: .trailing),
style: StrokeStyle(lineWidth: 3, lineJoin: .round))
Expand All@@ -105,3 +105,15 @@ extension Line {
.drawingGroup()
}
}

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)
}
}
}

private let blackLineStyle = ChartStyle(backgroundColor: ColorGradient(.white), foregroundColor: ColorGradient(.black))
private let redLineStyle = ChartStyle(backgroundColor: .whiteBlack, foregroundColor: ColorGradient(.red))
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
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
64 changes: 64 additions & 0 deletions .swiftlint.yml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
disabled_rules:
- explicit_acl
- trailing_whitespace
- force_cast
- unused_closure_parameter
- multiple_closures_with_trailing_closure
opt_in_rules:
- anyobject_protocol
- array_init
- attributes
- collection_alignment
- colon
- conditional_returns_on_newline
- convenience_type
- empty_count
- empty_string
- empty_collection_literal
- enum_case_associated_values_count
- function_default_parameter_at_end
- fatal_error_message
- file_name
- first_where
- modifier_order
- toggle_bool
- unused_private_declaration
- yoda_condition
excluded:
- Carthage
- Pods
- SwiftLint/Common/3rdPartyLib
identifier_name:
excluded:
- a
- b
- c
- i
- id
- t
- to
- x
- y
line_length:
warning: 150
error: 200
ignores_function_declarations: true
ignores_comments: true
ignores_urls: true
function_body_length:
warning: 300
error: 500
function_parameter_count:
warning: 6
error: 8
type_body_length:
warning: 300
error: 400
file_length:
warning: 500
error: 1200
ignore_comment_only_lines: true
cyclomatic_complexity:
warning: 15
error: 21
reporter: "xcode"
6 changes: 3 additions & 3 deletions Package.swift
Original file line numberDiff line numberDiff line change
Expand Up@@ -6,13 +6,13 @@ import PackageDescription
let package = Package(
name: "SwiftUICharts",
platforms: [
.iOS(.v13),.watchOS(.v6)
.iOS(.v13),.watchOS(.v6)
],
products: [
// Products define the executables and libraries produced by a package, and make them visible to other packages.
.library(
name: "SwiftUICharts",
targets: ["SwiftUICharts"]),
targets: ["SwiftUICharts"])
],
dependencies: [
// Dependencies declare other packages that this package depends on.
Expand All@@ -26,6 +26,6 @@ let package = Package(
dependencies: []),
.testTarget(
name: "SwiftUIChartsTests",
dependencies: ["SwiftUICharts"]),
dependencies: ["SwiftUICharts"])
]
)
16 changes: 16 additions & 0 deletions Sources/SwiftUICharts/Base/Extensions/CGRect+Extension.swift
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
//
// CGRect+Extension.swift
// SwiftUICharts
//
// Created by Nicolas Savoini on 2020-05-24.
//

import Foundation
import SwiftUI

extension CGRect {
// Return the coordinate for a rectangle center
public var mid: CGPoint {
return CGPoint(x: self.midX, y: self.midY)
}
}
12 changes: 6 additions & 6 deletions Sources/SwiftUICharts/Base/Extensions/Color+Extension.swift
Original file line numberDiff line numberDiff line change
Expand Up@@ -5,17 +5,17 @@ extension Color {
let hex = hexString.trimmingCharacters(in: CharacterSet.alphanumerics.inverted)
var int = UInt64()
Scanner(string: hex).scanHexInt64(&int)
let r, g, b: UInt64
let red, green, blue: UInt64
switch hex.count {
case 3: // RGB (12-bit)
(r, g, b) = ((int >> 8) * 17, (int >> 4 & 0xF) * 17, (int & 0xF) * 17)
(red, green, blue) = ((int >> 8) * 17, (int >> 4 & 0xF) * 17, (int & 0xF) * 17)
case 6: // RGB (24-bit)
(r, g, b) = (int >> 16, int >> 8 & 0xFF, int & 0xFF)
(red, green, blue) = (int >> 16, int >> 8 & 0xFF, int & 0xFF)
case 8: // ARGB (32-bit)
(r, g, b) = (int >> 16 & 0xFF, int >> 8 & 0xFF, int & 0xFF)
(red, green, blue) = (int >> 16 & 0xFF, int >> 8 & 0xFF, int & 0xFF)
default:
(r, g, b) = (0, 0, 0)
(red, green, blue) = (0, 0, 0)
}
self.init(red: Double(r) / 255, green: Double(g) / 255, blue: Double(b) / 255)
self.init(red: Double(red) / 255, green: Double(green) / 255, blue: Double(blue) / 255)
}
}
21 changes: 19 additions & 2 deletions Sources/SwiftUICharts/Base/Style/ChartStyle.swift
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,28 @@
import SwiftUI

public struct ChartStyle {
public let backgroundColor: Color
public let foregroundColor: ColorGradient

public let backgroundColor: ColorGradient
public let foregroundColor: [ColorGradient]

public init(backgroundColor: Color, foregroundColor: [ColorGradient]) {
self.backgroundColor = ColorGradient.init(backgroundColor)
self.foregroundColor = foregroundColor
}

public init(backgroundColor: Color, foregroundColor: ColorGradient) {
self.backgroundColor = ColorGradient.init(backgroundColor)
self.foregroundColor = [foregroundColor]
}

public init(backgroundColor: ColorGradient, foregroundColor: ColorGradient) {
self.backgroundColor = backgroundColor
self.foregroundColor = [foregroundColor]
}

public init(backgroundColor: ColorGradient, foregroundColor: [ColorGradient]) {
self.backgroundColor = backgroundColor
self.foregroundColor = foregroundColor
}

}
23 changes: 23 additions & 0 deletions Sources/SwiftUICharts/Base/Style/ColorGradient.swift
Original file line numberDiff line numberDiff line change
Expand Up@@ -4,6 +4,11 @@ public struct ColorGradient {
public let startColor: Color
public let endColor: Color

public init(_ color: Color) {
self.startColor = color
self.endColor = color
}

public init (_ startColor: Color, _ endColor: Color) {
self.startColor = startColor
self.endColor = endColor
Expand All@@ -13,3 +18,21 @@ public struct ColorGradient {
return Gradient(colors: [startColor, endColor])
}
}

extension ColorGradient {
/// Convenience method to return a LinearGradient from the ColorGradient
/// - Parameters:
/// - startPoint: starting point
/// - endPoint: ending point
/// - Returns: a Linear gradient
public func linearGradient(from startPoint: UnitPoint, to endPoint: UnitPoint) -> LinearGradient {
return LinearGradient(gradient: self.gradient, startPoint: startPoint, endPoint: endPoint)
}
}

extension ColorGradient {
public static let orangeBright = ColorGradient(ChartColors.orangeBright)
public static let redBlack = ColorGradient(.red, .black)
public static let greenRed = ColorGradient(.green, .red)
public static let whiteBlack = ColorGradient(.white, .black)
}
22 changes: 20 additions & 2 deletions Sources/SwiftUICharts/Charts/BarChart/BarChart.swift
Original file line numberDiff line numberDiff line change
Expand Up@@ -2,8 +2,26 @@ import SwiftUI

public struct BarChart: ChartType {
public func makeChart(configuration: Self.Configuration, style: Self.Style) -> some View {
BarChartRow(data: configuration.data, gradientColor: style.foregroundColor)
BarChartRow(data: configuration.data, style: style)
}

public init() {}
}

struct BarChart_Previews: PreviewProvider {
static var previews: some View {
Group {
Group {
BarChart().makeChart(
configuration: .init(data: [1, 2, 3, 5, 1]),
style: .init(backgroundColor: .white, foregroundColor: ColorGradient.redBlack))
}.environment(\.colorScheme, .light)

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

}
}
}
26 changes: 23 additions & 3 deletions Sources/SwiftUICharts/Charts/BarChart/BarChartCell.swift
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
import SwiftUI

public struct BarChartCell: View {
public struct BarChartCell: View {
@State var value: Double
@State var index: Int = 0
@State var width: Float
Expand All@@ -13,16 +13,36 @@ public struct BarChartCell : View {

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

public var body: some View {
ZStack {
RoundedRectangle(cornerRadius: 4)
.fill(LinearGradient(gradient: gradientColor.gradient, startPoint: .bottom, endPoint: .top))
.fill(gradientColor.linearGradient(from: .bottom, to: .top))
}
.frame(width: CGFloat(self.cellWidth))
.scaleEffect(CGSize(width: 1, height: self.scaleValue), anchor: .bottom)
.onAppear(){
.onAppear{
self.scaleValue = self.value
}
.animation(Animation.spring().delay(self.touchLocation < 0 ? Double(self.index) * 0.04 : 0))
}
}

struct BarChartCell_Previews: PreviewProvider {
static var previews: some View {
Group {
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()))
}

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()))
}.environment(\.colorScheme, .dark)
}

}
}
37 changes: 30 additions & 7 deletions Sources/SwiftUICharts/Charts/BarChart/BarChartRow.swift
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
import SwiftUI

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

enum Constant {
static let spacing: CGFloat = 16.0
}

var gradientColor: ColorGradient
var style: ChartStyle

var maxValue: Double {
data.max() ?? 0
}
Expand All@@ -17,14 +18,14 @@ public struct BarChartRow : 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) { i in
BarChartCell(value: self.normalizedValue(index: i),
index: i,
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.gradientColor,
gradientColor: self.style.foregroundColor.rotate(for: index),
touchLocation: self.$touchLocation)
.scaleEffect(self.getScaleSize(touchLocation: self.touchLocation, index: i), anchor: .bottom)
.scaleEffect(self.getScaleSize(touchLocation: self.touchLocation, index: index), anchor: .bottom)
.animation(.spring())

}
Expand DownExpand Up@@ -52,4 +53,26 @@ public struct BarChartRow : View {
}
return CGSize(width: 1, height: 1)
}

}

struct BarChartRow_Previews: PreviewProvider {
static var previews: some View {
Group {
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])
18 changes: 15 additions & 3 deletions Sources/SwiftUICharts/Charts/LineChart/Line.swift
Original file line numberDiff line numberDiff line change
Expand Up@@ -3,7 +3,7 @@ import SwiftUI
public struct Line: View {
@State var frame: CGRect = .zero
@State var data: [Double]
var gradientColor: ColorGradient
var style: ChartStyle

@State var showIndicator: Bool = false
@State var touchLocation: CGPoint = .zero
Expand DownExpand Up@@ -79,7 +79,7 @@ extension Line {

private func getBackgroundPathView() -> some View {
self.closedPath
.fill(LinearGradient(gradient: gradientColor.gradient, startPoint: .bottom, endPoint: .top))
.fill(style.backgroundColor.linearGradient(from: .bottom, to: .top))
.rotationEffect(.degrees(180), anchor: .center)
.rotation3DEffect(.degrees(180), axis: (x: 0, y: 1, z: 0))
.transition(.opacity)
Expand All@@ -89,7 +89,7 @@ extension Line {
private func getLinePathView() -> some View {
self.path
.trim(from: 0, to: self.showFull ? 1:0)
.stroke(LinearGradient(gradient: gradientColor.gradient,
.stroke(LinearGradient(gradient: style.foregroundColor.first?.gradient ?? ColorGradient.orangeBright.gradient,
startPoint: .leading,
endPoint: .trailing),
style: StrokeStyle(lineWidth: 3, lineJoin: .round))
Expand All@@ -105,3 +105,15 @@ extension Line {
.drawingGroup()
}
}

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)
}
}
}

private let blackLineStyle = ChartStyle(backgroundColor: ColorGradient(.white), foregroundColor: ColorGradient(.black))
private let redLineStyle = ChartStyle(backgroundColor: .whiteBlack, foregroundColor: ColorGradient(.red))
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
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
64 changes: 64 additions & 0 deletions .swiftlint.yml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
disabled_rules:
- explicit_acl
- trailing_whitespace
- force_cast
- unused_closure_parameter
- multiple_closures_with_trailing_closure
opt_in_rules:
- anyobject_protocol
- array_init
- attributes
- collection_alignment
- colon
- conditional_returns_on_newline
- convenience_type
- empty_count
- empty_string
- empty_collection_literal
- enum_case_associated_values_count
- function_default_parameter_at_end
- fatal_error_message
- file_name
- first_where
- modifier_order
- toggle_bool
- unused_private_declaration
- yoda_condition
excluded:
- Carthage
- Pods
- SwiftLint/Common/3rdPartyLib
identifier_name:
excluded:
- a
- b
- c
- i
- id
- t
- to
- x
- y
line_length:
warning: 150
error: 200
ignores_function_declarations: true
ignores_comments: true
ignores_urls: true
function_body_length:
warning: 300
error: 500
function_parameter_count:
warning: 6
error: 8
type_body_length:
warning: 300
error: 400
file_length:
warning: 500
error: 1200
ignore_comment_only_lines: true
cyclomatic_complexity:
warning: 15
error: 21
reporter: "xcode"
6 changes: 3 additions & 3 deletions Package.swift
Original file line numberDiff line numberDiff line change
Expand Up@@ -6,13 +6,13 @@ import PackageDescription
let package = Package(
name: "SwiftUICharts",
platforms: [
.iOS(.v13),.watchOS(.v6)
.iOS(.v13),.watchOS(.v6)
],
products: [
// Products define the executables and libraries produced by a package, and make them visible to other packages.
.library(
name: "SwiftUICharts",
targets: ["SwiftUICharts"]),
targets: ["SwiftUICharts"])
],
dependencies: [
// Dependencies declare other packages that this package depends on.
Expand All@@ -26,6 +26,6 @@ let package = Package(
dependencies: []),
.testTarget(
name: "SwiftUIChartsTests",
dependencies: ["SwiftUICharts"]),
dependencies: ["SwiftUICharts"])
]
)
16 changes: 16 additions & 0 deletions Sources/SwiftUICharts/Base/Extensions/CGRect+Extension.swift
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
//
// CGRect+Extension.swift
// SwiftUICharts
//
// Created by Nicolas Savoini on 2020-05-24.
//

import Foundation
import SwiftUI

extension CGRect {
// Return the coordinate for a rectangle center
public var mid: CGPoint {
return CGPoint(x: self.midX, y: self.midY)
}
}
12 changes: 6 additions & 6 deletions Sources/SwiftUICharts/Base/Extensions/Color+Extension.swift
Original file line numberDiff line numberDiff line change
Expand Up@@ -5,17 +5,17 @@ extension Color {
let hex = hexString.trimmingCharacters(in: CharacterSet.alphanumerics.inverted)
var int = UInt64()
Scanner(string: hex).scanHexInt64(&int)
let r, g, b: UInt64
let red, green, blue: UInt64
switch hex.count {
case 3: // RGB (12-bit)
(r, g, b) = ((int >> 8) * 17, (int >> 4 & 0xF) * 17, (int & 0xF) * 17)
(red, green, blue) = ((int >> 8) * 17, (int >> 4 & 0xF) * 17, (int & 0xF) * 17)
case 6: // RGB (24-bit)
(r, g, b) = (int >> 16, int >> 8 & 0xFF, int & 0xFF)
(red, green, blue) = (int >> 16, int >> 8 & 0xFF, int & 0xFF)
case 8: // ARGB (32-bit)
(r, g, b) = (int >> 16 & 0xFF, int >> 8 & 0xFF, int & 0xFF)
(red, green, blue) = (int >> 16 & 0xFF, int >> 8 & 0xFF, int & 0xFF)
default:
(r, g, b) = (0, 0, 0)
(red, green, blue) = (0, 0, 0)
}
self.init(red: Double(r) / 255, green: Double(g) / 255, blue: Double(b) / 255)
self.init(red: Double(red) / 255, green: Double(green) / 255, blue: Double(blue) / 255)
}
}
21 changes: 19 additions & 2 deletions Sources/SwiftUICharts/Base/Style/ChartStyle.swift
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,28 @@
import SwiftUI

public struct ChartStyle {
public let backgroundColor: Color
public let foregroundColor: ColorGradient

public let backgroundColor: ColorGradient
public let foregroundColor: [ColorGradient]

public init(backgroundColor: Color, foregroundColor: [ColorGradient]) {
self.backgroundColor = ColorGradient.init(backgroundColor)
self.foregroundColor = foregroundColor
}

public init(backgroundColor: Color, foregroundColor: ColorGradient) {
self.backgroundColor = ColorGradient.init(backgroundColor)
self.foregroundColor = [foregroundColor]
}

public init(backgroundColor: ColorGradient, foregroundColor: ColorGradient) {
self.backgroundColor = backgroundColor
self.foregroundColor = [foregroundColor]
}

public init(backgroundColor: ColorGradient, foregroundColor: [ColorGradient]) {
self.backgroundColor = backgroundColor
self.foregroundColor = foregroundColor
}

}
23 changes: 23 additions & 0 deletions Sources/SwiftUICharts/Base/Style/ColorGradient.swift
Original file line numberDiff line numberDiff line change
Expand Up@@ -4,6 +4,11 @@ public struct ColorGradient {
public let startColor: Color
public let endColor: Color

public init(_ color: Color) {
self.startColor = color
self.endColor = color
}

public init (_ startColor: Color, _ endColor: Color) {
self.startColor = startColor
self.endColor = endColor
Expand All@@ -13,3 +18,21 @@ public struct ColorGradient {
return Gradient(colors: [startColor, endColor])
}
}

extension ColorGradient {
/// Convenience method to return a LinearGradient from the ColorGradient
/// - Parameters:
/// - startPoint: starting point
/// - endPoint: ending point
/// - Returns: a Linear gradient
public func linearGradient(from startPoint: UnitPoint, to endPoint: UnitPoint) -> LinearGradient {
return LinearGradient(gradient: self.gradient, startPoint: startPoint, endPoint: endPoint)
}
}

extension ColorGradient {
public static let orangeBright = ColorGradient(ChartColors.orangeBright)
public static let redBlack = ColorGradient(.red, .black)
public static let greenRed = ColorGradient(.green, .red)
public static let whiteBlack = ColorGradient(.white, .black)
}
22 changes: 20 additions & 2 deletions Sources/SwiftUICharts/Charts/BarChart/BarChart.swift
Original file line numberDiff line numberDiff line change
Expand Up@@ -2,8 +2,26 @@ import SwiftUI

public struct BarChart: ChartType {
public func makeChart(configuration: Self.Configuration, style: Self.Style) -> some View {
BarChartRow(data: configuration.data, gradientColor: style.foregroundColor)
BarChartRow(data: configuration.data, style: style)
}

public init() {}
}

struct BarChart_Previews: PreviewProvider {
static var previews: some View {
Group {
Group {
BarChart().makeChart(
configuration: .init(data: [1, 2, 3, 5, 1]),
style: .init(backgroundColor: .white, foregroundColor: ColorGradient.redBlack))
}.environment(\.colorScheme, .light)

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

}
}
}
26 changes: 23 additions & 3 deletions Sources/SwiftUICharts/Charts/BarChart/BarChartCell.swift
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
import SwiftUI

public struct BarChartCell: View {
public struct BarChartCell: View {
@State var value: Double
@State var index: Int = 0
@State var width: Float
Expand All@@ -13,16 +13,36 @@ public struct BarChartCell : View {

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

public var body: some View {
ZStack {
RoundedRectangle(cornerRadius: 4)
.fill(LinearGradient(gradient: gradientColor.gradient, startPoint: .bottom, endPoint: .top))
.fill(gradientColor.linearGradient(from: .bottom, to: .top))
}
.frame(width: CGFloat(self.cellWidth))
.scaleEffect(CGSize(width: 1, height: self.scaleValue), anchor: .bottom)
.onAppear(){
.onAppear{
self.scaleValue = self.value
}
.animation(Animation.spring().delay(self.touchLocation < 0 ? Double(self.index) * 0.04 : 0))
}
}

struct BarChartCell_Previews: PreviewProvider {
static var previews: some View {
Group {
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()))
}

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()))
}.environment(\.colorScheme, .dark)
}

}
}
37 changes: 30 additions & 7 deletions Sources/SwiftUICharts/Charts/BarChart/BarChartRow.swift
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
import SwiftUI

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

enum Constant {
static let spacing: CGFloat = 16.0
}

var gradientColor: ColorGradient
var style: ChartStyle

var maxValue: Double {
data.max() ?? 0
}
Expand All@@ -17,14 +18,14 @@ public struct BarChartRow : 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) { i in
BarChartCell(value: self.normalizedValue(index: i),
index: i,
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.gradientColor,
gradientColor: self.style.foregroundColor.rotate(for: index),
touchLocation: self.$touchLocation)
.scaleEffect(self.getScaleSize(touchLocation: self.touchLocation, index: i), anchor: .bottom)
.scaleEffect(self.getScaleSize(touchLocation: self.touchLocation, index: index), anchor: .bottom)
.animation(.spring())

}
Expand DownExpand Up@@ -52,4 +53,26 @@ public struct BarChartRow : View {
}
return CGSize(width: 1, height: 1)
}

}

struct BarChartRow_Previews: PreviewProvider {
static var previews: some View {
Group {
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])
18 changes: 15 additions & 3 deletions Sources/SwiftUICharts/Charts/LineChart/Line.swift
Original file line numberDiff line numberDiff line change
Expand Up@@ -3,7 +3,7 @@ import SwiftUI
public struct Line: View {
@State var frame: CGRect = .zero
@State var data: [Double]
var gradientColor: ColorGradient
var style: ChartStyle

@State var showIndicator: Bool = false
@State var touchLocation: CGPoint = .zero
Expand DownExpand Up@@ -79,7 +79,7 @@ extension Line {

private func getBackgroundPathView() -> some View {
self.closedPath
.fill(LinearGradient(gradient: gradientColor.gradient, startPoint: .bottom, endPoint: .top))
.fill(style.backgroundColor.linearGradient(from: .bottom, to: .top))
.rotationEffect(.degrees(180), anchor: .center)
.rotation3DEffect(.degrees(180), axis: (x: 0, y: 1, z: 0))
.transition(.opacity)
Expand All@@ -89,7 +89,7 @@ extension Line {
private func getLinePathView() -> some View {
self.path
.trim(from: 0, to: self.showFull ? 1:0)
.stroke(LinearGradient(gradient: gradientColor.gradient,
.stroke(LinearGradient(gradient: style.foregroundColor.first?.gradient ?? ColorGradient.orangeBright.gradient,
startPoint: .leading,
endPoint: .trailing),
style: StrokeStyle(lineWidth: 3, lineJoin: .round))
Expand All@@ -105,3 +105,15 @@ extension Line {
.drawingGroup()
}
}

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)
}
}
}

private let blackLineStyle = ChartStyle(backgroundColor: ColorGradient(.white), foregroundColor: ColorGradient(.black))
private let redLineStyle = ChartStyle(backgroundColor: .whiteBlack, foregroundColor: ColorGradient(.red))
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content
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
64 changes: 64 additions & 0 deletions .swiftlint.yml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
disabled_rules:
- explicit_acl
- trailing_whitespace
- force_cast
- unused_closure_parameter
- multiple_closures_with_trailing_closure
opt_in_rules:
- anyobject_protocol
- array_init
- attributes
- collection_alignment
- colon
- conditional_returns_on_newline
- convenience_type
- empty_count
- empty_string
- empty_collection_literal
- enum_case_associated_values_count
- function_default_parameter_at_end
- fatal_error_message
- file_name
- first_where
- modifier_order
- toggle_bool
- unused_private_declaration
- yoda_condition
excluded:
- Carthage
- Pods
- SwiftLint/Common/3rdPartyLib
identifier_name:
excluded:
- a
- b
- c
- i
- id
- t
- to
- x
- y
line_length:
warning: 150
error: 200
ignores_function_declarations: true
ignores_comments: true
ignores_urls: true
function_body_length:
warning: 300
error: 500
function_parameter_count:
warning: 6
error: 8
type_body_length:
warning: 300
error: 400
file_length:
warning: 500
error: 1200
ignore_comment_only_lines: true
cyclomatic_complexity:
warning: 15
error: 21
reporter: "xcode"
6 changes: 3 additions & 3 deletions Package.swift
Original file line numberDiff line numberDiff line change
Expand Up@@ -6,13 +6,13 @@ import PackageDescription
let package = Package(
name: "SwiftUICharts",
platforms: [
.iOS(.v13),.watchOS(.v6)
.iOS(.v13),.watchOS(.v6)
],
products: [
// Products define the executables and libraries produced by a package, and make them visible to other packages.
.library(
name: "SwiftUICharts",
targets: ["SwiftUICharts"]),
targets: ["SwiftUICharts"])
],
dependencies: [
// Dependencies declare other packages that this package depends on.
Expand All@@ -26,6 +26,6 @@ let package = Package(
dependencies: []),
.testTarget(
name: "SwiftUIChartsTests",
dependencies: ["SwiftUICharts"]),
dependencies: ["SwiftUICharts"])
]
)
16 changes: 16 additions & 0 deletions Sources/SwiftUICharts/Base/Extensions/CGRect+Extension.swift
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
//
// CGRect+Extension.swift
// SwiftUICharts
//
// Created by Nicolas Savoini on 2020-05-24.
//

import Foundation
import SwiftUI

extension CGRect {
// Return the coordinate for a rectangle center
public var mid: CGPoint {
return CGPoint(x: self.midX, y: self.midY)
}
}
12 changes: 6 additions & 6 deletions Sources/SwiftUICharts/Base/Extensions/Color+Extension.swift
Original file line numberDiff line numberDiff line change
Expand Up@@ -5,17 +5,17 @@ extension Color {
let hex = hexString.trimmingCharacters(in: CharacterSet.alphanumerics.inverted)
var int = UInt64()
Scanner(string: hex).scanHexInt64(&int)
let r, g, b: UInt64
let red, green, blue: UInt64
switch hex.count {
case 3: // RGB (12-bit)
(r, g, b) = ((int >> 8) * 17, (int >> 4 & 0xF) * 17, (int & 0xF) * 17)
(red, green, blue) = ((int >> 8) * 17, (int >> 4 & 0xF) * 17, (int & 0xF) * 17)
case 6: // RGB (24-bit)
(r, g, b) = (int >> 16, int >> 8 & 0xFF, int & 0xFF)
(red, green, blue) = (int >> 16, int >> 8 & 0xFF, int & 0xFF)
case 8: // ARGB (32-bit)
(r, g, b) = (int >> 16 & 0xFF, int >> 8 & 0xFF, int & 0xFF)
(red, green, blue) = (int >> 16 & 0xFF, int >> 8 & 0xFF, int & 0xFF)
default:
(r, g, b) = (0, 0, 0)
(red, green, blue) = (0, 0, 0)
}
self.init(red: Double(r) / 255, green: Double(g) / 255, blue: Double(b) / 255)
self.init(red: Double(red) / 255, green: Double(green) / 255, blue: Double(blue) / 255)
}
}
21 changes: 19 additions & 2 deletions Sources/SwiftUICharts/Base/Style/ChartStyle.swift
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,28 @@
import SwiftUI

public struct ChartStyle {
public let backgroundColor: Color
public let foregroundColor: ColorGradient

public let backgroundColor: ColorGradient
public let foregroundColor: [ColorGradient]

public init(backgroundColor: Color, foregroundColor: [ColorGradient]) {
self.backgroundColor = ColorGradient.init(backgroundColor)
self.foregroundColor = foregroundColor
}

public init(backgroundColor: Color, foregroundColor: ColorGradient) {
self.backgroundColor = ColorGradient.init(backgroundColor)
self.foregroundColor = [foregroundColor]
}

public init(backgroundColor: ColorGradient, foregroundColor: ColorGradient) {
self.backgroundColor = backgroundColor
self.foregroundColor = [foregroundColor]
}

public init(backgroundColor: ColorGradient, foregroundColor: [ColorGradient]) {
self.backgroundColor = backgroundColor
self.foregroundColor = foregroundColor
}

}
23 changes: 23 additions & 0 deletions Sources/SwiftUICharts/Base/Style/ColorGradient.swift
Original file line numberDiff line numberDiff line change
Expand Up@@ -4,6 +4,11 @@ public struct ColorGradient {
public let startColor: Color
public let endColor: Color

public init(_ color: Color) {
self.startColor = color
self.endColor = color
}

public init (_ startColor: Color, _ endColor: Color) {
self.startColor = startColor
self.endColor = endColor
Expand All@@ -13,3 +18,21 @@ public struct ColorGradient {
return Gradient(colors: [startColor, endColor])
}
}

extension ColorGradient {
/// Convenience method to return a LinearGradient from the ColorGradient
/// - Parameters:
/// - startPoint: starting point
/// - endPoint: ending point
/// - Returns: a Linear gradient
public func linearGradient(from startPoint: UnitPoint, to endPoint: UnitPoint) -> LinearGradient {
return LinearGradient(gradient: self.gradient, startPoint: startPoint, endPoint: endPoint)
}
}

extension ColorGradient {
public static let orangeBright = ColorGradient(ChartColors.orangeBright)
public static let redBlack = ColorGradient(.red, .black)
public static let greenRed = ColorGradient(.green, .red)
public static let whiteBlack = ColorGradient(.white, .black)
}
22 changes: 20 additions & 2 deletions Sources/SwiftUICharts/Charts/BarChart/BarChart.swift
Original file line numberDiff line numberDiff line change
Expand Up@@ -2,8 +2,26 @@ import SwiftUI

public struct BarChart: ChartType {
public func makeChart(configuration: Self.Configuration, style: Self.Style) -> some View {
BarChartRow(data: configuration.data, gradientColor: style.foregroundColor)
BarChartRow(data: configuration.data, style: style)
}

public init() {}
}

struct BarChart_Previews: PreviewProvider {
static var previews: some View {
Group {
Group {
BarChart().makeChart(
configuration: .init(data: [1, 2, 3, 5, 1]),
style: .init(backgroundColor: .white, foregroundColor: ColorGradient.redBlack))
}.environment(\.colorScheme, .light)

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

}
}
}
26 changes: 23 additions & 3 deletions Sources/SwiftUICharts/Charts/BarChart/BarChartCell.swift
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
import SwiftUI

public struct BarChartCell: View {
public struct BarChartCell: View {
@State var value: Double
@State var index: Int = 0
@State var width: Float
Expand All@@ -13,16 +13,36 @@ public struct BarChartCell : View {

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

public var body: some View {
ZStack {
RoundedRectangle(cornerRadius: 4)
.fill(LinearGradient(gradient: gradientColor.gradient, startPoint: .bottom, endPoint: .top))
.fill(gradientColor.linearGradient(from: .bottom, to: .top))
}
.frame(width: CGFloat(self.cellWidth))
.scaleEffect(CGSize(width: 1, height: self.scaleValue), anchor: .bottom)
.onAppear(){
.onAppear{
self.scaleValue = self.value
}
.animation(Animation.spring().delay(self.touchLocation < 0 ? Double(self.index) * 0.04 : 0))
}
}

struct BarChartCell_Previews: PreviewProvider {
static var previews: some View {
Group {
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()))
}

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()))
}.environment(\.colorScheme, .dark)
}

}
}
37 changes: 30 additions & 7 deletions Sources/SwiftUICharts/Charts/BarChart/BarChartRow.swift
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
import SwiftUI

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

enum Constant {
static let spacing: CGFloat = 16.0
}

var gradientColor: ColorGradient
var style: ChartStyle

var maxValue: Double {
data.max() ?? 0
}
Expand All@@ -17,14 +18,14 @@ public struct BarChartRow : 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) { i in
BarChartCell(value: self.normalizedValue(index: i),
index: i,
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.gradientColor,
gradientColor: self.style.foregroundColor.rotate(for: index),
touchLocation: self.$touchLocation)
.scaleEffect(self.getScaleSize(touchLocation: self.touchLocation, index: i), anchor: .bottom)
.scaleEffect(self.getScaleSize(touchLocation: self.touchLocation, index: index), anchor: .bottom)
.animation(.spring())

}
Expand DownExpand Up@@ -52,4 +53,26 @@ public struct BarChartRow : View {
}
return CGSize(width: 1, height: 1)
}

}

struct BarChartRow_Previews: PreviewProvider {
static var previews: some View {
Group {
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])
18 changes: 15 additions & 3 deletions Sources/SwiftUICharts/Charts/LineChart/Line.swift
Original file line numberDiff line numberDiff line change
Expand Up@@ -3,7 +3,7 @@ import SwiftUI
public struct Line: View {
@State var frame: CGRect = .zero
@State var data: [Double]
var gradientColor: ColorGradient
var style: ChartStyle

@State var showIndicator: Bool = false
@State var touchLocation: CGPoint = .zero
Expand DownExpand Up@@ -79,7 +79,7 @@ extension Line {

private func getBackgroundPathView() -> some View {
self.closedPath
.fill(LinearGradient(gradient: gradientColor.gradient, startPoint: .bottom, endPoint: .top))
.fill(style.backgroundColor.linearGradient(from: .bottom, to: .top))
.rotationEffect(.degrees(180), anchor: .center)
.rotation3DEffect(.degrees(180), axis: (x: 0, y: 1, z: 0))
.transition(.opacity)
Expand All@@ -89,7 +89,7 @@ extension Line {
private func getLinePathView() -> some View {
self.path
.trim(from: 0, to: self.showFull ? 1:0)
.stroke(LinearGradient(gradient: gradientColor.gradient,
.stroke(LinearGradient(gradient: style.foregroundColor.first?.gradient ?? ColorGradient.orangeBright.gradient,
startPoint: .leading,
endPoint: .trailing),
style: StrokeStyle(lineWidth: 3, lineJoin: .round))
Expand All@@ -105,3 +105,15 @@ extension Line {
.drawingGroup()
}
}

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)
}
}
}

private let blackLineStyle = ChartStyle(backgroundColor: ColorGradient(.white), foregroundColor: ColorGradient(.black))
private let redLineStyle = ChartStyle(backgroundColor: .whiteBlack, foregroundColor: ColorGradient(.red))
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
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
64 changes: 64 additions & 0 deletions .swiftlint.yml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
disabled_rules:
- explicit_acl
- trailing_whitespace
- force_cast
- unused_closure_parameter
- multiple_closures_with_trailing_closure
opt_in_rules:
- anyobject_protocol
- array_init
- attributes
- collection_alignment
- colon
- conditional_returns_on_newline
- convenience_type
- empty_count
- empty_string
- empty_collection_literal
- enum_case_associated_values_count
- function_default_parameter_at_end
- fatal_error_message
- file_name
- first_where
- modifier_order
- toggle_bool
- unused_private_declaration
- yoda_condition
excluded:
- Carthage
- Pods
- SwiftLint/Common/3rdPartyLib
identifier_name:
excluded:
- a
- b
- c
- i
- id
- t
- to
- x
- y
line_length:
warning: 150
error: 200
ignores_function_declarations: true
ignores_comments: true
ignores_urls: true
function_body_length:
warning: 300
error: 500
function_parameter_count:
warning: 6
error: 8
type_body_length:
warning: 300
error: 400
file_length:
warning: 500
error: 1200
ignore_comment_only_lines: true
cyclomatic_complexity:
warning: 15
error: 21
reporter: "xcode"
6 changes: 3 additions & 3 deletions Package.swift
Original file line numberDiff line numberDiff line change
Expand Up@@ -6,13 +6,13 @@ import PackageDescription
let package = Package(
name: "SwiftUICharts",
platforms: [
.iOS(.v13),.watchOS(.v6)
.iOS(.v13),.watchOS(.v6)
],
products: [
// Products define the executables and libraries produced by a package, and make them visible to other packages.
.library(
name: "SwiftUICharts",
targets: ["SwiftUICharts"]),
targets: ["SwiftUICharts"])
],
dependencies: [
// Dependencies declare other packages that this package depends on.
Expand All@@ -26,6 +26,6 @@ let package = Package(
dependencies: []),
.testTarget(
name: "SwiftUIChartsTests",
dependencies: ["SwiftUICharts"]),
dependencies: ["SwiftUICharts"])
]
)
16 changes: 16 additions & 0 deletions Sources/SwiftUICharts/Base/Extensions/CGRect+Extension.swift
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
//
// CGRect+Extension.swift
// SwiftUICharts
//
// Created by Nicolas Savoini on 2020-05-24.
//

import Foundation
import SwiftUI

extension CGRect {
// Return the coordinate for a rectangle center
public var mid: CGPoint {
return CGPoint(x: self.midX, y: self.midY)
}
}
12 changes: 6 additions & 6 deletions Sources/SwiftUICharts/Base/Extensions/Color+Extension.swift
Original file line numberDiff line numberDiff line change
Expand Up@@ -5,17 +5,17 @@ extension Color {
let hex = hexString.trimmingCharacters(in: CharacterSet.alphanumerics.inverted)
var int = UInt64()
Scanner(string: hex).scanHexInt64(&int)
let r, g, b: UInt64
let red, green, blue: UInt64
switch hex.count {
case 3: // RGB (12-bit)
(r, g, b) = ((int >> 8) * 17, (int >> 4 & 0xF) * 17, (int & 0xF) * 17)
(red, green, blue) = ((int >> 8) * 17, (int >> 4 & 0xF) * 17, (int & 0xF) * 17)
case 6: // RGB (24-bit)
(r, g, b) = (int >> 16, int >> 8 & 0xFF, int & 0xFF)
(red, green, blue) = (int >> 16, int >> 8 & 0xFF, int & 0xFF)
case 8: // ARGB (32-bit)
(r, g, b) = (int >> 16 & 0xFF, int >> 8 & 0xFF, int & 0xFF)
(red, green, blue) = (int >> 16 & 0xFF, int >> 8 & 0xFF, int & 0xFF)
default:
(r, g, b) = (0, 0, 0)
(red, green, blue) = (0, 0, 0)
}
self.init(red: Double(r) / 255, green: Double(g) / 255, blue: Double(b) / 255)
self.init(red: Double(red) / 255, green: Double(green) / 255, blue: Double(blue) / 255)
}
}
21 changes: 19 additions & 2 deletions Sources/SwiftUICharts/Base/Style/ChartStyle.swift
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,28 @@
import SwiftUI

public struct ChartStyle {
public let backgroundColor: Color
public let foregroundColor: ColorGradient

public let backgroundColor: ColorGradient
public let foregroundColor: [ColorGradient]

public init(backgroundColor: Color, foregroundColor: [ColorGradient]) {
self.backgroundColor = ColorGradient.init(backgroundColor)
self.foregroundColor = foregroundColor
}

public init(backgroundColor: Color, foregroundColor: ColorGradient) {
self.backgroundColor = ColorGradient.init(backgroundColor)
self.foregroundColor = [foregroundColor]
}

public init(backgroundColor: ColorGradient, foregroundColor: ColorGradient) {
self.backgroundColor = backgroundColor
self.foregroundColor = [foregroundColor]
}

public init(backgroundColor: ColorGradient, foregroundColor: [ColorGradient]) {
self.backgroundColor = backgroundColor
self.foregroundColor = foregroundColor
}

}
23 changes: 23 additions & 0 deletions Sources/SwiftUICharts/Base/Style/ColorGradient.swift
Original file line numberDiff line numberDiff line change
Expand Up@@ -4,6 +4,11 @@ public struct ColorGradient {
public let startColor: Color
public let endColor: Color

public init(_ color: Color) {
self.startColor = color
self.endColor = color
}

public init (_ startColor: Color, _ endColor: Color) {
self.startColor = startColor
self.endColor = endColor
Expand All@@ -13,3 +18,21 @@ public struct ColorGradient {
return Gradient(colors: [startColor, endColor])
}
}

extension ColorGradient {
/// Convenience method to return a LinearGradient from the ColorGradient
/// - Parameters:
/// - startPoint: starting point
/// - endPoint: ending point
/// - Returns: a Linear gradient
public func linearGradient(from startPoint: UnitPoint, to endPoint: UnitPoint) -> LinearGradient {
return LinearGradient(gradient: self.gradient, startPoint: startPoint, endPoint: endPoint)
}
}

extension ColorGradient {
public static let orangeBright = ColorGradient(ChartColors.orangeBright)
public static let redBlack = ColorGradient(.red, .black)
public static let greenRed = ColorGradient(.green, .red)
public static let whiteBlack = ColorGradient(.white, .black)
}
22 changes: 20 additions & 2 deletions Sources/SwiftUICharts/Charts/BarChart/BarChart.swift
Original file line numberDiff line numberDiff line change
Expand Up@@ -2,8 +2,26 @@ import SwiftUI

public struct BarChart: ChartType {
public func makeChart(configuration: Self.Configuration, style: Self.Style) -> some View {
BarChartRow(data: configuration.data, gradientColor: style.foregroundColor)
BarChartRow(data: configuration.data, style: style)
}

public init() {}
}

struct BarChart_Previews: PreviewProvider {
static var previews: some View {
Group {
Group {
BarChart().makeChart(
configuration: .init(data: [1, 2, 3, 5, 1]),
style: .init(backgroundColor: .white, foregroundColor: ColorGradient.redBlack))
}.environment(\.colorScheme, .light)

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

}
}
}
26 changes: 23 additions & 3 deletions Sources/SwiftUICharts/Charts/BarChart/BarChartCell.swift
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
import SwiftUI

public struct BarChartCell: View {
public struct BarChartCell: View {
@State var value: Double
@State var index: Int = 0
@State var width: Float
Expand All@@ -13,16 +13,36 @@ public struct BarChartCell : View {

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

public var body: some View {
ZStack {
RoundedRectangle(cornerRadius: 4)
.fill(LinearGradient(gradient: gradientColor.gradient, startPoint: .bottom, endPoint: .top))
.fill(gradientColor.linearGradient(from: .bottom, to: .top))
}
.frame(width: CGFloat(self.cellWidth))
.scaleEffect(CGSize(width: 1, height: self.scaleValue), anchor: .bottom)
.onAppear(){
.onAppear{
self.scaleValue = self.value
}
.animation(Animation.spring().delay(self.touchLocation < 0 ? Double(self.index) * 0.04 : 0))
}
}

struct BarChartCell_Previews: PreviewProvider {
static var previews: some View {
Group {
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()))
}

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()))
}.environment(\.colorScheme, .dark)
}

}
}
37 changes: 30 additions & 7 deletions Sources/SwiftUICharts/Charts/BarChart/BarChartRow.swift
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
import SwiftUI

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

enum Constant {
static let spacing: CGFloat = 16.0
}

var gradientColor: ColorGradient
var style: ChartStyle

var maxValue: Double {
data.max() ?? 0
}
Expand All@@ -17,14 +18,14 @@ public struct BarChartRow : 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) { i in
BarChartCell(value: self.normalizedValue(index: i),
index: i,
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.gradientColor,
gradientColor: self.style.foregroundColor.rotate(for: index),
touchLocation: self.$touchLocation)
.scaleEffect(self.getScaleSize(touchLocation: self.touchLocation, index: i), anchor: .bottom)
.scaleEffect(self.getScaleSize(touchLocation: self.touchLocation, index: index), anchor: .bottom)
.animation(.spring())

}
Expand DownExpand Up@@ -52,4 +53,26 @@ public struct BarChartRow : View {
}
return CGSize(width: 1, height: 1)
}

}

struct BarChartRow_Previews: PreviewProvider {
static var previews: some View {
Group {
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])
18 changes: 15 additions & 3 deletions Sources/SwiftUICharts/Charts/LineChart/Line.swift
Original file line numberDiff line numberDiff line change
Expand Up@@ -3,7 +3,7 @@ import SwiftUI
public struct Line: View {
@State var frame: CGRect = .zero
@State var data: [Double]
var gradientColor: ColorGradient
var style: ChartStyle

@State var showIndicator: Bool = false
@State var touchLocation: CGPoint = .zero
Expand DownExpand Up@@ -79,7 +79,7 @@ extension Line {

private func getBackgroundPathView() -> some View {
self.closedPath
.fill(LinearGradient(gradient: gradientColor.gradient, startPoint: .bottom, endPoint: .top))
.fill(style.backgroundColor.linearGradient(from: .bottom, to: .top))
.rotationEffect(.degrees(180), anchor: .center)
.rotation3DEffect(.degrees(180), axis: (x: 0, y: 1, z: 0))
.transition(.opacity)
Expand All@@ -89,7 +89,7 @@ extension Line {
private func getLinePathView() -> some View {
self.path
.trim(from: 0, to: self.showFull ? 1:0)
.stroke(LinearGradient(gradient: gradientColor.gradient,
.stroke(LinearGradient(gradient: style.foregroundColor.first?.gradient ?? ColorGradient.orangeBright.gradient,
startPoint: .leading,
endPoint: .trailing),
style: StrokeStyle(lineWidth: 3, lineJoin: .round))
Expand All@@ -105,3 +105,15 @@ extension Line {
.drawingGroup()
}
}

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)
}
}
}

private let blackLineStyle = ChartStyle(backgroundColor: ColorGradient(.white), foregroundColor: ColorGradient(.black))
private let redLineStyle = ChartStyle(backgroundColor: .whiteBlack, foregroundColor: ColorGradient(.red))
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
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
64 changes: 64 additions & 0 deletions .swiftlint.yml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
disabled_rules:
- explicit_acl
- trailing_whitespace
- force_cast
- unused_closure_parameter
- multiple_closures_with_trailing_closure
opt_in_rules:
- anyobject_protocol
- array_init
- attributes
- collection_alignment
- colon
- conditional_returns_on_newline
- convenience_type
- empty_count
- empty_string
- empty_collection_literal
- enum_case_associated_values_count
- function_default_parameter_at_end
- fatal_error_message
- file_name
- first_where
- modifier_order
- toggle_bool
- unused_private_declaration
- yoda_condition
excluded:
- Carthage
- Pods
- SwiftLint/Common/3rdPartyLib
identifier_name:
excluded:
- a
- b
- c
- i
- id
- t
- to
- x
- y
line_length:
warning: 150
error: 200
ignores_function_declarations: true
ignores_comments: true
ignores_urls: true
function_body_length:
warning: 300
error: 500
function_parameter_count:
warning: 6
error: 8
type_body_length:
warning: 300
error: 400
file_length:
warning: 500
error: 1200
ignore_comment_only_lines: true
cyclomatic_complexity:
warning: 15
error: 21
reporter: "xcode"
6 changes: 3 additions & 3 deletions Package.swift
Original file line numberDiff line numberDiff line change
Expand Up@@ -6,13 +6,13 @@ import PackageDescription
let package = Package(
name: "SwiftUICharts",
platforms: [
.iOS(.v13),.watchOS(.v6)
.iOS(.v13),.watchOS(.v6)
],
products: [
// Products define the executables and libraries produced by a package, and make them visible to other packages.
.library(
name: "SwiftUICharts",
targets: ["SwiftUICharts"]),
targets: ["SwiftUICharts"])
],
dependencies: [
// Dependencies declare other packages that this package depends on.
Expand All@@ -26,6 +26,6 @@ let package = Package(
dependencies: []),
.testTarget(
name: "SwiftUIChartsTests",
dependencies: ["SwiftUICharts"]),
dependencies: ["SwiftUICharts"])
]
)
16 changes: 16 additions & 0 deletions Sources/SwiftUICharts/Base/Extensions/CGRect+Extension.swift
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
//
// CGRect+Extension.swift
// SwiftUICharts
//
// Created by Nicolas Savoini on 2020-05-24.
//

import Foundation
import SwiftUI

extension CGRect {
// Return the coordinate for a rectangle center
public var mid: CGPoint {
return CGPoint(x: self.midX, y: self.midY)
}
}
12 changes: 6 additions & 6 deletions Sources/SwiftUICharts/Base/Extensions/Color+Extension.swift
Original file line numberDiff line numberDiff line change
Expand Up@@ -5,17 +5,17 @@ extension Color {
let hex = hexString.trimmingCharacters(in: CharacterSet.alphanumerics.inverted)
var int = UInt64()
Scanner(string: hex).scanHexInt64(&int)
let r, g, b: UInt64
let red, green, blue: UInt64
switch hex.count {
case 3: // RGB (12-bit)
(r, g, b) = ((int >> 8) * 17, (int >> 4 & 0xF) * 17, (int & 0xF) * 17)
(red, green, blue) = ((int >> 8) * 17, (int >> 4 & 0xF) * 17, (int & 0xF) * 17)
case 6: // RGB (24-bit)
(r, g, b) = (int >> 16, int >> 8 & 0xFF, int & 0xFF)
(red, green, blue) = (int >> 16, int >> 8 & 0xFF, int & 0xFF)
case 8: // ARGB (32-bit)
(r, g, b) = (int >> 16 & 0xFF, int >> 8 & 0xFF, int & 0xFF)
(red, green, blue) = (int >> 16 & 0xFF, int >> 8 & 0xFF, int & 0xFF)
default:
(r, g, b) = (0, 0, 0)
(red, green, blue) = (0, 0, 0)
}
self.init(red: Double(r) / 255, green: Double(g) / 255, blue: Double(b) / 255)
self.init(red: Double(red) / 255, green: Double(green) / 255, blue: Double(blue) / 255)
}
}
21 changes: 19 additions & 2 deletions Sources/SwiftUICharts/Base/Style/ChartStyle.swift
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,28 @@
import SwiftUI

public struct ChartStyle {
public let backgroundColor: Color
public let foregroundColor: ColorGradient

public let backgroundColor: ColorGradient
public let foregroundColor: [ColorGradient]

public init(backgroundColor: Color, foregroundColor: [ColorGradient]) {
self.backgroundColor = ColorGradient.init(backgroundColor)
self.foregroundColor = foregroundColor
}

public init(backgroundColor: Color, foregroundColor: ColorGradient) {
self.backgroundColor = ColorGradient.init(backgroundColor)
self.foregroundColor = [foregroundColor]
}

public init(backgroundColor: ColorGradient, foregroundColor: ColorGradient) {
self.backgroundColor = backgroundColor
self.foregroundColor = [foregroundColor]
}

public init(backgroundColor: ColorGradient, foregroundColor: [ColorGradient]) {
self.backgroundColor = backgroundColor
self.foregroundColor = foregroundColor
}

}
23 changes: 23 additions & 0 deletions Sources/SwiftUICharts/Base/Style/ColorGradient.swift
Original file line numberDiff line numberDiff line change
Expand Up@@ -4,6 +4,11 @@ public struct ColorGradient {
public let startColor: Color
public let endColor: Color

public init(_ color: Color) {
self.startColor = color
self.endColor = color
}

public init (_ startColor: Color, _ endColor: Color) {
self.startColor = startColor
self.endColor = endColor
Expand All@@ -13,3 +18,21 @@ public struct ColorGradient {
return Gradient(colors: [startColor, endColor])
}
}

extension ColorGradient {
/// Convenience method to return a LinearGradient from the ColorGradient
/// - Parameters:
/// - startPoint: starting point
/// - endPoint: ending point
/// - Returns: a Linear gradient
public func linearGradient(from startPoint: UnitPoint, to endPoint: UnitPoint) -> LinearGradient {
return LinearGradient(gradient: self.gradient, startPoint: startPoint, endPoint: endPoint)
}
}

extension ColorGradient {
public static let orangeBright = ColorGradient(ChartColors.orangeBright)
public static let redBlack = ColorGradient(.red, .black)
public static let greenRed = ColorGradient(.green, .red)
public static let whiteBlack = ColorGradient(.white, .black)
}
22 changes: 20 additions & 2 deletions Sources/SwiftUICharts/Charts/BarChart/BarChart.swift
Original file line numberDiff line numberDiff line change
Expand Up@@ -2,8 +2,26 @@ import SwiftUI

public struct BarChart: ChartType {
public func makeChart(configuration: Self.Configuration, style: Self.Style) -> some View {
BarChartRow(data: configuration.data, gradientColor: style.foregroundColor)
BarChartRow(data: configuration.data, style: style)
}

public init() {}
}

struct BarChart_Previews: PreviewProvider {
static var previews: some View {
Group {
Group {
BarChart().makeChart(
configuration: .init(data: [1, 2, 3, 5, 1]),
style: .init(backgroundColor: .white, foregroundColor: ColorGradient.redBlack))
}.environment(\.colorScheme, .light)

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

}
}
}
26 changes: 23 additions & 3 deletions Sources/SwiftUICharts/Charts/BarChart/BarChartCell.swift
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
import SwiftUI

public struct BarChartCell: View {
public struct BarChartCell: View {
@State var value: Double
@State var index: Int = 0
@State var width: Float
Expand All@@ -13,16 +13,36 @@ public struct BarChartCell : View {

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

public var body: some View {
ZStack {
RoundedRectangle(cornerRadius: 4)
.fill(LinearGradient(gradient: gradientColor.gradient, startPoint: .bottom, endPoint: .top))
.fill(gradientColor.linearGradient(from: .bottom, to: .top))
}
.frame(width: CGFloat(self.cellWidth))
.scaleEffect(CGSize(width: 1, height: self.scaleValue), anchor: .bottom)
.onAppear(){
.onAppear{
self.scaleValue = self.value
}
.animation(Animation.spring().delay(self.touchLocation < 0 ? Double(self.index) * 0.04 : 0))
}
}

struct BarChartCell_Previews: PreviewProvider {
static var previews: some View {
Group {
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()))
}

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()))
}.environment(\.colorScheme, .dark)
}

}
}
37 changes: 30 additions & 7 deletions Sources/SwiftUICharts/Charts/BarChart/BarChartRow.swift
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
import SwiftUI

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

enum Constant {
static let spacing: CGFloat = 16.0
}

var gradientColor: ColorGradient
var style: ChartStyle

var maxValue: Double {
data.max() ?? 0
}
Expand All@@ -17,14 +18,14 @@ public struct BarChartRow : 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) { i in
BarChartCell(value: self.normalizedValue(index: i),
index: i,
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.gradientColor,
gradientColor: self.style.foregroundColor.rotate(for: index),
touchLocation: self.$touchLocation)
.scaleEffect(self.getScaleSize(touchLocation: self.touchLocation, index: i), anchor: .bottom)
.scaleEffect(self.getScaleSize(touchLocation: self.touchLocation, index: index), anchor: .bottom)
.animation(.spring())

}
Expand DownExpand Up@@ -52,4 +53,26 @@ public struct BarChartRow : View {
}
return CGSize(width: 1, height: 1)
}

}

struct BarChartRow_Previews: PreviewProvider {
static var previews: some View {
Group {
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])
18 changes: 15 additions & 3 deletions Sources/SwiftUICharts/Charts/LineChart/Line.swift
Original file line numberDiff line numberDiff line change
Expand Up@@ -3,7 +3,7 @@ import SwiftUI
public struct Line: View {
@State var frame: CGRect = .zero
@State var data: [Double]
var gradientColor: ColorGradient
var style: ChartStyle

@State var showIndicator: Bool = false
@State var touchLocation: CGPoint = .zero
Expand DownExpand Up@@ -79,7 +79,7 @@ extension Line {

private func getBackgroundPathView() -> some View {
self.closedPath
.fill(LinearGradient(gradient: gradientColor.gradient, startPoint: .bottom, endPoint: .top))
.fill(style.backgroundColor.linearGradient(from: .bottom, to: .top))
.rotationEffect(.degrees(180), anchor: .center)
.rotation3DEffect(.degrees(180), axis: (x: 0, y: 1, z: 0))
.transition(.opacity)
Expand All@@ -89,7 +89,7 @@ extension Line {
private func getLinePathView() -> some View {
self.path
.trim(from: 0, to: self.showFull ? 1:0)
.stroke(LinearGradient(gradient: gradientColor.gradient,
.stroke(LinearGradient(gradient: style.foregroundColor.first?.gradient ?? ColorGradient.orangeBright.gradient,
startPoint: .leading,
endPoint: .trailing),
style: StrokeStyle(lineWidth: 3, lineJoin: .round))
Expand All@@ -105,3 +105,15 @@ extension Line {
.drawingGroup()
}
}

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)
}
}
}

private let blackLineStyle = ChartStyle(backgroundColor: ColorGradient(.white), foregroundColor: ColorGradient(.black))
private let redLineStyle = ChartStyle(backgroundColor: .whiteBlack, foregroundColor: ColorGradient(.red))
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content
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
64 changes: 64 additions & 0 deletions .swiftlint.yml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
disabled_rules:
- explicit_acl
- trailing_whitespace
- force_cast
- unused_closure_parameter
- multiple_closures_with_trailing_closure
opt_in_rules:
- anyobject_protocol
- array_init
- attributes
- collection_alignment
- colon
- conditional_returns_on_newline
- convenience_type
- empty_count
- empty_string
- empty_collection_literal
- enum_case_associated_values_count
- function_default_parameter_at_end
- fatal_error_message
- file_name
- first_where
- modifier_order
- toggle_bool
- unused_private_declaration
- yoda_condition
excluded:
- Carthage
- Pods
- SwiftLint/Common/3rdPartyLib
identifier_name:
excluded:
- a
- b
- c
- i
- id
- t
- to
- x
- y
line_length:
warning: 150
error: 200
ignores_function_declarations: true
ignores_comments: true
ignores_urls: true
function_body_length:
warning: 300
error: 500
function_parameter_count:
warning: 6
error: 8
type_body_length:
warning: 300
error: 400
file_length:
warning: 500
error: 1200
ignore_comment_only_lines: true
cyclomatic_complexity:
warning: 15
error: 21
reporter: "xcode"
6 changes: 3 additions & 3 deletions Package.swift
Original file line numberDiff line numberDiff line change
Expand Up@@ -6,13 +6,13 @@ import PackageDescription
let package = Package(
name: "SwiftUICharts",
platforms: [
.iOS(.v13),.watchOS(.v6)
.iOS(.v13),.watchOS(.v6)
],
products: [
// Products define the executables and libraries produced by a package, and make them visible to other packages.
.library(
name: "SwiftUICharts",
targets: ["SwiftUICharts"]),
targets: ["SwiftUICharts"])
],
dependencies: [
// Dependencies declare other packages that this package depends on.
Expand All@@ -26,6 +26,6 @@ let package = Package(
dependencies: []),
.testTarget(
name: "SwiftUIChartsTests",
dependencies: ["SwiftUICharts"]),
dependencies: ["SwiftUICharts"])
]
)
16 changes: 16 additions & 0 deletions Sources/SwiftUICharts/Base/Extensions/CGRect+Extension.swift
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
//
// CGRect+Extension.swift
// SwiftUICharts
//
// Created by Nicolas Savoini on 2020-05-24.
//

import Foundation
import SwiftUI

extension CGRect {
// Return the coordinate for a rectangle center
public var mid: CGPoint {
return CGPoint(x: self.midX, y: self.midY)
}
}
12 changes: 6 additions & 6 deletions Sources/SwiftUICharts/Base/Extensions/Color+Extension.swift
Original file line numberDiff line numberDiff line change
Expand Up@@ -5,17 +5,17 @@ extension Color {
let hex = hexString.trimmingCharacters(in: CharacterSet.alphanumerics.inverted)
var int = UInt64()
Scanner(string: hex).scanHexInt64(&int)
let r, g, b: UInt64
let red, green, blue: UInt64
switch hex.count {
case 3: // RGB (12-bit)
(r, g, b) = ((int >> 8) * 17, (int >> 4 & 0xF) * 17, (int & 0xF) * 17)
(red, green, blue) = ((int >> 8) * 17, (int >> 4 & 0xF) * 17, (int & 0xF) * 17)
case 6: // RGB (24-bit)
(r, g, b) = (int >> 16, int >> 8 & 0xFF, int & 0xFF)
(red, green, blue) = (int >> 16, int >> 8 & 0xFF, int & 0xFF)
case 8: // ARGB (32-bit)
(r, g, b) = (int >> 16 & 0xFF, int >> 8 & 0xFF, int & 0xFF)
(red, green, blue) = (int >> 16 & 0xFF, int >> 8 & 0xFF, int & 0xFF)
default:
(r, g, b) = (0, 0, 0)
(red, green, blue) = (0, 0, 0)
}
self.init(red: Double(r) / 255, green: Double(g) / 255, blue: Double(b) / 255)
self.init(red: Double(red) / 255, green: Double(green) / 255, blue: Double(blue) / 255)
}
}
21 changes: 19 additions & 2 deletions Sources/SwiftUICharts/Base/Style/ChartStyle.swift
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,28 @@
import SwiftUI

public struct ChartStyle {
public let backgroundColor: Color
public let foregroundColor: ColorGradient

public let backgroundColor: ColorGradient
public let foregroundColor: [ColorGradient]

public init(backgroundColor: Color, foregroundColor: [ColorGradient]) {
self.backgroundColor = ColorGradient.init(backgroundColor)
self.foregroundColor = foregroundColor
}

public init(backgroundColor: Color, foregroundColor: ColorGradient) {
self.backgroundColor = ColorGradient.init(backgroundColor)
self.foregroundColor = [foregroundColor]
}

public init(backgroundColor: ColorGradient, foregroundColor: ColorGradient) {
self.backgroundColor = backgroundColor
self.foregroundColor = [foregroundColor]
}

public init(backgroundColor: ColorGradient, foregroundColor: [ColorGradient]) {
self.backgroundColor = backgroundColor
self.foregroundColor = foregroundColor
}

}
23 changes: 23 additions & 0 deletions Sources/SwiftUICharts/Base/Style/ColorGradient.swift
Original file line numberDiff line numberDiff line change
Expand Up@@ -4,6 +4,11 @@ public struct ColorGradient {
public let startColor: Color
public let endColor: Color

public init(_ color: Color) {
self.startColor = color
self.endColor = color
}

public init (_ startColor: Color, _ endColor: Color) {
self.startColor = startColor
self.endColor = endColor
Expand All@@ -13,3 +18,21 @@ public struct ColorGradient {
return Gradient(colors: [startColor, endColor])
}
}

extension ColorGradient {
/// Convenience method to return a LinearGradient from the ColorGradient
/// - Parameters:
/// - startPoint: starting point
/// - endPoint: ending point
/// - Returns: a Linear gradient
public func linearGradient(from startPoint: UnitPoint, to endPoint: UnitPoint) -> LinearGradient {
return LinearGradient(gradient: self.gradient, startPoint: startPoint, endPoint: endPoint)
}
}

extension ColorGradient {
public static let orangeBright = ColorGradient(ChartColors.orangeBright)
public static let redBlack = ColorGradient(.red, .black)
public static let greenRed = ColorGradient(.green, .red)
public static let whiteBlack = ColorGradient(.white, .black)
}
22 changes: 20 additions & 2 deletions Sources/SwiftUICharts/Charts/BarChart/BarChart.swift
Original file line numberDiff line numberDiff line change
Expand Up@@ -2,8 +2,26 @@ import SwiftUI

public struct BarChart: ChartType {
public func makeChart(configuration: Self.Configuration, style: Self.Style) -> some View {
BarChartRow(data: configuration.data, gradientColor: style.foregroundColor)
BarChartRow(data: configuration.data, style: style)
}

public init() {}
}

struct BarChart_Previews: PreviewProvider {
static var previews: some View {
Group {
Group {
BarChart().makeChart(
configuration: .init(data: [1, 2, 3, 5, 1]),
style: .init(backgroundColor: .white, foregroundColor: ColorGradient.redBlack))
}.environment(\.colorScheme, .light)

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

}
}
}
26 changes: 23 additions & 3 deletions Sources/SwiftUICharts/Charts/BarChart/BarChartCell.swift
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
import SwiftUI

public struct BarChartCell: View {
public struct BarChartCell: View {
@State var value: Double
@State var index: Int = 0
@State var width: Float
Expand All@@ -13,16 +13,36 @@ public struct BarChartCell : View {

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

public var body: some View {
ZStack {
RoundedRectangle(cornerRadius: 4)
.fill(LinearGradient(gradient: gradientColor.gradient, startPoint: .bottom, endPoint: .top))
.fill(gradientColor.linearGradient(from: .bottom, to: .top))
}
.frame(width: CGFloat(self.cellWidth))
.scaleEffect(CGSize(width: 1, height: self.scaleValue), anchor: .bottom)
.onAppear(){
.onAppear{
self.scaleValue = self.value
}
.animation(Animation.spring().delay(self.touchLocation < 0 ? Double(self.index) * 0.04 : 0))
}
}

struct BarChartCell_Previews: PreviewProvider {
static var previews: some View {
Group {
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()))
}

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()))
}.environment(\.colorScheme, .dark)
}

}
}
37 changes: 30 additions & 7 deletions Sources/SwiftUICharts/Charts/BarChart/BarChartRow.swift
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
import SwiftUI

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

enum Constant {
static let spacing: CGFloat = 16.0
}

var gradientColor: ColorGradient
var style: ChartStyle

var maxValue: Double {
data.max() ?? 0
}
Expand All@@ -17,14 +18,14 @@ public struct BarChartRow : 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) { i in
BarChartCell(value: self.normalizedValue(index: i),
index: i,
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.gradientColor,
gradientColor: self.style.foregroundColor.rotate(for: index),
touchLocation: self.$touchLocation)
.scaleEffect(self.getScaleSize(touchLocation: self.touchLocation, index: i), anchor: .bottom)
.scaleEffect(self.getScaleSize(touchLocation: self.touchLocation, index: index), anchor: .bottom)
.animation(.spring())

}
Expand DownExpand Up@@ -52,4 +53,26 @@ public struct BarChartRow : View {
}
return CGSize(width: 1, height: 1)
}

}

struct BarChartRow_Previews: PreviewProvider {
static var previews: some View {
Group {
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])
18 changes: 15 additions & 3 deletions Sources/SwiftUICharts/Charts/LineChart/Line.swift
Original file line numberDiff line numberDiff line change
Expand Up@@ -3,7 +3,7 @@ import SwiftUI
public struct Line: View {
@State var frame: CGRect = .zero
@State var data: [Double]
var gradientColor: ColorGradient
var style: ChartStyle

@State var showIndicator: Bool = false
@State var touchLocation: CGPoint = .zero
Expand DownExpand Up@@ -79,7 +79,7 @@ extension Line {

private func getBackgroundPathView() -> some View {
self.closedPath
.fill(LinearGradient(gradient: gradientColor.gradient, startPoint: .bottom, endPoint: .top))
.fill(style.backgroundColor.linearGradient(from: .bottom, to: .top))
.rotationEffect(.degrees(180), anchor: .center)
.rotation3DEffect(.degrees(180), axis: (x: 0, y: 1, z: 0))
.transition(.opacity)
Expand All@@ -89,7 +89,7 @@ extension Line {
private func getLinePathView() -> some View {
self.path
.trim(from: 0, to: self.showFull ? 1:0)
.stroke(LinearGradient(gradient: gradientColor.gradient,
.stroke(LinearGradient(gradient: style.foregroundColor.first?.gradient ?? ColorGradient.orangeBright.gradient,
startPoint: .leading,
endPoint: .trailing),
style: StrokeStyle(lineWidth: 3, lineJoin: .round))
Expand All@@ -105,3 +105,15 @@ extension Line {
.drawingGroup()
}
}

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)
}
}
}

private let blackLineStyle = ChartStyle(backgroundColor: ColorGradient(.white), foregroundColor: ColorGradient(.black))
private let redLineStyle = ChartStyle(backgroundColor: .whiteBlack, foregroundColor: ColorGradient(.red))
Loading