diff --git a/Cartfile.resolved b/Cartfile.resolved index 1672a76f44..24432d0bc4 100644 --- a/Cartfile.resolved +++ b/Cartfile.resolved @@ -1 +1 @@ -github "facebook/ios-snapshot-test-case" "ed4e6a6e81bfb69a5223156e6c3d389a416cf6e3" +github "facebook/ios-snapshot-test-case" "3efc829601128f7d9306e8e58db04d32594b62ce" diff --git a/ChartsDemo-iOS/Swift/DemoBaseViewController.swift b/ChartsDemo-iOS/Swift/DemoBaseViewController.swift index 27e911a7a2..e2e96f2bef 100644 --- a/ChartsDemo-iOS/Swift/DemoBaseViewController.swift +++ b/ChartsDemo-iOS/Swift/DemoBaseViewController.swift @@ -48,6 +48,8 @@ enum Option { case toggleYLabels case toggleRotate case toggleHighlightCircle + // VericalBarChart + case toggleBarGradient var label: String { switch self { @@ -89,6 +91,8 @@ enum Option { case .toggleYLabels: return "Toggle Y-Labels" case .toggleRotate: return "Toggle Rotate" case .toggleHighlightCircle: return "Toggle highlight circle" + // VericalBarChart + case .toggleBarGradient: return "Toggle Bar Gradient" } } } diff --git a/ChartsDemo-iOS/Swift/Demos/AnotherBarChartViewController.swift b/ChartsDemo-iOS/Swift/Demos/AnotherBarChartViewController.swift index 7d9a77f3b3..9691eda829 100644 --- a/ChartsDemo-iOS/Swift/Demos/AnotherBarChartViewController.swift +++ b/ChartsDemo-iOS/Swift/Demos/AnotherBarChartViewController.swift @@ -31,7 +31,8 @@ class AnotherBarChartViewController: DemoBaseViewController { .saveToGallery, .togglePinchZoom, .toggleData, - .toggleBarBorders] + .toggleBarBorders, + .toggleBarGradient] chartView.delegate = self @@ -87,7 +88,20 @@ class AnotherBarChartViewController: DemoBaseViewController { } override func optionTapped(_ option: Option) { - super.handleOption(option, forChartView: chartView) + switch option { + case .toggleBarGradient: + for set in chartView.data!.dataSets as! [BarChartDataSet] { + if set.barGradientColors == nil { + set.barGradientColors = ChartColorTemplates.gradients() + set.barGradientOrientation = .horizontal + } else { + set.barGradientColors = nil + } + } + chartView.notifyDataSetChanged() + default: + super.handleOption(option, forChartView: chartView) + } } // MARK: - Actions diff --git a/ChartsDemo-iOS/Swift/Demos/BarChartViewController.swift b/ChartsDemo-iOS/Swift/Demos/BarChartViewController.swift index 60be8856c1..1e41827fb0 100644 --- a/ChartsDemo-iOS/Swift/Demos/BarChartViewController.swift +++ b/ChartsDemo-iOS/Swift/Demos/BarChartViewController.swift @@ -31,7 +31,8 @@ class BarChartViewController: DemoBaseViewController { .saveToGallery, .togglePinchZoom, .toggleData, - .toggleBarBorders] + .toggleBarBorders, + .toggleBarGradient] self.setup(barLineChartView: chartView) @@ -139,7 +140,19 @@ class BarChartViewController: DemoBaseViewController { } override func optionTapped(_ option: Option) { - super.handleOption(option, forChartView: chartView) + switch option { + case .toggleBarGradient: + for set in chartView.data!.dataSets as! [BarChartDataSet] { + if set.barGradientColors == nil { + set.barGradientColors = ChartColorTemplates.gradients() + } else { + set.barGradientColors = nil + } + } + chartView.notifyDataSetChanged() + default: + super.handleOption(option, forChartView: chartView) + } } // MARK: - Actions diff --git a/ChartsDemo-iOS/Swift/Demos/MultipleBarChartViewController.swift b/ChartsDemo-iOS/Swift/Demos/MultipleBarChartViewController.swift index 35cbacc2eb..72cea693d7 100644 --- a/ChartsDemo-iOS/Swift/Demos/MultipleBarChartViewController.swift +++ b/ChartsDemo-iOS/Swift/Demos/MultipleBarChartViewController.swift @@ -32,7 +32,8 @@ class MultipleBarChartViewController: DemoBaseViewController { .togglePinchZoom, .toggleAutoScaleMinMax, .toggleData, - .toggleBarBorders] + .toggleBarBorders, + .toggleBarGradient] chartView.delegate = self @@ -138,7 +139,19 @@ class MultipleBarChartViewController: DemoBaseViewController { } override func optionTapped(_ option: Option) { - super.handleOption(option, forChartView: chartView) + switch option { + case .toggleBarGradient: + for set in chartView.data!.dataSets as! [BarChartDataSet] { + if set.barGradientColors == nil { + set.barGradientColors = ChartColorTemplates.gradients() + } else { + set.barGradientColors = nil + } + } + chartView.notifyDataSetChanged() + default: + super.handleOption(option, forChartView: chartView) + } } // MARK: - Actions diff --git a/ChartsDemo-iOS/Swift/Demos/PositiveNegativeBarChartViewController.swift b/ChartsDemo-iOS/Swift/Demos/PositiveNegativeBarChartViewController.swift index 9dae355783..705f7fea15 100644 --- a/ChartsDemo-iOS/Swift/Demos/PositiveNegativeBarChartViewController.swift +++ b/ChartsDemo-iOS/Swift/Demos/PositiveNegativeBarChartViewController.swift @@ -33,7 +33,8 @@ class PositiveNegativeBarChartViewController: DemoBaseViewController { .togglePinchZoom, .toggleAutoScaleMinMax, .toggleData, - .toggleBarBorders] + .toggleBarBorders, + .toggleBarGradient] self.setup(barLineChartView: chartView) @@ -109,7 +110,19 @@ class PositiveNegativeBarChartViewController: DemoBaseViewController { } override func optionTapped(_ option: Option) { - super.handleOption(option, forChartView: chartView) + switch option { + case .toggleBarGradient: + for set in chartView.data!.dataSets as! [BarChartDataSet] { + if set.barGradientColors == nil { + set.barGradientColors = ChartColorTemplates.gradients() + } else { + set.barGradientColors = nil + } + } + chartView.notifyDataSetChanged() + default: + super.handleOption(option, forChartView: chartView) + } } } diff --git a/ChartsDemo-iOS/Swift/Demos/StackedBarChartViewController.swift b/ChartsDemo-iOS/Swift/Demos/StackedBarChartViewController.swift index 3572958a17..92b442ac3f 100644 --- a/ChartsDemo-iOS/Swift/Demos/StackedBarChartViewController.swift +++ b/ChartsDemo-iOS/Swift/Demos/StackedBarChartViewController.swift @@ -41,7 +41,8 @@ class StackedBarChartViewController: DemoBaseViewController { .togglePinchZoom, .toggleAutoScaleMinMax, .toggleData, - .toggleBarBorders] + .toggleBarBorders, + .toggleBarGradient] chartView.delegate = self @@ -113,7 +114,19 @@ class StackedBarChartViewController: DemoBaseViewController { } override func optionTapped(_ option: Option) { - super.handleOption(option, forChartView: chartView) + switch option { + case .toggleBarGradient: + for set in chartView.data!.dataSets as! [BarChartDataSet] { + if set.barGradientColors == nil { + set.barGradientColors = ChartColorTemplates.gradients() + } else { + set.barGradientColors = nil + } + } + chartView.notifyDataSetChanged() + default: + super.handleOption(option, forChartView: chartView) + } } @IBAction func slidersValueChanged(_ sender: Any?) { diff --git a/Source/Charts/Data/Implementations/Standard/BarChartDataSet.swift b/Source/Charts/Data/Implementations/Standard/BarChartDataSet.swift index cf86d883ee..931ee56568 100644 --- a/Source/Charts/Data/Implementations/Standard/BarChartDataSet.swift +++ b/Source/Charts/Data/Implementations/Standard/BarChartDataSet.swift @@ -12,9 +12,16 @@ import Foundation import CoreGraphics +@objc +public enum BarGradientOrientation: Int +{ + case vertical + case horizontal +} open class BarChartDataSet: BarLineScatterCandleBubbleChartDataSet, BarChartDataSetProtocol { + private func initialize() { self.highlightColor = NSUIColor.black @@ -117,6 +124,19 @@ open class BarChartDataSet: BarLineScatterCandleBubbleChartDataSet, BarChartData /// the alpha value (transparency) that is used for drawing the highlight indicator bar. min = 0.0 (fully transparent), max = 1.0 (fully opaque) open var highlightAlpha = CGFloat(120.0 / 255.0) + /// array of gradient colors [[color1, color2], [color3, color4]] + open var barGradientColors: [[NSUIColor]]? + + open var barGradientOrientation: BarGradientOrientation = .vertical + + /// - returns: The gradient colors at the given index of the DataSet's gradient color array. + /// This prevents out-of-bounds by performing a modulus on the gradient color index, so colours will repeat themselves. + open func barGradientColor(at index: Int) -> [NSUIColor]? + { + guard let gradientColors = barGradientColors else { return nil } + return gradientColors[index % gradientColors.count] + } + // MARK: - NSCopying open override func copyWithZone(_ zone: NSZone?) -> AnyObject diff --git a/Source/Charts/Data/Interfaces/BarChartDataSetProtocol.swift b/Source/Charts/Data/Interfaces/BarChartDataSetProtocol.swift index 3e64d24f49..79786dc3e8 100644 --- a/Source/Charts/Data/Interfaces/BarChartDataSetProtocol.swift +++ b/Source/Charts/Data/Interfaces/BarChartDataSetProtocol.swift @@ -39,4 +39,13 @@ public protocol BarChartDataSetProtocol: BarLineScatterCandleBubbleChartDataSetP /// array of labels used to describe the different values of the stacked bars var stackLabels: [String] { get set } + + /// array of gradient colors [[color1, color2], [color3, color4]] + var barGradientColors: [[NSUIColor]]? { get set } + + var barGradientOrientation: BarGradientOrientation { get set } + + /// - returns: The gradient colors at the given index of the DataSet's gradient color array. + /// This prevents out-of-bounds by performing a modulus on the gradient color index, so colours will repeat themselves. + func barGradientColor(at index: Int) -> [NSUIColor]? } diff --git a/Source/Charts/Renderers/BarChartRenderer.swift b/Source/Charts/Renderers/BarChartRenderer.swift index de94e87d42..86ac2801d9 100644 --- a/Source/Charts/Renderers/BarChartRenderer.swift +++ b/Source/Charts/Renderers/BarChartRenderer.swift @@ -318,16 +318,11 @@ open class BarChartRenderer: BarLineScatterCandleBubbleRenderer guard viewPortHandler.isInBoundsLeft(barRect.origin.x + barRect.size.width) else { continue } guard viewPortHandler.isInBoundsRight(barRect.origin.x) else { break } - if !isSingleColor - { - // Set the color for the currently drawn value. If the index is out of bounds, reuse colors. - context.setFillColor(dataSet.color(atIndex: j).cgColor) - } - - context.fill(barRect) + drawBar(context: context, dataSet: dataSet, index: j, barRect: barRect) if drawBorder { + context.saveGState() context.setStrokeColor(borderColor.cgColor) context.setLineWidth(borderWidth) context.stroke(barRect) @@ -350,6 +345,50 @@ open class BarChartRenderer: BarLineScatterCandleBubbleRenderer } } + open func drawBar(context: CGContext, dataSet: BarChartDataSetProtocol, index: Int, barRect: CGRect) + { + context.saveGState() + defer { context.restoreGState() } + + if let gradientColor = dataSet.barGradientColor(at: index) + { + drawGradient(context: context, barRect: barRect, gradientColors: gradientColor, orientation: dataSet.barGradientOrientation) + } + else + { + // Set the color for the currently drawn value. If the index is out of bounds, reuse colors. + let fillColor = dataSet.color(atIndex: index).cgColor + context.setFillColor(fillColor) + context.fill(barRect) + } + } + + open func drawGradient(context: CGContext, barRect: CGRect, gradientColors: Array, orientation: BarGradientOrientation) + { + let cgColors = gradientColors.map{ $0.cgColor } as CFArray + let gradient = CGGradient(colorsSpace: CGColorSpaceCreateDeviceRGB(), colors: cgColors, locations: nil) + + let startPoint: CGPoint + let endPoint: CGPoint + + switch orientation + { + case .vertical: + startPoint = CGPoint(x: barRect.midX, y: barRect.maxY) + endPoint = CGPoint(x: barRect.midX, y: barRect.minY) + + case .horizontal: + startPoint = CGPoint(x: barRect.minX, y: barRect.midY) + endPoint = CGPoint(x: barRect.maxX, y: barRect.midY) + } + + let path = CGPath(rect: barRect, transform: nil) + + context.addPath(path) + context.clip() + context.drawLinearGradient(gradient!, start: startPoint, end: endPoint, options: []) + } + open func prepareBarHighlight( x: Double, y1: Double, diff --git a/Source/Charts/Renderers/HorizontalBarChartRenderer.swift b/Source/Charts/Renderers/HorizontalBarChartRenderer.swift index d992f49da5..2d242cb08e 100644 --- a/Source/Charts/Renderers/HorizontalBarChartRenderer.swift +++ b/Source/Charts/Renderers/HorizontalBarChartRenderer.swift @@ -259,6 +259,8 @@ open class HorizontalBarChartRenderer: BarChartRenderer continue } + drawBar(context: context, dataSet: dataSet, index: j, barRect: barRect) + if !isSingleColor { // Set the color for the currently drawn value. If the index is out of bounds, reuse colors. diff --git a/Source/Charts/Utils/ChartColorTemplates.swift b/Source/Charts/Utils/ChartColorTemplates.swift index 461ef8ab3d..fdcb6c50ac 100644 --- a/Source/Charts/Utils/ChartColorTemplates.swift +++ b/Source/Charts/Utils/ChartColorTemplates.swift @@ -84,6 +84,14 @@ open class ChartColorTemplates: NSObject ] } + @objc open class func gradients () -> [[NSUIColor]] + { + let palette = joyful() + return [[palette[0], palette[1]], + [palette[2], palette[3]], + [palette[4], palette[0]]] + } + @objc open class func colorFromString(_ colorString: String) -> NSUIColor { let leftParenCharset: CharacterSet = CharacterSet(charactersIn: "( ") diff --git a/Source/Charts/Utils/Platform.swift b/Source/Charts/Utils/Platform.swift index b1796919a7..eb3c448a25 100644 --- a/Source/Charts/Utils/Platform.swift +++ b/Source/Charts/Utils/Platform.swift @@ -661,5 +661,5 @@ public typealias NSUIGestureRecognizerState = UIGestureRecognizer.State { return NSUIScreen.main } - + #endif