Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make ChartViewBase's _data optional. (Fixes #771) #772

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
20 changes: 6 additions & 14 deletions Charts/Classes/Charts/BarChartView.swift
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
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 @@ -1404,7 +1404,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 @@ -1678,6 +1678,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
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
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