Skip to content

Commit

Permalink
Merge pull request #772 from ospr/support-optional-charts-data-property
Browse files Browse the repository at this point in the history
Make ChartViewBase's _data optional. (Fixes #771)
  • Loading branch information
danielgindi committed Feb 28, 2016
2 parents a16e84d + bcc69ef commit 35a7cf3
Show file tree
Hide file tree
Showing 11 changed files with 110 additions and 116 deletions.
20 changes: 6 additions & 14 deletions Charts/Classes/Charts/BarChartView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -42,18 +42,15 @@ public class BarChartView: BarLineChartViewBase, BarChartDataProvider
{
super.calcMinMax()

if (_data === nil)
{
return
}
guard let data = _data else { return }

let barData = _data as! BarChartData
let barData = data as! BarChartData

// increase deltax by 1 because the bars have a width of 1
_deltaX += 0.5

// extend xDelta to make space for multiple datasets (if ther are one)
_deltaX *= CGFloat(_data.dataSetCount)
_deltaX *= CGFloat(data.dataSetCount)

let groupSpace = barData.groupSpace
_deltaX += CGFloat(barData.xValCount) * groupSpace
Expand All @@ -75,12 +72,7 @@ public class BarChartView: BarLineChartViewBase, BarChartDataProvider
/// - returns: the bounding box of the specified Entry in the specified DataSet. Returns null if the Entry could not be found in the charts data.
public func getBarBounds(e: BarChartDataEntry) -> CGRect
{
let set = _data.getDataSetForEntry(e) as! IBarChartDataSet!

if (set === nil)
{
return CGRectNull
}
guard let set = _data?.getDataSetForEntry(e) as? IBarChartDataSet else { return CGRectNull }

let barspace = set.barSpace
let y = CGFloat(e.value)
Expand All @@ -103,7 +95,7 @@ public class BarChartView: BarLineChartViewBase, BarChartDataProvider

public override var lowestVisibleXIndex: Int
{
let step = CGFloat(_data.dataSetCount)
let step = CGFloat(_data?.dataSetCount ?? 0)
let div = (step <= 1.0) ? 1.0 : step + (_data as! BarChartData).groupSpace

var pt = CGPoint(x: _viewPortHandler.contentLeft, y: _viewPortHandler.contentBottom)
Expand All @@ -114,7 +106,7 @@ public class BarChartView: BarLineChartViewBase, BarChartDataProvider

public override var highestVisibleXIndex: Int
{
let step = CGFloat(_data.dataSetCount)
let step = CGFloat(_data?.dataSetCount ?? 0)
let div = (step <= 1.0) ? 1.0 : step + (_data as! BarChartData).groupSpace

var pt = CGPoint(x: _viewPortHandler.contentRight, y: _viewPortHandler.contentBottom)
Expand Down
44 changes: 24 additions & 20 deletions Charts/Classes/Charts/BarLineChartViewBase.swift
Original file line number Diff line number Diff line change
Expand Up @@ -263,11 +263,6 @@ public class BarLineChartViewBase: ChartViewBase, BarLineScatterCandleBubbleChar

public override func notifyDataSetChanged()
{
if _data === nil
{
return
}

calcMinMax()

_leftAxis?._defaultValueFormatter = _defaultValueFormatter
Expand All @@ -276,11 +271,14 @@ public class BarLineChartViewBase: ChartViewBase, BarLineScatterCandleBubbleChar
_leftYAxisRenderer?.computeAxis(yMin: _leftAxis.axisMinimum, yMax: _leftAxis.axisMaximum)
_rightYAxisRenderer?.computeAxis(yMin: _rightAxis.axisMinimum, yMax: _rightAxis.axisMaximum)

_xAxisRenderer?.computeAxis(xValAverageLength: _data.xValAverageLength, xValues: _data.xVals)

if (_legend !== nil)
if let data = _data
{
_legendRenderer?.computeLegend(_data)
_xAxisRenderer?.computeAxis(xValAverageLength: data.xValAverageLength, xValues: data.xVals)

if (_legend !== nil)
{
_legendRenderer?.computeLegend(data)
}
}

calculateOffsets()
Expand All @@ -292,21 +290,21 @@ public class BarLineChartViewBase: ChartViewBase, BarLineScatterCandleBubbleChar
{
if (_autoScaleMinMaxEnabled)
{
_data.calcMinMax(start: lowestVisibleXIndex, end: highestVisibleXIndex)
_data?.calcMinMax(start: lowestVisibleXIndex, end: highestVisibleXIndex)
}

var minLeft = !isnan(_leftAxis.customAxisMin)
? _leftAxis.customAxisMin
: _data.getYMin(.Left)
: _data?.getYMin(.Left) ?? 0
var maxLeft = !isnan(_leftAxis.customAxisMax)
? _leftAxis.customAxisMax
: _data.getYMax(.Left)
: _data?.getYMax(.Left) ?? 0
var minRight = !isnan(_rightAxis.customAxisMin)
? _rightAxis.customAxisMin
: _data.getYMin(.Right)
: _data?.getYMin(.Right) ?? 0
var maxRight = !isnan(_rightAxis.customAxisMax)
? _rightAxis.customAxisMax
: _data.getYMax(.Right)
: _data?.getYMax(.Right) ?? 0

let leftRange = abs(maxLeft - minLeft)
let rightRange = abs(maxRight - minRight)
Expand All @@ -329,7 +327,7 @@ public class BarLineChartViewBase: ChartViewBase, BarLineScatterCandleBubbleChar
let bottomSpaceLeft = leftRange * Double(_leftAxis.spaceBottom)
let bottomSpaceRight = rightRange * Double(_rightAxis.spaceBottom)

_chartXMax = Double(_data.xVals.count - 1)
_chartXMax = Double((_data?.xVals.count ?? 0) - 1)
_deltaX = CGFloat(abs(_chartXMax - _chartXMin))

// Use the values as they are
Expand Down Expand Up @@ -455,7 +453,7 @@ public class BarLineChartViewBase: ChartViewBase, BarLineScatterCandleBubbleChar

if (!_xAxis.isAxisModulusCustom)
{
_xAxis.axisLabelModulus = Int(ceil((CGFloat(_data.xValCount) * _xAxis.labelRotatedWidth) / (_viewPortHandler.contentWidth * _viewPortHandler.touchMatrix.a)))
_xAxis.axisLabelModulus = Int(ceil((CGFloat(_data?.xValCount ?? 0) * _xAxis.labelRotatedWidth) / (_viewPortHandler.contentWidth * _viewPortHandler.touchMatrix.a)))
}

if (_xAxis.axisLabelModulus < 1)
Expand All @@ -466,6 +464,8 @@ public class BarLineChartViewBase: ChartViewBase, BarLineScatterCandleBubbleChar

public override func getMarkerPosition(entry e: ChartDataEntry, highlight: ChartHighlight) -> CGPoint
{
guard let data = _data else { return CGPointZero }

let dataSetIndex = highlight.dataSetIndex
var xPos = CGFloat(e.xIndex)
var yPos = CGFloat(e.value)
Expand All @@ -474,7 +474,7 @@ public class BarLineChartViewBase: ChartViewBase, BarLineScatterCandleBubbleChar
{
let bd = _data as! BarChartData
let space = bd.groupSpace
let setCount = _data.dataSetCount
let setCount = data.dataSetCount
let i = e.xIndex

if self is HorizontalBarChartView
Expand Down Expand Up @@ -519,7 +519,7 @@ public class BarLineChartViewBase: ChartViewBase, BarLineScatterCandleBubbleChar
// position of the marker depends on selected value index and value
var pt = CGPoint(x: xPos, y: yPos * _animator.phaseY)

getTransformer(_data.getDataSetByIndex(dataSetIndex)!.axisDependency).pointValueToPixel(&pt)
getTransformer(data.getDataSetByIndex(dataSetIndex)!.axisDependency).pointValueToPixel(&pt)

return pt
}
Expand Down Expand Up @@ -1638,7 +1638,7 @@ public class BarLineChartViewBase: ChartViewBase, BarLineScatterCandleBubbleChar
let h = getHighlightByTouchPoint(pt)
if (h !== nil)
{
return _data.getDataSetByIndex(h!.dataSetIndex) as! IBarLineScatterCandleBubbleChartDataSet!
return _data?.getDataSetByIndex(h!.dataSetIndex) as! IBarLineScatterCandleBubbleChartDataSet!
}
return nil
}
Expand Down Expand Up @@ -1912,6 +1912,10 @@ public class BarLineChartViewBase: ChartViewBase, BarLineScatterCandleBubbleChar
{
var pt = CGPoint(x: viewPortHandler.contentRight, y: viewPortHandler.contentBottom)
getTransformer(.Left).pixelToValue(&pt)
return (_data != nil && Int(round(pt.x)) >= _data.xValCount) ? _data.xValCount - 1 : Int(round(pt.x))
let ptRoundedX = Int(round(pt.x))

guard let data = _data else { return ptRoundedX }

return min(data.xValCount - 1, ptRoundedX)
}
}
7 changes: 4 additions & 3 deletions Charts/Classes/Charts/BubbleChartView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,18 @@ public class BubbleChartView: BarLineChartViewBase, BubbleChartDataProvider
public override func calcMinMax()
{
super.calcMinMax()
guard let data = _data else { return }

if (_deltaX == 0.0 && _data.yValCount > 0)
if (_deltaX == 0.0 && data.yValCount > 0)
{
_deltaX = 1.0
}

_chartXMin = -0.5
_chartXMax = Double(_data.xVals.count) - 0.5
_chartXMax = Double(data.xVals.count) - 0.5

if renderer as? BubbleChartRenderer !== nil,
let sets = _data.dataSets as? [IBubbleChartDataSet]
let sets = data.dataSets as? [IBubbleChartDataSet]
{
for set in sets {

Expand Down
76 changes: 35 additions & 41 deletions Charts/Classes/Charts/ChartViewBase.swift
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public class ChartViewBase: UIView, ChartDataProvider, ChartAnimatorDelegate
internal var _defaultValueFormatter: NSNumberFormatter = ChartUtils.defaultValueFormatter()

/// object that holds all data that was originally set for the chart, before it was modified or any filtering algorithms had been applied
internal var _data: ChartData!
internal var _data: ChartData?

/// Flag that indicates if highlighting per tap (touch) is enabled
private var _highlightPerTapEnabled = true
Expand Down Expand Up @@ -191,17 +191,14 @@ public class ChartViewBase: UIView, ChartDataProvider, ChartAnimatorDelegate
}
set
{
if newValue == nil
{
print("Charts: data argument is nil on setData()", terminator: "\n")
return
}

_offsetsCalculated = false
_data = newValue

// calculate how many digits are needed
calculateFormatter(min: _data.getYMin(), max: _data.getYMax())
if let data = _data
{
calculateFormatter(min: data.getYMin(), max: data.getYMax())
}

notifyDataSetChanged()
}
Expand All @@ -218,31 +215,22 @@ public class ChartViewBase: UIView, ChartDataProvider, ChartAnimatorDelegate
/// Removes all DataSets (and thereby Entries) from the chart. Does not remove the x-values. Also refreshes the chart by calling setNeedsDisplay().
public func clearValues()
{
if (_data !== nil)
{
_data.clearValues()
}
_data?.clearValues()
setNeedsDisplay()
}

/// - returns: true if the chart is empty (meaning it's data object is either null or contains no entries).
public func isEmpty() -> Bool
{
if (_data == nil)
guard let data = _data else { return true }

if (data.yValCount <= 0)
{
return true
}
else
{

if (_data.yValCount <= 0)
{
return true
}
else
{
return false
}
return false
}
}

Expand Down Expand Up @@ -271,15 +259,15 @@ public class ChartViewBase: UIView, ChartDataProvider, ChartAnimatorDelegate
// check if a custom formatter is set or not
var reference = Double(0.0)

if (_data == nil || _data.xValCount < 2)
if let data = _data where data.xValCount >= 2
{
let absMin = fabs(min)
let absMax = fabs(max)
reference = absMin > absMax ? absMin : absMax
reference = fabs(max - min)
}
else
{
reference = fabs(max - min)
let absMin = fabs(min)
let absMax = fabs(max)
reference = absMin > absMax ? absMin : absMax
}

let digits = ChartUtils.decimals(reference)
Expand Down Expand Up @@ -453,7 +441,13 @@ public class ChartViewBase: UIView, ChartDataProvider, ChartAnimatorDelegate
/// Provide -1 as the x-index to undo all highlighting.
public func highlightValue(xIndex xIndex: Int, dataSetIndex: Int, callDelegate: Bool)
{
if (xIndex < 0 || dataSetIndex < 0 || xIndex >= _data.xValCount || dataSetIndex >= _data.dataSetCount)
guard let data = _data else
{
print("Value not highlighted because data is nil")
return
}

if (xIndex < 0 || dataSetIndex < 0 || xIndex >= data.xValCount || dataSetIndex >= data.dataSetCount)
{
highlightValue(highlight: nil, callDelegate: callDelegate)
}
Expand All @@ -476,7 +470,7 @@ public class ChartViewBase: UIView, ChartDataProvider, ChartAnimatorDelegate
else
{
// set the indices to highlight
entry = _data.getEntryForHighlight(h!)
entry = _data?.getEntryForHighlight(h!)
if (entry === nil || entry!.xIndex != h?.xIndex)
{
h = nil
Expand Down Expand Up @@ -527,7 +521,7 @@ public class ChartViewBase: UIView, ChartDataProvider, ChartAnimatorDelegate

if (xIndex <= Int(_deltaX) && xIndex <= Int(_deltaX * _animator.phaseX))
{
let e = _data.getEntryForHighlight(highlight)
let e = _data?.getEntryForHighlight(highlight)
if (e === nil || e!.xIndex != highlight.xIndex)
{
continue
Expand Down Expand Up @@ -680,13 +674,13 @@ public class ChartViewBase: UIView, ChartDataProvider, ChartAnimatorDelegate
/// - returns: the current y-max value across all DataSets
public var chartYMax: Double
{
return _data.yMax
return _data?.yMax ?? 0.0
}

/// - returns: the current y-min value across all DataSets
public var chartYMin: Double
{
return _data.yMin
return _data?.yMin ?? 0.0
}

public var chartXMax: Double
Expand All @@ -701,13 +695,13 @@ public class ChartViewBase: UIView, ChartDataProvider, ChartAnimatorDelegate

public var xValCount: Int
{
return _data.xValCount
return _data?.xValCount ?? 0
}

/// - returns: the total number of (y) values the chart holds (across all DataSets)
public var valueCount: Int
{
return _data.yValCount
return _data?.yValCount ?? 0
}

/// *Note: (Equivalent of getCenter() in MPAndroidChart, as center is already a standard in iOS that returns the center point relative to superview, and MPAndroidChart returns relative to self)*
Expand Down Expand Up @@ -750,24 +744,24 @@ public class ChartViewBase: UIView, ChartDataProvider, ChartAnimatorDelegate
/// - returns: the x-value at the given index
public func getXValue(index: Int) -> String!
{
if (_data == nil || _data.xValCount <= index)
guard let data = _data where data.xValCount > index else
{
return nil
}
else
{
return _data.xVals[index]
}

return data.xVals[index]
}

/// Get all Entry objects at the given index across all DataSets.
public func getEntriesAtIndex(xIndex: Int) -> [ChartDataEntry]
{
var vals = [ChartDataEntry]()

for (var i = 0, count = _data.dataSetCount; i < count; i++)
guard let data = _data else { return vals }

for (var i = 0, count = data.dataSetCount; i < count; i++)
{
let set = _data.getDataSetByIndex(i)
let set = data.getDataSetByIndex(i)
let e = set.entryForXIndex(xIndex)
if (e !== nil)
{
Expand Down
Loading

0 comments on commit 35a7cf3

Please sign in to comment.