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

Syncing 4.0.0 with master #3160

Merged
merged 13 commits into from
Jan 7, 2018
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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