Search code examples
iosdelegatesios-charts

danielgindi/iOSCharts chartValueSelected not called


I am using danielgindi/iOSCharts library to crate combined line&bar charts like below.

enter image description here

enter image description here

My chart is rendered correctly and it has user interactions like tap and pinch zoom. Also chart is able to detect my tap gesture. But somehow

func chartValueSelected(chartView: ChartViewBase, entry: ChartDataEntry, dataSetIndex: Int, highlight: Highlight){
        print("###################")
    }

cannot be called. Really need some help here.

What I want to implement is that both balloon mark with same X value would show if I click on either a bar or a point on line. (both mark in above two pictures will display at same time when I tap a bar or a point)

Below is my entire controller code:

class FirstViewController: UIViewController,ChartViewDelegate {
@objc(ChartFormatter)
public class ChartFormatter: NSObject, IAxisValueFormatter{

    var months: [String]! = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]


    public func stringForValue(_ value: Double, axis: AxisBase?) -> String {

        return months[Int(value)]
    }
}

@IBOutlet weak var chartView: CombinedChartView!
var lineChartData = LineChartData()
var barChartData = BarChartData()

override func viewDidLoad() {
    super.viewDidLoad()

    chartView.delegate = self

    chartView.chartDescription?.enabled = true

    chartView.dragEnabled = true
    chartView.setScaleEnabled(true)
    chartView.pinchZoomEnabled = true
    chartView.drawGridBackgroundEnabled = false

    let xAxis:XAxis = chartView.xAxis
    xAxis.labelPosition = .bottom

    xAxis.labelFont = UIFont.systemFont(ofSize: 11.0)
    xAxis.labelTextColor = UIColor.black
    xAxis.drawGridLinesEnabled = true
    xAxis.drawAxisLineEnabled = false
    xAxis.drawLabelsEnabled = false

    let leftAxis:YAxis = chartView.leftAxis;
    leftAxis.labelTextColor = UIColor(red: 1, green: 165/255, blue: 0, alpha: 1)
    leftAxis.axisMaximum = 5.0
    leftAxis.axisMinimum = -5.0
    leftAxis.drawGridLinesEnabled = false
    leftAxis.drawZeroLineEnabled = true
    leftAxis.granularityEnabled = true
    leftAxis.drawLabelsEnabled = false

    let rightAxis:YAxis = chartView.rightAxis
    rightAxis.enabled = false

    let credit: [Double] = [1.0, 4.0, 2.0, 3.0, 3.0, 1.0, 3.0, 0.0, 0.0, 0.0, 0.0]
    let gpa: [Double] = [-1.0, -4.0, -1.5, -1.4, -1.3, -1.0, -3.0, 0.0, 0.0, 0.0, 0.0]
    let chartDescription = ""


    let marker = BalloonMarker(color: UIColor(white: 180/255, alpha: 1.0), font: UIFont.systemFont(ofSize:12.0), textColor: UIColor.white, insets: UIEdgeInsetsMake(8.0, 8.0, 20.0, 8.0))

    marker.chartView = chartView
    marker.minimumSize = CGSize(width:80.0, height:40.0)

    chartView.marker = marker

    self.setLineChart(dataPoints: gpa, chartDescription: chartDescription)
    self.setBarChart(dataPoints: credit)

    self.setChartData()
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}


func setLineChart(dataPoints: [Double], chartDescription: String) {

    let formatter:ChartFormatter = ChartFormatter()
    let xaxis:XAxis = XAxis()

    var dataEntries: [ChartDataEntry] = Array()

    for i in 0..<dataPoints.count {
        let dataEntry = ChartDataEntry(x: Double(i), y: dataPoints[i])
        dataEntries.append(dataEntry)
        formatter.stringForValue(Double(i), axis: xaxis)
    }

    let lineChartDataSet = LineChartDataSet(values: dataEntries, label: "Credit")
    self.lineChartData = LineChartData(dataSet: lineChartDataSet)

    xaxis.valueFormatter = formatter
    chartView.xAxis.valueFormatter = xaxis.valueFormatter

    xaxis.drawGridLinesEnabled = false

    lineChartDataSet.mode = .linear
    lineChartDataSet.drawCirclesEnabled = false
    lineChartDataSet.drawValuesEnabled = false

    lineChartDataSet.colors = [UIColor.brown]

    chartView.descriptionText = chartDescription


}

func setBarChart(dataPoints: [Double]) {
    let formatter:ChartFormatter = ChartFormatter()
    let xaxis:XAxis = XAxis()

    var dataEntries: [BarChartDataEntry] = Array()

    for i in 0..<dataPoints.count {
        let dataEntry = BarChartDataEntry(x: Double(i), y: dataPoints[i])
        dataEntries.append(dataEntry)
        formatter.stringForValue(Double(i), axis: xaxis)
    }
    let barChartDataSet = BarChartDataSet(values: dataEntries, label: "GPA")
    self.barChartData = BarChartData(dataSet: barChartDataSet)


    xaxis.valueFormatter = formatter
    chartView.xAxis.valueFormatter = xaxis.valueFormatter

    xaxis.drawGridLinesEnabled = false

    barChartDataSet.drawValuesEnabled = false
}

func setChartData() {
    let data:CombinedChartData = CombinedChartData()

    data.lineData = self.lineChartData
    data.barData = self.barChartData
    chartView.data = data
    chartView.data?.highlightEnabled = true
    //chartView.autoScaleMinMaxEnabled = true
    //chartView.setNeedsDisplay()
}

@objc func chartValueSelected(chartView: ChartViewBase, entry: ChartDataEntry, dataSetIndex: Int, highlight: Highlight){
    print("###################")
}

@objc func chartValueNothingSelected(chartView: ChartViewBase){
    NSLog("chartValueNothingSelected");
}

}


Solution

  • Chiming in very late here, but the method signature has changed in Swift 3.0 (see this answer), and no longer includes dataSetIndex.

    You should be able to see this firing in the console by changing your function signature (and implementation) to the following:

    func chartValueSelected(chartView: ChartViewBase, entry: ChartDataEntry, highlight: Highlight){
        print("###################")
    }