Skip to content

Commit f49ef5f

Browse files
committed
Major work on highlights
1 parent d0e05d8 commit f49ef5f

File tree

65 files changed

+932
-822
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

65 files changed

+932
-822
lines changed

Charts/Charts.xcodeproj/project.pbxproj

+48-8
Large diffs are not rendered by default.

Charts/Classes/Charts/BarLineChartViewBase.swift

+1-30
Original file line numberDiff line numberDiff line change
@@ -451,23 +451,6 @@ public class BarLineChartViewBase: ChartViewBase, BarLineScatterCandleBubbleChar
451451
prepareValuePxMatrix()
452452
}
453453

454-
public override func getMarkerPosition(entry e: ChartDataEntry, highlight: ChartHighlight) -> CGPoint
455-
{
456-
guard let data = _data else { return CGPointZero }
457-
458-
let dataSetIndex = highlight.dataSetIndex
459-
let xPos = e.x
460-
let yPos = e.y * _animator.phaseY
461-
462-
// position of the marker depends on selected value index and value
463-
var pt = CGPoint(x: CGFloat(xPos), y: CGFloat(yPos * _animator.phaseY))
464-
465-
getTransformer(data.getDataSetByIndex(dataSetIndex)!.axisDependency)
466-
.pointValueToPixel(&pt)
467-
468-
return pt
469-
}
470-
471454
/// draws the grid background
472455
internal func drawGridBackground(context context: CGContext)
473456
{
@@ -1560,18 +1543,6 @@ public class BarLineChartViewBase: ChartViewBase, BarLineScatterCandleBubbleChar
15601543
{
15611544
return drawBordersEnabled
15621545
}
1563-
1564-
/// - returns: the Highlight object (contains x-index and DataSet index) of the selected value at the given touch point inside the Line-, Scatter-, or CandleStick-Chart.
1565-
public func getHighlightByTouchPoint(pt: CGPoint) -> ChartHighlight?
1566-
{
1567-
if _data === nil
1568-
{
1569-
Swift.print("Can't select by touch. No data set.")
1570-
return nil
1571-
}
1572-
1573-
return self.highlighter?.getHighlight(x: pt.x, y: pt.y)
1574-
}
15751546

15761547
/// - returns: the x and y values in the chart at the given touch point
15771548
/// (encapsulated in a `CGPoint`). This method transforms pixel coordinates to
@@ -1602,7 +1573,7 @@ public class BarLineChartViewBase: ChartViewBase, BarLineScatterCandleBubbleChar
16021573
let h = getHighlightByTouchPoint(pt)
16031574
if (h !== nil)
16041575
{
1605-
return _data!.getEntryForHighlight(h!)
1576+
return _data!.entryForHighlight(h!)
16061577
}
16071578
return nil
16081579
}

Charts/Classes/Charts/ChartViewBase.swift

+23-9
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ public protocol ChartViewDelegate
2626
/// Called when a value has been selected inside the chart.
2727
/// - parameter entry: The selected Entry.
2828
/// - parameter dataSetIndex: The index in the datasets array of the data object the Entrys DataSet is in.
29-
optional func chartValueSelected(chartView: ChartViewBase, entry: ChartDataEntry, dataSetIndex: Int, highlight: ChartHighlight)
29+
optional func chartValueSelected(chartView: ChartViewBase, entry: ChartDataEntry, highlight: ChartHighlight)
3030

3131
// Called when nothing has been selected or an "un-select" has been made.
3232
optional func chartValueNothingSelected(chartView: ChartViewBase)
@@ -108,7 +108,7 @@ public class ChartViewBase: NSUIView, ChartDataProvider, ChartAnimatorDelegate
108108
/// object responsible for rendering the data
109109
public var renderer: ChartDataRendererBase?
110110

111-
public var highlighter: ChartHighlighter?
111+
public var highlighter: IChartHighlighter?
112112

