Skip to content

Commit

Permalink
Feature #539 Stepped line charts
Browse files Browse the repository at this point in the history
A new flag was added to ILineChartDataSet and relative implementations. The value of the flag is then used to slightly modify the behavior of drawLinear and generateFilledPath in LineChartRenderer.
The appropriate demo viewControllers were also updated with the new flag.
  • Loading branch information
ezamagni committed Feb 26, 2016
1 parent 796b2f8 commit 70cd5bd
Show file tree
Hide file tree
Showing 8 changed files with 90 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -160,6 +166,7 @@ public class LineChartDataSet: LineRadarChartDataSet, ILineChartDataSet
copy.lineDashLengths = lineDashLengths
copy.drawCirclesEnabled = drawCirclesEnabled
copy.drawCubicEnabled = drawCubicEnabled
copy.drawSteppedEnabled = drawSteppedEnabled
return copy
}
}
6 changes: 6 additions & 0 deletions Charts/Classes/Data/Interfaces/ILineChartDataSet.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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 }

Expand Down
36 changes: 26 additions & 10 deletions Charts/Classes/Renderers/LineChartRenderer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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++)
Expand All @@ -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))
{
Expand All @@ -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
Expand All @@ -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)
Expand All @@ -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)
}
Expand Down Expand Up @@ -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)
}

Expand Down
11 changes: 11 additions & 0 deletions ChartsDemo/Classes/Demos/LineChart1ViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -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"},
Expand Down Expand Up @@ -201,6 +202,16 @@ - (void)optionTapped:(NSString *)key

[_chartView setNeedsDisplay];
}

if ([key isEqualToString:@"toggleStepped"])
{
for (id<ILineChartDataSet> set in _chartView.data.dataSets)
{
set.drawSteppedEnabled = !set.isDrawSteppedEnabled;
}

[_chartView setNeedsDisplay];
}

if ([key isEqualToString:@"toggleHighlight"])
{
Expand Down
11 changes: 11 additions & 0 deletions ChartsDemo/Classes/Demos/LineChart2ViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -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"},
Expand Down Expand Up @@ -197,6 +198,16 @@ - (void)optionTapped:(NSString *)key

[_chartView setNeedsDisplay];
}

if ([key isEqualToString:@"toggleStepped"])
{
for (id<ILineChartDataSet> set in _chartView.data.dataSets)
{
set.drawSteppedEnabled = !set.isDrawSteppedEnabled;
}

[_chartView setNeedsDisplay];
}

if ([key isEqualToString:@"toggleHighlight"])
{
Expand Down
11 changes: 11 additions & 0 deletions ChartsDemo/Classes/Demos/MultipleLinesChartViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -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"},
Expand Down Expand Up @@ -161,6 +162,16 @@ - (void)optionTapped:(NSString *)key

[_chartView setNeedsDisplay];
}

if ([key isEqualToString:@"toggleStepped"])
{
for (id<ILineChartDataSet> set in _chartView.data.dataSets)
{
set.drawSteppedEnabled = !set.isDrawSteppedEnabled;
}

[_chartView setNeedsDisplay];
}

if ([key isEqualToString:@"toggleHighlight"])
{
Expand Down
11 changes: 11 additions & 0 deletions ChartsDemo/Classes/RealmDemos/RealmLineChartViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -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"},
Expand Down Expand Up @@ -134,6 +135,16 @@ - (void)optionTapped:(NSString *)key
[_chartView setNeedsDisplay];
}

if ([key isEqualToString:@"toggleStepped"])
{
for (id<ILineChartDataSet> set in _chartView.data.dataSets)
{
set.drawSteppedEnabled = !set.isDrawSteppedEnabled;
}

[_chartView setNeedsDisplay];
}

if ([key isEqualToString:@"toggleHighlight"])
{
_chartView.data.highlightEnabled = !_chartView.data.isHighlightEnabled;
Expand Down
7 changes: 7 additions & 0 deletions ChartsRealm/Classes/Data/RealmLineDataSet.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down Expand Up @@ -150,6 +156,7 @@ public class RealmLineDataSet: RealmLineRadarDataSet, ILineChartDataSet
copy.lineDashLengths = lineDashLengths
copy.drawCirclesEnabled = drawCirclesEnabled
copy.drawCubicEnabled = drawCubicEnabled
copy.drawSteppedEnabled = drawSteppedEnabled
return copy
}

Expand Down

0 comments on commit 70cd5bd

Please sign in to comment.