1

I am using Charts to create custom graphs in an application. The one thing I am having trouble with is detecting touch events on the chart marker that is presented for the current value. I want to perform and action based on the marker that was tapped. The action should take in the data entry represented by the tapped marker.

I have read through Selectable marker view & images at Y axis, but still haven't been able to produce a viable solution.

It would be great if someone could provide a code sample, or more detailed explanation than found in the link above, to point me in the right direction.

Thanks

smandrus
  • 305
  • 1
  • 2
  • 16

2 Answers2

1

As per your requirement Charts library already have that method in its delegate.

Please check below code :

  1. Assign delegate to your ChartView like below
lineChartView.delegate = self
  1. Implement Delegate method in your class
public func chartValueSelected(_ chartView: ChartViewBase, entry: ChartDataEntry, highlight: Highlight) {

}

Here you can write your code while user click on chart.

Hope this info will helps!

CodeChanger
  • 7,953
  • 5
  • 49
  • 80
  • 1
    Unfortunately, this only detects when you tap a particular value on the chart, not the marker. It doesn't distinguish whether or not a user tapped on the chart marker vs the user just tapped the value. I need to be able to perform an action when they tap the marker only, not just the value – smandrus Aug 21 '18 at 15:23
  • but it will give you near by marker so this method you can utilize it as per your requirements. – CodeChanger Aug 22 '18 at 10:13
1

I ended up solving this by subclassing the ChartView of my choice and overriding the existing tap gesture recognizer with my own.

Example

final class CustomChartView: BarChartView {
    ...
    private func initialize() {
        ...
        let tap = UITapGestureRecognizer(target: self, action: #selector(tapRecognized))
        self.addGestureRecognizer(tap)
    }

    @objc func tapRecognized(_ recognizer: UITapGestureRecognizer) {
        guard data !== nil else { return }

        switch recognizer.state {
            case .ended:
            // Detect whether or not the touch was inside a marker that was being presented
            // Otherwise, add/remove highlight as necessary

            if let marker = self.marker as? BalloonMarker {
                let location = recognizer.location(in: self)

                if !highlighted.isEmpty && marker.rect.contains(location) {
                    // In my case, I created custom property 'vertex' on BalloonMarker for easy reference to get `xValue`
                    let xValue = self.getTransformer(forAxis: .left).valueForTouchPoint(marker.vertex).x

                    // Do what you need to here with tap (call function, create custom delegate and trigger it, etc)
                    // In my case, my chart has a marker tap delegate
                    // ex, something like: `markerTapDelegate?.tappedMarker()`

                    return
                }
            }

            // Default tap handling
            guard isHighLightPerTapEnabled else { return }

            let h = getHighlightByTouchPoint(recognizer.location(in: self))

            if h === nil || h == self.lastHighlighted {
                lastHighlighted = nil
                highlightValue(nil, callDelegate: true)

            } else {
                lastHighlighted = h
                highlightValue(h, callDelegate: true)
            }

        default:
            break
    }
}
smandrus
  • 305
  • 1
  • 2
  • 16