113113
/// object that manages the bounds and drawing constraints of the chart
114114
internal var _viewPortHandler: ChartViewPortHandler!
@@ -490,7 +490,7 @@ public class ChartViewBase: NSUIView, ChartDataProvider, ChartAnimatorDelegate
490490
else
491491
{
492492
// set the indices to highlight
493-
entry = _data?.getEntryForHighlight(h!)
493+
entry = _data?.entryForHighlight(h!)
494494
if (entry == nil)
495495
{
496496
h = nil
@@ -501,7 +501,7 @@ public class ChartViewBase: NSUIView, ChartDataProvider, ChartAnimatorDelegate
501501
if self is BarLineChartViewBase
502502
&& (self as! BarLineChartViewBase).isHighlightFullBarEnabled
503503
{
504-
h = ChartHighlight(x: h!.x, y: Double.NaN, dataIndex: -1, dataSetIndex: -1, stackIndex: -1)
504+
h = ChartHighlight(x: h!.x, y: Double.NaN, xPx: CGFloat.NaN, yPx: CGFloat.NaN, dataSetIndex: -1, axis: .Left)
505505
}
506506

507507
_indicesToHighlight = [h!]
@@ -517,14 +517,28 @@ public class ChartViewBase: NSUIView, ChartDataProvider, ChartAnimatorDelegate
517517
else
518518
{
519519
// notify the listener
520-
delegate!.chartValueSelected?(self, entry: entry!, dataSetIndex: h!.dataSetIndex, highlight: h!)
520+
delegate!.chartValueSelected?(self, entry: entry!, highlight: h!)
521521
}
522522
}
523523

524524
// redraw the chart
525525
setNeedsDisplay()
526526
}
527527

528+
/// Returns the Highlight object (contains x-index and DataSet index) of the
529+
/// selected value at the given touch point inside the Line-, Scatter-, or
530+
/// CandleStick-Chart.
531+
public func getHighlightByTouchPoint(pt: CGPoint) -> ChartHighlight?
532+
{
533+
if _data === nil
534+
{
535+
Swift.print("Can't select by touch. No data set.")
536+
return nil
537+
}
538+
539+
return self.highlighter?.getHighlight(x: pt.x, y: pt.y)
540+
}
541+
528542
/// The last value that was highlighted via touch.
529543
public var lastHighlighted: ChartHighlight?
530544

@@ -545,7 +559,7 @@ public class ChartViewBase: NSUIView, ChartDataProvider, ChartAnimatorDelegate
545559

546560
guard let
547561
set = data?.getDataSetByIndex(highlight.dataSetIndex),
548-
e = _data?.getEntryForHighlight(highlight)
562+
e = _data?.entryForHighlight(highlight)
549563
else { continue }
550564

551565
let entryIndex = set.entryIndex(entry: e)
@@ -554,7 +568,7 @@ public class ChartViewBase: NSUIView, ChartDataProvider, ChartAnimatorDelegate
554568
continue
555569
}
556570

557-
let pos = getMarkerPosition(entry: e, highlight: highlight)
571+
let pos = getMarkerPosition(highlight: highlight)
558572

559573
// check bounds
560574
if !_viewPortHandler.isInBounds(x: pos.x, y: pos.y)
@@ -579,9 +593,9 @@ public class ChartViewBase: NSUIView, ChartDataProvider, ChartAnimatorDelegate
579593
}
580594

581595
/// - returns: the actual position in pixels of the MarkerView for the given Entry in the given DataSet.
582-
public func getMarkerPosition(entry entry: ChartDataEntry, highlight: ChartHighlight) -> CGPoint
596+
public func getMarkerPosition(highlight highlight: ChartHighlight) -> CGPoint
583597
{
584-
fatalError("getMarkerPosition() cannot be called on ChartViewBase")
598+
return CGPoint(x: highlight.drawX, y: highlight.drawY)
585599
}
586600

587601
// MARK: - Animation

Charts/Classes/Charts/CombinedChartView.swift

+15-2
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import Foundation
1515
import CoreGraphics
1616

1717
/// This chart class allows the combination of lines, bars, scatter and candle data all displayed in one chart area.
18-
public class CombinedChartView: BarLineChartViewBase, LineChartDataProvider, BarChartDataProvider, ScatterChartDataProvider, CandleChartDataProvider, BubbleChartDataProvider
18+
public class CombinedChartView: BarLineChartViewBase, CombinedChartDataProvider
1919
{
2020
/// the fill-formatter used for determining the position of the fill-line
2121
internal var _fillFormatter: ChartFillFormatter!
@@ -35,7 +35,7 @@ public class CombinedChartView: BarLineChartViewBase, LineChartDataProvider, Bar
3535
{
3636
super.initialize()
3737

38-
self.highlighter = CombinedHighlighter(chart: self)
38+
self.highlighter = CombinedHighlighter(chart: self, barDataProvider: self)
3939

4040
// Old default behaviour
4141
self.highlightFullBarEnabled = true
@@ -56,6 +56,9 @@ public class CombinedChartView: BarLineChartViewBase, LineChartDataProvider, Bar
5656
set
5757
{
5858
super.data = newValue
59+
60+
self.highlighter = CombinedHighlighter(chart: self, barDataProvider: self)
61+
5962
(renderer as! CombinedChartRenderer?)!.createRenderers()
6063
renderer?.initBuffers()
6164
}
@@ -77,6 +80,16 @@ public class CombinedChartView: BarLineChartViewBase, LineChartDataProvider, Bar
7780
}
7881
}
7982

