Skip to content

Commit

Permalink
Syncing 4.0.0 with master (#3160)
Browse files Browse the repository at this point in the history
* Fixed using wrong axis (Issue #2257)

* fix #1830. credit from #2049 (#2874)

* fix #1830. credit from #2049

* add combined chart unit tests for iOS, tvOS (macOS only have build process)

* use iterater rather than index

* Removed redundant ivars in BarLineChartViewBase (#3043)

* Removed redundant ivars in favour of proper access control

* Moved initialization of axes to their declaration to keep the same optionality exposed.

* Update 4.0.0 with master (#3135)

* Replaced relevant `ChartUtils` methods with `Double` extensions (#2994)

* Replaced relevant `ChartUtils` methods with `Double` extensions

Improves readability.
`nextUp` is built in and provides the same functionality.

* Updated `ChartUtilsTests` to match changes

* add option to build demo projects unit tests on iOS (#3121)

* add option to build demo projects unit tests on iOS

* add ChartsDemo-OSX build test.

* Update ViewPortHandler.swift (#3143)

fix a small bug

* Refactored ChartUtils method into CGPoint extension (#3087)

* Refactored ChartUtils method into CGPoint extension

* Replaced ChartUtils.defaultValueFormatter()

* Codestyle fixes

* Minor cleanup to Highlighter types (#3003)

* Minor cleanup to Highlighter types

* Fixes for PR

* Pulled master and updated code style

* added DataApproximator+N extension (#2848)

* added DataApproximator+N extension

* fixed PR notes

* Readded in missing files
  • Loading branch information
jjatie authored Jan 7, 2018
1 parent 11ff349 commit d9dba58
Show file tree
Hide file tree
Showing 15 changed files with 1,708 additions and 1,389 deletions.
2,420 changes: 1,212 additions & 1,208 deletions Charts.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions Source/Charts/Charts/BarLineChartViewBase.swift
Original file line number Diff line number Diff line change
Expand Up @@ -72,14 +72,14 @@ open class BarLineChartViewBase: ChartViewBase, BarLineScatterCandleBubbleChartD
/// The right Y axis renderer. This is a read-write property so you can set your own custom renderer here.
/// **default**: An instance of YAxisRenderer
@objc open lazy var rightYAxisRenderer = YAxisRenderer(viewPortHandler: viewPortHandler, axis: rightAxis, transformer: _rightAxisTransformer)

internal var _leftAxisTransformer: Transformer!
internal var _rightAxisTransformer: Transformer!

/// The X axis renderer. This is a read-write property so you can set your own custom renderer here.
/// **default**: An instance of XAxisRenderer
@objc open lazy var xAxisRenderer = XAxisRenderer(viewPortHandler: viewPortHandler, axis: xAxis, transformer: _leftAxisTransformer)

internal var _tapGestureRecognizer: NSUITapGestureRecognizer!
internal var _doubleTapGestureRecognizer: NSUITapGestureRecognizer!
#if !os(tvOS)
Expand Down Expand Up @@ -111,7 +111,7 @@ open class BarLineChartViewBase: ChartViewBase, BarLineScatterCandleBubbleChartD

_leftAxisTransformer = Transformer(viewPortHandler: viewPortHandler)
_rightAxisTransformer = Transformer(viewPortHandler: viewPortHandler)

self.highlighter = ChartHighlighter(chart: self)

_tapGestureRecognizer = NSUITapGestureRecognizer(target: self, action: #selector(tapGestureRecognized(_:)))
Expand Down
2 changes: 1 addition & 1 deletion Source/Charts/Charts/HorizontalBarChartView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ open class HorizontalBarChartView: BarChartView

_leftAxisTransformer = TransformerHorizontalBarChart(viewPortHandler: viewPortHandler)
_rightAxisTransformer = TransformerHorizontalBarChart(viewPortHandler: viewPortHandler)

renderer = HorizontalBarChartRenderer(dataProvider: self, animator: chartAnimator, viewPortHandler: viewPortHandler)
leftYAxisRenderer = YAxisRendererHorizontalBarChart(viewPortHandler: viewPortHandler, axis: leftAxis, transformer: _leftAxisTransformer)
rightYAxisRenderer = YAxisRendererHorizontalBarChart(viewPortHandler: viewPortHandler, axis: rightAxis, transformer: _rightAxisTransformer)
Expand Down
152 changes: 152 additions & 0 deletions Source/Charts/Filters/DataApproximator+N.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
//
// DataApproximator+N.swift
// Charts
//
// Created by M Ivaniushchenko on 9/6/17.
// Licensed under Apache License 2.0
//
// https://github.com/danielgindi/Charts
//

import Foundation

extension CGPoint {
fileprivate func distanceToLine(from linePoint1: CGPoint, to linePoint2: CGPoint) -> CGFloat {
let dx = linePoint2.x - linePoint1.x
let dy = linePoint2.y - linePoint1.y

let dividend = fabs(dy * self.x - dx * self.y - linePoint1.x * linePoint2.y + linePoint2.x * linePoint1.y)
let divisor = sqrt(dx * dx + dy * dy)

return dividend / divisor
}
}

private struct LineAlt {
let start: Int
let end: Int

var distance: CGFloat = 0
var index: Int = 0

init(start: Int, end: Int, points: [CGPoint]) {
self.start = start
self.end = end

let startPoint = points[start]
let endPoint = points[end]

guard (end > start + 1) else {
return
}

for i in start + 1 ..< end {
let currentPoint = points[i]

let distance = currentPoint.distanceToLine(from: startPoint, to: endPoint)

if distance > self.distance {
self.index = i
self.distance = distance
}
}
}
}

extension LineAlt: Comparable {
static func ==(lhs: LineAlt, rhs: LineAlt) -> Bool {
return (lhs.start == rhs.start) && (lhs.end == rhs.end) && (lhs.index == rhs.index)
}

static func <(lhs: LineAlt, rhs: LineAlt) -> Bool {
return lhs.distance < rhs.distance
}
}


extension DataApproximator {
/// uses the douglas peuker algorithm to reduce the given arraylist of entries to given number of points
/// More algorithm details here - http://psimpl.sourceforge.net/douglas-peucker.html
@objc open class func reduceWithDouglasPeukerN(_ points: [CGPoint], resultCount: Int) -> [CGPoint]
{
// if a shape has 2 or less points it cannot be reduced
if resultCount <= 2 || resultCount >= points.count
{
return points
}
var keep = [Bool](repeating: false, count: points.count)

// first and last always stay
keep[0] = true
keep[points.count - 1] = true
var currentStoredPoints = 2

var queue = [LineAlt]()
let line = LineAlt(start: 0, end: points.count - 1, points: points)
queue.append(line)

repeat {
let line = queue.popLast()!

// store the key
keep[line.index] = true

// check point count tolerance
currentStoredPoints += 1

if (currentStoredPoints == resultCount) {
break;
}

// split the polyline at the key and recurse
let left = LineAlt(start: line.start, end: line.index, points: points)
if (left.index > 0) {
self.insertLine(left, into: &queue)
}

let right = LineAlt(start: line.index, end: line.end, points: points)
if (right.index > 0) {
self.insertLine(right, into: &queue)
}

} while !queue.isEmpty

// create a new array with series, only take the kept ones
let reducedEntries = points.enumerated().flatMap { (index: Int, point: CGPoint) -> CGPoint? in
return keep[index] ? point : nil
}

return reducedEntries
}

// Keeps array sorted
private static func insertLine(_ line: LineAlt, into array: inout [LineAlt]) {
let insertionIndex = self.insertionIndex(for: line, into: &array)
array.insert(line, at: insertionIndex)
}

private static func insertionIndex(for line: LineAlt, into array: inout [LineAlt]) -> Int {
var indices = array.indices

while !indices.isEmpty {
let midIndex = indices.lowerBound.advanced(by: indices.count / 2)
let midLine = array[midIndex]

if midLine == line {
return midIndex
}
else if (line < midLine) {
// perform search in left half
indices = indices.lowerBound..<midIndex
}
else {
// perform search in right half
indices = (midIndex + 1)..<indices.upperBound
}
}

return indices.lowerBound
}
}


78 changes: 34 additions & 44 deletions Source/Charts/Highlight/BarHighlighter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,30 +17,25 @@ open class BarHighlighter: ChartHighlighter
{
open override func getHighlight(x: CGFloat, y: CGFloat) -> Highlight?
{
let high = super.getHighlight(x: x, y: y)
guard
let barData = (self.chart as? BarChartDataProvider)?.barData,
let high = super.getHighlight(x: x, y: y)
else { return nil }

if high == nil
let pos = getValsForTouch(x: x, y: y)

if let set = barData.getDataSetByIndex(high.dataSetIndex) as? BarChartDataSetProtocol,
set.isStacked
{
return nil
return getStackedHighlight(high: high,
set: set,
xValue: Double(pos.x),
yValue: Double(pos.y))
}

if let barData = (self.chart as? BarChartDataProvider)?.barData
else
{
let pos = getValsForTouch(x: x, y: y)

if
let set = barData.getDataSetByIndex(high!.dataSetIndex) as? BarChartDataSetProtocol,
set.isStacked
{
return getStackedHighlight(high: high!,
set: set,
xValue: Double(pos.x),
yValue: Double(pos.y))
}

return high
}
return nil
}

internal override func getDistance(x1: CGFloat, y1: CGFloat, x2: CGFloat, y2: CGFloat) -> CGFloat
Expand Down Expand Up @@ -75,25 +70,23 @@ open class BarHighlighter: ChartHighlighter
return high
}

if let ranges = entry.ranges,
guard
let ranges = entry.ranges,
ranges.count > 0
{
let stackIndex = getClosestStackIndex(ranges: ranges, value: yValue)

let pixel = chart
.getTransformer(forAxis: set.axisDependency)
.pixelForValues(x: high.x, y: ranges[stackIndex].to)

return Highlight(x: entry.x,
y: entry.y,
xPx: pixel.x,
yPx: pixel.y,
dataSetIndex: high.dataSetIndex,
stackIndex: stackIndex,
axis: high.axis)
}

return nil
else { return nil }

let stackIndex = getClosestStackIndex(ranges: ranges, value: yValue)
let pixel = chart
.getTransformer(forAxis: set.axisDependency)
.pixelForValues(x: high.x, y: ranges[stackIndex].to)

return Highlight(x: entry.x,
y: entry.y,
xPx: pixel.x,
yPx: pixel.y,
dataSetIndex: high.dataSetIndex,
stackIndex: stackIndex,
axis: high.axis)
}

/// - returns: The index of the closest value inside the values array / ranges (stacked barchart) to the value given as a parameter.
Expand All @@ -102,14 +95,11 @@ open class BarHighlighter: ChartHighlighter
/// - returns:
@objc open func getClosestStackIndex(ranges: [Range]?, value: Double) -> Int
{
if ranges == nil
{
return 0
}

guard let ranges = ranges else { return 0 }

var stackIndex = 0

for range in ranges!
for range in ranges
{
if range.contains(value)
{
Expand All @@ -121,8 +111,8 @@ open class BarHighlighter: ChartHighlighter
}
}

let length = max(ranges!.count - 1, 0)
let length = max(ranges.count - 1, 0)

return (value > ranges![length].to) ? length : 0
return (value > ranges[length].to) ? length : 0
}
}
Loading

0 comments on commit d9dba58

Please sign in to comment.