Skip to content
3 changes: 3 additions & 0 deletions Classes/Drawing/BarDrawingLayer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ internal class BarDrawingLayer: ScrollableGraphViewDrawingLayer {
private var barWidth: CGFloat = 4
private var shouldRoundCorners = false

override init(layer: Any) {
super.init(layer: layer)
}
init(frame: CGRect, barWidth: CGFloat, barColor: UIColor, barLineWidth: CGFloat, barLineColor: UIColor, shouldRoundCorners: Bool) {
super.init(viewportWidth: frame.size.width, viewportHeight: frame.size.height)

Expand Down
4 changes: 4 additions & 0 deletions Classes/Drawing/DotDrawingLayer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ internal class DotDrawingLayer: ScrollableGraphViewDrawingLayer {

private var customDataPointPath: ((_ centre: CGPoint) -> UIBezierPath)?

override init(layer: Any) {
super.init(layer: layer)
}

init(frame: CGRect, fillColor: UIColor, dataPointType: ScrollableGraphViewDataPointType, dataPointSize: CGFloat, customDataPointPath: ((_ centre: CGPoint) -> UIBezierPath)? = nil) {

self.dataPointType = dataPointType
Expand Down
5 changes: 4 additions & 1 deletion Classes/Drawing/FillDrawingLayer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,11 @@ internal class FillDrawingLayer : ScrollableGraphViewDrawingLayer {

// Fills are only used with lineplots and we need
// to know what the line looks like.
private var lineDrawingLayer: LineDrawingLayer
private var lineDrawingLayer: LineDrawingLayer!

override init(layer: Any) {
super.init(layer: layer)
}
init(frame: CGRect, fillColor: UIColor, lineDrawingLayer: LineDrawingLayer) {

self.lineDrawingLayer = lineDrawingLayer
Expand Down
8 changes: 7 additions & 1 deletion Classes/Drawing/GradientDrawingLayer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ internal class GradientDrawingLayer : ScrollableGraphViewDrawingLayer {

// Gradient fills are only used with lineplots and we need
// to know what the line looks like.
private var lineDrawingLayer: LineDrawingLayer
private var lineDrawingLayer: LineDrawingLayer!

lazy private var gradientMask: CAShapeLayer = ({
let mask = CAShapeLayer()
Expand All @@ -34,6 +34,12 @@ internal class GradientDrawingLayer : ScrollableGraphViewDrawingLayer {
addMaskLayer()
self.setNeedsDisplay()
}
override init(layer: Any) {
self.startColor = UIColor.black
self.endColor = UIColor.black
self.gradientType = .linear
super.init(layer: layer)
}

required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
Expand Down
8 changes: 7 additions & 1 deletion Classes/Drawing/LineDrawingLayer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,13 @@ internal class LineDrawingLayer : ScrollableGraphViewDrawingLayer {
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

override init(layer: Any) {
// Default values
lineStyle = .smooth
shouldFill = false
lineCurviness = 1.0
super.init(layer: layer)
}
internal func createLinePath() -> UIBezierPath {

guard let owner = owner else {
Expand Down
43 changes: 25 additions & 18 deletions Classes/Drawing/ReferenceLineDrawingView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -93,9 +93,9 @@ internal class ReferenceLineDrawingView : UIView {

switch(settings.positionType) {
case .relative:
createReferenceLines(in: initialRect, atRelativePositions: self.settings.relativePositions, forPath: referenceLinePath)
createReferenceLines(in: initialRect, relativeLines: self.settings.relativeLines, forPath: referenceLinePath)
case .absolute:
createReferenceLines(in: initialRect, atAbsolutePositions: self.settings.absolutePositions, forPath: referenceLinePath)
createReferenceLines(in: initialRect, absoluteLines: self.settings.absoluteLines, forPath: referenceLinePath)
}

return referenceLinePath
Expand All @@ -110,54 +110,61 @@ internal class ReferenceLineDrawingView : UIView {
return numberFormatter
}

private func createReferenceLines(in rect: CGRect, atRelativePositions relativePositions: [Double], forPath path: UIBezierPath) {
private func createReferenceLines(in rect: CGRect, relativeLines: [ReferenceLine], forPath path: UIBezierPath) {

let height = rect.size.height
var relativePositions = relativePositions
var relativeLines = relativeLines

// If we are including the min and max already need to make sure we don't redraw them.
if(self.settings.includeMinMax) {
relativePositions = relativePositions.filter({ (x:Double) -> Bool in
return (x != 0 && x != 1)
relativeLines = relativeLines.filter({ (x: ReferenceLine) -> Bool in
return (x.position != 0 && x.position != 1)
})
}

for relativePosition in relativePositions {
for relativeLine in relativeLines {

let yPosition = height * CGFloat(1 - relativePosition)
let yPosition = height * CGFloat(1 - relativeLine.position)

let lineStart = CGPoint(x: 0, y: rect.origin.y + yPosition)
let lineEnd = CGPoint(x: lineStart.x + lineWidth, y: lineStart.y)

createReferenceLineFrom(from: lineStart, to: lineEnd, in: path)
createReferenceLineFrom(from: lineStart, to: lineEnd, in: path, withLabel: relativeLine.label)
}
}

private func createReferenceLines(in rect: CGRect, atAbsolutePositions absolutePositions: [Double], forPath path: UIBezierPath) {
private func createReferenceLines(in rect: CGRect, absoluteLines: [ReferenceLine], forPath path: UIBezierPath) {

for absolutePosition in absolutePositions {
for absoluteLine in absoluteLines {

let yPosition = calculateYPositionForYAxisValue(value: absolutePosition)
let yPosition = calculateYPositionForYAxisValue(value: absoluteLine.position)

// don't need to add rect.origin.y to yPosition like we do for relativePositions,
// don't need to add rect.origin.y to yPosition like we do for relativeLines,
// as we calculate the position for the y axis value in the previous line,
// this already takes into account margins, etc.
let lineStart = CGPoint(x: 0, y: yPosition)
let lineEnd = CGPoint(x: lineStart.x + lineWidth, y: lineStart.y)

createReferenceLineFrom(from: lineStart, to: lineEnd, in: path)
createReferenceLineFrom(from: lineStart, to: lineEnd, in: path, withLabel: absoluteLine.label)
}
}

private func createReferenceLineFrom(from lineStart: CGPoint, to lineEnd: CGPoint, in path: UIBezierPath) {
private func createReferenceLineFrom(from lineStart: CGPoint, to lineEnd: CGPoint, in path: UIBezierPath, withLabel label: String?) {
if(self.settings.shouldAddLabelsToIntermediateReferenceLines) {

let value = calculateYAxisValue(for: lineStart)
let numberFormatter = referenceNumberFormatter()
var valueString = numberFormatter.string(from: value as NSNumber)!

if(self.settings.shouldAddUnitsToIntermediateReferenceLineLabels) {
valueString += " \(units)"
var valueString: String

if let label = label {
valueString = label
} else {
valueString = numberFormatter.string(from: value as NSNumber)!

if(self.settings.shouldAddUnitsToIntermediateReferenceLineLabels) {
valueString += " \(units)"
}
}

addLine(withTag: valueString, from: lineStart, to: lineEnd, in: path)
Expand Down
3 changes: 3 additions & 0 deletions Classes/Drawing/ScrollableGraphViewDrawingLayer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ internal class ScrollableGraphViewDrawingLayer : CAShapeLayer {

setup()
}
override init(layer: Any) {
super.init()
}

required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
Expand Down
2 changes: 1 addition & 1 deletion Classes/Plots/Plot.swift
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ open class Plot {
}

private func dequeue(animation: GraphPointAnimation) {
if let index = currentAnimations.index(of: animation) {
if let index = currentAnimations.firstIndex(of: animation) {
currentAnimations.remove(at: index)
}

Expand Down
2 changes: 1 addition & 1 deletion Classes/Reference/LabelPool.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ internal class LabelPool {
else {
label = UILabel()
labels.append(label)
let newLabelIndex = labels.index(of: label)!
let newLabelIndex = labels.firstIndex(of: label)!
relations[pointIndex] = newLabelIndex
}

Expand Down
23 changes: 19 additions & 4 deletions Classes/Reference/ReferenceLines.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,17 @@ open class ReferenceLines {
open var referenceLinePosition = ScrollableGraphViewReferenceLinePosition.left

@IBInspectable open var positionType = ReferenceLinePositioningType.relative
@IBInspectable open var relativePositions: [Double] = [0.25, 0.5, 0.75]
@IBInspectable open var absolutePositions: [Double] = [25, 50, 75]
@IBInspectable open var includeMinMax: Bool = true

open var relativeLines: [ReferenceLine] = [ReferenceLine(position: 0, label: "start"),
ReferenceLine(position: 0.25, label: "a"),
ReferenceLine(position: 0.5, label: "b"),
ReferenceLine(position: 0.75, label: "c"),
ReferenceLine(position: 1, label: "end")]
open var absoluteLines: [ReferenceLine] = [ReferenceLine(position: 25),
ReferenceLine(position: 50),
ReferenceLine(position: 75)]

@IBInspectable open var includeMinMax: Bool = false

/// Whether or not to add labels to the intermediate reference lines.
@IBInspectable open var shouldAddLabelsToIntermediateReferenceLines: Bool = true
Expand Down Expand Up @@ -72,7 +80,14 @@ open class ReferenceLines {
// Need this for external frameworks.
}
}

open class ReferenceLine {
public let position: Double
public let label: String?
public init(position: Double, label: String? = nil) {
self.position = position
self.label = label
}
}

@objc public enum ScrollableGraphViewReferenceLinePosition : Int {
case left
Expand Down
2 changes: 1 addition & 1 deletion Classes/ScrollableGraphView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -981,7 +981,7 @@ fileprivate class SGVQueue<T> {

// We have to be our own data source for interface builder.
#if TARGET_INTERFACE_BUILDER
public extension ScrollableGraphView : ScrollableGraphViewDataSource {
extension ScrollableGraphView : ScrollableGraphViewDataSource {

var numberOfDisplayItems: Int {
get {
Expand Down
17 changes: 11 additions & 6 deletions GraphView/GraphView.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -287,13 +287,16 @@
TargetAttributes = {
2918399D1C72E6A400753A45 = {
CreatedOnToolsVersion = 7.2.1;
LastSwiftMigration = 1000;
LastSwiftMigration = 1130;
};
E10847832129DC60009A9586 = {
LastSwiftMigration = 1130;
};
};
};
buildConfigurationList = 291839991C72E6A400753A45 /* Build configuration list for PBXProject "GraphView" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
Expand Down Expand Up @@ -512,7 +515,7 @@
PRODUCT_BUNDLE_IDENTIFIER = com.ios.GraphViewCode;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE = "";
SWIFT_VERSION = 4.2;
SWIFT_VERSION = 5.0;
};
name = Debug;
};
Expand All @@ -529,7 +532,7 @@
PRODUCT_BUNDLE_IDENTIFIER = com.ios.GraphViewCode;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE = "";
SWIFT_VERSION = 4.2;
SWIFT_VERSION = 5.0;
};
name = Release;
};
Expand All @@ -546,7 +549,8 @@
PRODUCT_BUNDLE_IDENTIFIER = com.ios.GraphViewIB;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE = "";
SWIFT_VERSION = 4.2;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
Expand All @@ -563,7 +567,8 @@
PRODUCT_BUNDLE_IDENTIFIER = com.ios.GraphViewIB;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE = "";
SWIFT_VERSION = 4.2;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Release;
};
Expand Down
12 changes: 10 additions & 2 deletions GraphView/GraphViewCode/Examples.swift
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,12 @@ class Examples : ScrollableGraphViewDataSource {
referenceLines.referenceLineLabelFont = UIFont.boldSystemFont(ofSize: 8)
referenceLines.referenceLineColor = UIColor.white.withAlphaComponent(0.2)
referenceLines.referenceLineLabelColor = UIColor.white
referenceLines.relativePositions = [0, 0.2, 0.4, 0.6, 0.8, 1]
referenceLines.relativeLines = [ReferenceLine(position: 0),
ReferenceLine(position: 0.2),
ReferenceLine(position: 0.4),
ReferenceLine(position: 0.6),
ReferenceLine(position: 0.8),
ReferenceLine(position: 1)]

referenceLines.dataPointLabelColor = UIColor.white.withAlphaComponent(1)

Expand Down Expand Up @@ -257,7 +262,10 @@ class Examples : ScrollableGraphViewDataSource {

referenceLines.positionType = .absolute
// Reference lines will be shown at these values on the y-axis.
referenceLines.absolutePositions = [10, 20, 25, 30]
referenceLines.absoluteLines = [ReferenceLine(position: 10),
ReferenceLine(position: 20),
ReferenceLine(position: 25),
ReferenceLine(position: 30)]
referenceLines.includeMinMax = false

referenceLines.dataPointLabelColor = UIColor.white.withAlphaComponent(0.5)
Expand Down
11 changes: 11 additions & 0 deletions Package.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// swift-tools-version:5.0
//
import PackageDescription

let package = Package(name: "ScrollableGraphView",
platforms: [.iOS(.v8)],
products: [.library(name: "ScrollableGraphView",
targets: ["ScrollableGraphView"])],
targets: [.target(name: "ScrollableGraphView",
path: "Classes")],
swiftLanguageVersions: [.v5])
12 changes: 10 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -364,7 +364,10 @@ referenceLines.referenceLineLabelColor = UIColor.white

referenceLines.positionType = .absolute
// Reference lines will be shown at these values on the y-axis.
referenceLines.absolutePositions = [10, 20, 25, 30]
referenceLines.absoluteLines = [ReferenceLine(position: 10),
ReferenceLine(position: 20),
ReferenceLine(position: 25),
ReferenceLine(position: 30)]
referenceLines.includeMinMax = false

referenceLines.dataPointLabelColor = UIColor.white.withAlphaComponent(0.5)
Expand Down Expand Up @@ -554,7 +557,12 @@ let referenceLines = ReferenceLines()
referenceLines.referenceLineLabelFont = UIFont.boldSystemFont(ofSize: 8)
referenceLines.referenceLineColor = UIColor.white.withAlphaComponent(0.2)
referenceLines.referenceLineLabelColor = UIColor.white
referenceLines.relativePositions = [0, 0.2, 0.4, 0.6, 0.8, 1]
referenceLines.relativeLines = [ReferenceLine(position: 0),
ReferenceLine(position: 0.2),
ReferenceLine(position: 0.4),
ReferenceLine(position: 0.6),
ReferenceLine(position: 0.8),
ReferenceLine(position: 1)]

referenceLines.dataPointLabelColor = UIColor.white.withAlphaComponent(1)

Expand Down