83+
// MARK: - CombinedChartDataProvider
84+
85+
public var combinedData: CombinedChartData?
86+
{
87+
get
88+
{
89+
return _data as? CombinedChartData
90+
}
91+
}
92+
8093
// MARK: - LineChartDataProvider
8194

8295
public var lineData: LineChartData?

Charts/Classes/Charts/HorizontalBarChartView.swift

+5
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,11 @@ public class HorizontalBarChartView: BarChartView
100100
_leftAxisTransformer.prepareMatrixValuePx(chartXMin: _leftAxis._axisMinimum, deltaX: CGFloat(_leftAxis.axisRange), deltaY: CGFloat(_xAxis.axisRange), chartYMin: _xAxis._axisMinimum)
101101
}
102102

103+
public override func getMarkerPosition(highlight highlight: ChartHighlight) -> CGPoint
104+
{
105+
return CGPoint(x: highlight.drawY, y: highlight.drawX)
106+
}
107+
103108
public override func getBarBounds(e: BarChartDataEntry) -> CGRect
104109
{
105110
guard let

Charts/Classes/Charts/PieChartView.swift

+8-8
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,8 @@ public class PieChartView: PieRadarChartViewBase
8080

8181
renderer = PieChartRenderer(chart: self, animator: _animator, viewPortHandler: _viewPortHandler)
8282
_xAxis = nil
83+
84+
self.highlighter = PieChartHighlighter(chart: self)
8385
}
8486

8587
public override func drawRect(rect: CGRect)
@@ -140,7 +142,7 @@ public class PieChartView: PieRadarChartViewBase
140142
calcAngles()
141143
}
142144

143-
public override func getMarkerPosition(entry e: ChartDataEntry, highlight: ChartHighlight) -> CGPoint
145+
public override func getMarkerPosition(highlight highlight: ChartHighlight) -> CGPoint
144146
{
145147
let center = self.centerCircleBox
146148
var r = self.radius
@@ -156,8 +158,7 @@ public class PieChartView: PieRadarChartViewBase
156158

157159
let rotationAngle = self.rotationAngle
158160

159-
guard let entryIndex = data?.dataSets[0].entryIndex(x: highlight.x, rounding: .Closest)
160-
else { return CGPoint(x: 0.0, y: 0.0) }
161+
let entryIndex = Int(highlight.x)
161162

162163
// offset needed to center the drawn text in the slice
163164
let offset = drawAngles[entryIndex] / 2.0
@@ -213,20 +214,19 @@ public class PieChartView: PieRadarChartViewBase
213214
}
214215
}
215216

