diff --git a/Charts/Classes/Data/Implementations/Standard/LineChartDataSet.swift b/Charts/Classes/Data/Implementations/Standard/LineChartDataSet.swift index 6886428701..05b7938040 100644 --- a/Charts/Classes/Data/Implementations/Standard/LineChartDataSet.swift +++ b/Charts/Classes/Data/Implementations/Standard/LineChartDataSet.swift @@ -67,8 +67,14 @@ public class LineChartDataSet: LineRadarChartDataSet, ILineChartDataSet /// If true, cubic lines are drawn instead of linear public var drawCubicEnabled = false + /// If true, stepped lines are drawn instead of linear + public var drawSteppedEnabled = false + /// - returns: true if drawing cubic lines is enabled, false if not. public var isDrawCubicEnabled: Bool { return drawCubicEnabled } + + /// - returns: true if drawing stepped lines is enabled, false if not. + public var isDrawSteppedEnabled: Bool { return drawSteppedEnabled } /// The radius of the drawn circles. public var circleRadius = CGFloat(8.0) @@ -160,6 +166,7 @@ public class LineChartDataSet: LineRadarChartDataSet, ILineChartDataSet copy.lineDashLengths = lineDashLengths copy.drawCirclesEnabled = drawCirclesEnabled copy.drawCubicEnabled = drawCubicEnabled + copy.drawSteppedEnabled = drawSteppedEnabled return copy } } diff --git a/Charts/Classes/Data/Interfaces/ILineChartDataSet.swift b/Charts/Classes/Data/Interfaces/ILineChartDataSet.swift index f6fb8312f1..4bb237f064 100644 --- a/Charts/Classes/Data/Interfaces/ILineChartDataSet.swift +++ b/Charts/Classes/Data/Interfaces/ILineChartDataSet.swift @@ -28,9 +28,15 @@ public protocol ILineChartDataSet: ILineRadarChartDataSet /// If true, cubic lines are drawn instead of linear var drawCubicEnabled: Bool { get set } + /// If true, stepped lines are drawn instead of linear + var drawSteppedEnabled: Bool { get set } + /// - returns: true if drawing cubic lines is enabled, false if not. var isDrawCubicEnabled: Bool { get } + /// - returns: true if drawing stepped lines is enabled, false if not. + var isDrawSteppedEnabled: Bool { get } + /// The radius of the drawn circles. var circleRadius: CGFloat { get set } diff --git a/Charts/Classes/Renderers/LineChartRenderer.swift b/Charts/Classes/Renderers/LineChartRenderer.swift index 2d685e2511..2884a03ab1 100644 --- a/Charts/Classes/Renderers/LineChartRenderer.swift +++ b/Charts/Classes/Renderers/LineChartRenderer.swift @@ -245,6 +245,7 @@ public class LineChartRenderer: LineRadarChartRenderer let valueToPixelMatrix = trans.valueToPixelMatrix let entryCount = dataSet.entryCount + let pointsPerEntryPair = dataSet.isDrawSteppedEnabled ? 4 : 2 let phaseX = animator.phaseX let phaseY = animator.phaseY @@ -263,9 +264,9 @@ public class LineChartRenderer: LineRadarChartRenderer // more than 1 color if (dataSet.colors.count > 1) { - if (_lineSegments.count != 2) + if (_lineSegments.count != pointsPerEntryPair) { - _lineSegments = [CGPoint](count: 2, repeatedValue: CGPoint()) + _lineSegments = [CGPoint](count: pointsPerEntryPair, repeatedValue: CGPoint()) } for (var j = minx, count = Int(ceil(CGFloat(maxx - minx) * phaseX + CGFloat(minx))); j < count; j++) @@ -281,21 +282,28 @@ public class LineChartRenderer: LineRadarChartRenderer _lineSegments[0].x = CGFloat(e.xIndex) _lineSegments[0].y = CGFloat(e.value) * phaseY - _lineSegments[0] = CGPointApplyAffineTransform(_lineSegments[0], valueToPixelMatrix) if (j + 1 < count) { e = dataSet.entryForIndex(j + 1) if e == nil { break } - _lineSegments[1].x = CGFloat(e.xIndex) - _lineSegments[1].y = CGFloat(e.value) * phaseY - _lineSegments[1] = CGPointApplyAffineTransform(_lineSegments[1], valueToPixelMatrix) + if dataSet.isDrawSteppedEnabled { + _lineSegments[1] = CGPoint(x: CGFloat(e.xIndex), y: _lineSegments[0].y) + _lineSegments[2] = _lineSegments[1] + _lineSegments[3] = CGPoint(x: CGFloat(e.xIndex), y: CGFloat(e.value) * phaseY) + } else { + _lineSegments[1] = CGPoint(x: CGFloat(e.xIndex), y: CGFloat(e.value) * phaseY) + } } else { _lineSegments[1] = _lineSegments[0] } + + for i in 0..<_lineSegments.count { + _lineSegments[i] = CGPointApplyAffineTransform(_lineSegments[i], valueToPixelMatrix) + } if (!viewPortHandler.isInBoundsRight(_lineSegments[0].x)) { @@ -312,7 +320,7 @@ public class LineChartRenderer: LineRadarChartRenderer // get the color that is set for this line-segment CGContextSetStrokeColorWithColor(context, dataSet.colorAt(j).CGColor) - CGContextStrokeLineSegments(context, _lineSegments, 2) + CGContextStrokeLineSegments(context, _lineSegments, pointsPerEntryPair) } } else @@ -321,9 +329,9 @@ public class LineChartRenderer: LineRadarChartRenderer var e1: ChartDataEntry! var e2: ChartDataEntry! - if (_lineSegments.count != max((entryCount - 1) * 2, 2)) + if (_lineSegments.count != max((entryCount - 1) * pointsPerEntryPair, pointsPerEntryPair)) { - _lineSegments = [CGPoint](count: max((entryCount - 1) * 2, 2), repeatedValue: CGPoint()) + _lineSegments = [CGPoint](count: max((entryCount - 1) * pointsPerEntryPair, pointsPerEntryPair), repeatedValue: CGPoint()) } e1 = dataSet.entryForIndex(minx) @@ -340,10 +348,14 @@ public class LineChartRenderer: LineRadarChartRenderer if e1 == nil || e2 == nil { continue } _lineSegments[j++] = CGPointApplyAffineTransform(CGPoint(x: CGFloat(e1.xIndex), y: CGFloat(e1.value) * phaseY), valueToPixelMatrix) + if dataSet.isDrawSteppedEnabled { + _lineSegments[j++] = CGPointApplyAffineTransform(CGPoint(x: CGFloat(e2.xIndex), y: CGFloat(e1.value) * phaseY), valueToPixelMatrix) + _lineSegments[j++] = CGPointApplyAffineTransform(CGPoint(x: CGFloat(e2.xIndex), y: CGFloat(e1.value) * phaseY), valueToPixelMatrix) + } _lineSegments[j++] = CGPointApplyAffineTransform(CGPoint(x: CGFloat(e2.xIndex), y: CGFloat(e2.value) * phaseY), valueToPixelMatrix) } - let size = max((count - minx - 1) * 2, 2) + let size = max((count - minx - 1) * pointsPerEntryPair, pointsPerEntryPair) CGContextSetStrokeColorWithColor(context, dataSet.colorAt(0).CGColor) CGContextStrokeLineSegments(context, _lineSegments, size) } @@ -400,6 +412,10 @@ public class LineChartRenderer: LineRadarChartRenderer for (var x = from + 1, count = Int(ceil(CGFloat(to - from) * phaseX + CGFloat(from))); x < count; x++) { guard let e = dataSet.entryForIndex(x) else { continue } + if dataSet.isDrawSteppedEnabled { + guard let ePrev = dataSet.entryForIndex(x-1) else { continue } + CGPathAddLineToPoint(filled, &matrix, CGFloat(e.xIndex), CGFloat(ePrev.value) * phaseY) + } CGPathAddLineToPoint(filled, &matrix, CGFloat(e.xIndex), CGFloat(e.value) * phaseY) } diff --git a/ChartsDemo/Classes/Demos/LineChart1ViewController.m b/ChartsDemo/Classes/Demos/LineChart1ViewController.m index 911c1a18b8..dd75095490 100644 --- a/ChartsDemo/Classes/Demos/LineChart1ViewController.m +++ b/ChartsDemo/Classes/Demos/LineChart1ViewController.m @@ -37,6 +37,7 @@ - (void)viewDidLoad @{@"key": @"toggleFilled", @"label": @"Toggle Filled"}, @{@"key": @"toggleCircles", @"label": @"Toggle Circles"}, @{@"key": @"toggleCubic", @"label": @"Toggle Cubic"}, + @{@"key": @"toggleStepped", @"label": @"Toggle Stepped"}, @{@"key": @"toggleHighlight", @"label": @"Toggle Highlight"}, @{@"key": @"animateX", @"label": @"Animate X"}, @{@"key": @"animateY", @"label": @"Animate Y"}, @@ -201,6 +202,16 @@ - (void)optionTapped:(NSString *)key [_chartView setNeedsDisplay]; } + + if ([key isEqualToString:@"toggleStepped"]) + { + for (id set in _chartView.data.dataSets) + { + set.drawSteppedEnabled = !set.isDrawSteppedEnabled; + } + + [_chartView setNeedsDisplay]; + } if ([key isEqualToString:@"toggleHighlight"]) { diff --git a/ChartsDemo/Classes/Demos/LineChart2ViewController.m b/ChartsDemo/Classes/Demos/LineChart2ViewController.m index 8cf162319d..3ca56add33 100644 --- a/ChartsDemo/Classes/Demos/LineChart2ViewController.m +++ b/ChartsDemo/Classes/Demos/LineChart2ViewController.m @@ -37,6 +37,7 @@ - (void)viewDidLoad @{@"key": @"toggleFilled", @"label": @"Toggle Filled"}, @{@"key": @"toggleCircles", @"label": @"Toggle Circles"}, @{@"key": @"toggleCubic", @"label": @"Toggle Cubic"}, + @{@"key": @"toggleStepped", @"label": @"Toggle Stepped"}, @{@"key": @"toggleHighlight", @"label": @"Toggle Highlight"}, @{@"key": @"animateX", @"label": @"Animate X"}, @{@"key": @"animateY", @"label": @"Animate Y"}, @@ -197,6 +198,16 @@ - (void)optionTapped:(NSString *)key [_chartView setNeedsDisplay]; } + + if ([key isEqualToString:@"toggleStepped"]) + { + for (id set in _chartView.data.dataSets) + { + set.drawSteppedEnabled = !set.isDrawSteppedEnabled; + } + + [_chartView setNeedsDisplay]; + } if ([key isEqualToString:@"toggleHighlight"]) { diff --git a/ChartsDemo/Classes/Demos/MultipleLinesChartViewController.m b/ChartsDemo/Classes/Demos/MultipleLinesChartViewController.m index 03fb8c980f..59ceffe802 100644 --- a/ChartsDemo/Classes/Demos/MultipleLinesChartViewController.m +++ b/ChartsDemo/Classes/Demos/MultipleLinesChartViewController.m @@ -37,6 +37,7 @@ - (void)viewDidLoad @{@"key": @"toggleFilled", @"label": @"Toggle Filled"}, @{@"key": @"toggleCircles", @"label": @"Toggle Circles"}, @{@"key": @"toggleCubic", @"label": @"Toggle Cubic"}, + @{@"key": @"toggleStepped", @"label": @"Toggle Stepped"}, @{@"key": @"toggleHighlight", @"label": @"Toggle Highlight"}, @{@"key": @"animateX", @"label": @"Animate X"}, @{@"key": @"animateY", @"label": @"Animate Y"}, @@ -161,6 +162,16 @@ - (void)optionTapped:(NSString *)key [_chartView setNeedsDisplay]; } + + if ([key isEqualToString:@"toggleStepped"]) + { + for (id set in _chartView.data.dataSets) + { + set.drawSteppedEnabled = !set.isDrawSteppedEnabled; + } + + [_chartView setNeedsDisplay]; + } if ([key isEqualToString:@"toggleHighlight"]) { diff --git a/ChartsDemo/Classes/RealmDemos/RealmLineChartViewController.m b/ChartsDemo/Classes/RealmDemos/RealmLineChartViewController.m index 78e45a5d39..7139465948 100644 --- a/ChartsDemo/Classes/RealmDemos/RealmLineChartViewController.m +++ b/ChartsDemo/Classes/RealmDemos/RealmLineChartViewController.m @@ -37,6 +37,7 @@ - (void)viewDidLoad @{@"key": @"toggleFilled", @"label": @"Toggle Filled"}, @{@"key": @"toggleCircles", @"label": @"Toggle Circles"}, @{@"key": @"toggleCubic", @"label": @"Toggle Cubic"}, + @{@"key": @"toggleStepped", @"label": @"Toggle Stepped"}, @{@"key": @"toggleHighlight", @"label": @"Toggle Highlight"}, @{@"key": @"animateX", @"label": @"Animate X"}, @{@"key": @"animateY", @"label": @"Animate Y"}, @@ -134,6 +135,16 @@ - (void)optionTapped:(NSString *)key [_chartView setNeedsDisplay]; } + if ([key isEqualToString:@"toggleStepped"]) + { + for (id set in _chartView.data.dataSets) + { + set.drawSteppedEnabled = !set.isDrawSteppedEnabled; + } + + [_chartView setNeedsDisplay]; + } + if ([key isEqualToString:@"toggleHighlight"]) { _chartView.data.highlightEnabled = !_chartView.data.isHighlightEnabled; diff --git a/ChartsRealm/Classes/Data/RealmLineDataSet.swift b/ChartsRealm/Classes/Data/RealmLineDataSet.swift index 055a801b9e..205e5b6cec 100644 --- a/ChartsRealm/Classes/Data/RealmLineDataSet.swift +++ b/ChartsRealm/Classes/Data/RealmLineDataSet.swift @@ -60,6 +60,12 @@ public class RealmLineDataSet: RealmLineRadarDataSet, ILineChartDataSet /// - returns: true if drawing cubic lines is enabled, false if not. public var isDrawCubicEnabled: Bool { return drawCubicEnabled } + /// If true, stepped lines are drawn instead of linear + public var drawSteppedEnabled = false + + /// - returns: true if drawing stepped lines is enabled, false if not. + public var isDrawSteppedEnabled: Bool { return drawSteppedEnabled } + /// The radius of the drawn circles. public var circleRadius = CGFloat(8.0) @@ -150,6 +156,7 @@ public class RealmLineDataSet: RealmLineRadarDataSet, ILineChartDataSet copy.lineDashLengths = lineDashLengths copy.drawCirclesEnabled = drawCirclesEnabled copy.drawCubicEnabled = drawCubicEnabled + copy.drawSteppedEnabled = drawSteppedEnabled return copy }