Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Interactive Tracking with iOS Charts. How to

Using iOS Charts (by Daniel Gindi https://github.com/danielgindi/Charts), is it possible to track touching? So when I move my finger on the screen, instead of panning the graph, it would continuously highlight the entry I touched. Something like the image below.

I am thinking to probably add a UIGestureRecognizer to the chart view, get the position of the touch, and programmatically highlight the entry. But how can I get the entry at that specific position? Thank you

enter image description here

like image 444
Jack Guo Avatar asked Feb 02 '18 14:02

Jack Guo


1 Answers

I figured it out to save you sometime

enter image description here

extension GraphViewController: ChartViewDelegate {

    func chartValueSelected(_ chartView: ChartViewBase, entry: ChartDataEntry, highlight: Highlight) {

        // I used the x pixel property of the highlight to update the
        // position of the floating label, and set its text to the 
        // x value of the selected entry
        floatingLabelCenterConstraint?.constant = highlight.xPx
        floatingLabel.text = "  Mar 14  \(highlight.x)"

        // Create the nice transition animation
        // fadeIn() and fadeOut() are simple extension methods I wrote
        if floatingLabel.isHidden {
            floatingLabel.fadeIn()
            subscripts.fadeOut()
        }

        // This gives you the y value of the selected entry
        greenNumber.text = NSString(format: "%.2f", highlight.y) as String
    }
}

However, this delegate method is called only when you are moving your finger. You need a way to tell when the pan gesture ended. Charts does not have this delegate method out of the box, so you need to add it. Go to the ChartViewBase.swift source file, add the following to ChartViewDelegate protocol

public protocol ChartViewDelegate
{
    ...
    @objc optional func panGestureEnded(_ chartView: ChartViewBase)
}

Then go to BarLineChartViewBase.swift, find panGestureRecognized function

@objc private func panGestureRecognized(_ recognizer: NSUIPanGestureRecognizer)
{
    ...
    else if recognizer.state == NSUIGestureRecognizerState.ended || recognizer.state == NSUIGestureRecognizerState.cancelled
    {
    ...

    // Add this line at the end
    delegate?.panGestureEnded?(self)
    }
}

Finally, go back to your viewController and add the following. Now everything works like a charm

func panGestureEnded(_ chartView: ChartViewBase) {
    subscripts.fadeIn()
    floatingLabel.fadeOut()

    // clear selection by setting highlightValue to nil
    chartView.highlightValue(nil)
}
like image 133
Jack Guo Avatar answered Sep 18 '22 03:09

Jack Guo