216-
/// checks if the given index in the given DataSet is set for highlighting or not
217-
public func needsHighlight(xValue xValue: Double, dataSetIndex: Int) -> Bool
217+
/// Checks if the given index is set to be highlighted.
218+
public func needsHighlight(index index: Int) -> Bool
218219
{
219220
// no highlight
220-
if (!valuesToHighlight() || dataSetIndex < 0)
221+
if !valuesToHighlight()
221222
{
222223
return false
223224
}
224225

225226
for i in 0 ..< _indicesToHighlight.count
226227
{
227228
// check if the xvalue for the given dataset needs highlight
228-
if (_indicesToHighlight[i].x == xValue
229-
&& _indicesToHighlight[i].dataSetIndex == dataSetIndex)
229+
if Int(_indicesToHighlight[i].x) == index
230230
{
231231
return true
232232
}

Charts/Classes/Charts/PieRadarChartViewBase.swift

+3-103
Original file line numberDiff line numberDiff line change
@@ -279,7 +279,7 @@ public class PieRadarChartViewBase: ChartViewBase
279279

280280
/// Calculates the position around a center point, depending on the distance
281281
/// from the center, and the angle of the position around the center.
282-
internal func getPosition(center center: CGPoint, dist: CGFloat, angle: CGFloat) -> CGPoint
282+
public func getPosition(center center: CGPoint, dist: CGFloat, angle: CGFloat) -> CGPoint
283283
{
284284
return CGPoint(x: center.x + dist * cos(angle * ChartUtils.Math.FDEG2RAD),
285285
y: center.y + dist * sin(angle * ChartUtils.Math.FDEG2RAD))
@@ -391,36 +391,6 @@ public class PieRadarChartViewBase: ChartViewBase
391391
return 0.0
392392
}
393393

394-
/// The SelectionDetail objects give information about the value at the selected index and the DataSet it belongs to.
395-
/// - returns: an array of SelectionDetail objects for the given x-index.
396-
public func getSelectionDetailsAtIndex(xValue: Double) -> [ChartSelectionDetail]
397-
{
398-
var vals = [ChartSelectionDetail]()
399-
400-
guard let data = _data else { return vals }
401-
402-
for i in 0 ..< data.dataSetCount
403-
{
404-
guard let dataSet = data.getDataSetByIndex(i) else { continue }
405-
406-
if !dataSet.isHighlightEnabled
407-
{
408-
continue
409-
}
410-
411-
// extract all y-values from all DataSets at the given x-index
412-
let yVal = dataSet.yValueForXValue(xValue)
413-
if (yVal.isNaN)
414-
{
415-
continue
416-
}
417-
418-
vals.append(ChartSelectionDetail(xValue: 0.0, yValue: yVal, dataSetIndex: i, dataSet: dataSet))
419-
}
420-
421-
return vals
422-
}
423-
424394
public var isRotationEnabled: Bool { return rotationEnabled; }
425395

426396
/// flag that indicates if rotation is done with two fingers or one.
@@ -860,79 +830,9 @@ public class PieRadarChartViewBase: ChartViewBase
860830
if !self.isHighLightPerTapEnabled { return }
861831

862832
let location = recognizer.locationInView(self)
863-
let distance = distanceToCenter(x: location.x, y: location.y)
864833

865-
// check if a slice was touched
866-
if (distance > self.radius)
867-
{
868-
// if no slice was touched, highlight nothing
869-
self.highlightValues(nil)
870-
871-
if _lastHighlight == nil
872-
{
873-
self.highlightValues(nil) // do not call delegate
874-
}
875-
else
876-
{
877-
self.highlightValue(highlight: nil, callDelegate: true) // call delegate
878-
}
879-
880-
_lastHighlight = nil
881-
}
882-
else
883-
{
884-
var angle = angleForPoint(x: location.x, y: location.y)
885-
886-
if (self.isKindOfClass(PieChartView))
887-
{
888-
angle /= CGFloat(_animator.phaseY)
889-
}
890-
891-
let index = indexForAngle(angle)
892-
893-
// check if the index could be found
894-
if (index < 0)
895-
{
896-
self.highlightValues(nil)
897-
_lastHighlight = nil
898-
}
899-
else
900-
{
901-
let valsAtIndex = getSelectionDetailsAtIndex(Double(index))
902-
903-
var dataSetIndex = 0
904-
905-
// get the dataset that is closest to the selection (PieChart only has one DataSet)
906-
if (self.isKindOfClass(RadarChartView))
907-
{
908-
dataSetIndex = ChartUtils.closestDataSetIndexByValue(
909-
valsAtIndex: valsAtIndex,
910-
value: Double(distance / (self as! RadarChartView).factor),
911-
axis: nil) ?? -1
912-
}
913-
914-
if (dataSetIndex < 0)
915-
{
916-
self.highlightValues(nil)
917-
_lastHighlight = nil
918-
}
919-
else
920-
{
921-
let h = ChartHighlight(x: Double(index), dataSetIndex: dataSetIndex)
922-
923-
if (_lastHighlight !== nil && h == _lastHighlight)
924-
{
925-
self.highlightValue(highlight: nil, callDelegate: true)
926-
_lastHighlight = nil
927-
}
928-
else
929-
{
930-
self.highlightValue(highlight: h, callDelegate: true)
931-
_lastHighlight = h
932-
}
933-
}
934-
}
935-
}
834+
let high = self.getHighlightByTouchPoint(location)
835+
self.highlightValue(high)
936836
}
937837
}
938838

0 commit comments

Comments
 (0)