How do I use getData() to plot a LineChart with ObjC PNChart library in Swift?

痞子三分冷 提交于 2019-12-10 21:14:55

问题


I am a newbie programmer and recently started learning Swift.

I am making a project in Swift and my intention is to plot a user-introduced signal function in the same View where the parameters are introduced (using a subView controlled by the class PNLineChart).

The fact is that I installed PNChart library using CocoaPods, using a bridging header for the Objective C headers. The thing is that the way to use the clases and methods in ObjC is "translating" them to Swift syntax. I found that PNChart has a Swift implementation made by the author, but is not available by Pods (if someone knows how to put them into my project it will be helpful too).

Well, the ObjC code to make the plot of an array given by the author in its wiki is the following:

#import "PNChart.h"

//For Line Chart
PNLineChart * lineChart = [[PNLineChart alloc] initWithFrame:CGRectMake(0, 135.0, SCREEN_WIDTH, 200.0)];
[lineChart setXLabels:@[@"SEP 1",@"SEP 2",@"SEP 3",@"SEP 4",@"SEP 5"]];

// Line Chart No.1
NSArray * data01Array = @[@60.1, @160.1, @126.4, @262.2, @186.2];
PNLineChartData *data01 = [PNLineChartData new];
data01.color = PNFreshGreen;
data01.itemCount = lineChart.xLabels.count;
data01.getData = ^(NSUInteger index) {
    CGFloat yValue = [data01Array[index] floatValue];
    return [PNLineChartDataItem dataItemWithY:yValue];
};
// Line Chart No.2
NSArray * data02Array = @[@20.1, @180.1, @26.4, @202.2, @126.2];
PNLineChartData *data02 = [PNLineChartData new];
data02.color = PNTwitterColor;
data02.itemCount = lineChart.xLabels.count;
data02.getData = ^(NSUInteger index) {
    CGFloat yValue = [data02Array[index] floatValue];
    return [PNLineChartDataItem dataItemWithY:yValue];
};

lineChart.chartData = @[data01, data02];
[lineChart strokeChart];

So I tried to convert it to Swift, where:

  • inputSignal : UITextField! -> will be the textField where the user introduces the mathematical function (this is still under development)
  • other IBOutlet -> Parameters to set the function limits and the global chart limits
  • inputSignalLineChart: PNLineChart! -> connection of the subView to the ViewController
  • initSignalExample -> initial array to test the plotting
  • signalObtainedValues -> declaration of the PNLineChartData type

Inside the viewDidLoad() function I am initiating an initial chart to test if it works in the View. The problem comes when I try to use the method getData() that is defined in the PNLineChartData class and I am not really able to translate it to a correct Swift code.

My understanding is that getData has as input an UInteger called index (I think it will select the individual data, but I do not see it declared anywhere :-/) and as output it returns a PNLineChartDataItem(). As I see in the ObjC code, the way to do this is somewhat like PNLineChartDataItem(y: CGFloat) so I suppose that I can do the code as I show you below:

import UIKit


class ViewController: UIViewController, PNChartDelegate{


    @IBOutlet weak var inputSignal: UITextField!

    @IBOutlet weak var initialTimeInputSignal: UITextField!

    @IBOutlet weak var finalTimeInputSignal: UITextField!

    @IBOutlet weak var initialGlobalTime: UITextField!
    @IBOutlet weak var finalGlobalTime: UITextField!

    @IBOutlet weak var inputSignalLineChart: PNLineChart!

    let screenWidth = UIScreen.mainScreen().bounds.size.width
    let screenHeight = UIScreen.mainScreen().bounds.size.height
    let initSignalExample = [0.0, 1.0, 1.0, 1.0, 0.0]
    let signalObtainedValues: PNLineChartData!

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        view.backgroundColor = UIColor.cyanColor()

        inputSignalLineChart.delegate = self
        inputSignalLineChart.frame = CGRectMake(0, 135.0, screenWidth, screenHeight)
        inputSignalLineChart.backgroundColor = UIColor.whiteColor()
        inputSignalLineChart.setXLabels(["0","1","2","3","4"], withWidth: 1)
        //signalObtainedValues.color = UIColor.greenColor()
        //signalObtainedValues.itemCount = UInt(inputSignalLineChart.xLabels.count)

        signalObtainedValues.getData(UInt(index)) = { PNLineChartDataItem(y: CGFloat(initSignalExample[index]))

        }

        //inputSignalLineChart.chartData = [signalObtainedValues]
        inputSignalLineChart.strokeChart()
    }

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


}

Trying and trying I only get the error: Cannot assign to the result of this expression, in the getData() line. So I think this is for the syntax of the code I have made in Swift. Has anyone any idea of how to do this and correctly draw the chart in the subview? Any answer or helpful tip will be appreciated. Thank you!


回答1:


Maybe this can be written in closure like the following:

signalObtainedValues.getData() = {
    index in
    let yValue: CGFloat = initSignalExample[UInt(index)]
    return PNLineChartDataItem(y: yValue)
}



回答2:


I finally got a solution for the problem. The code that works for me is the following:

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.

    view.backgroundColor = UIColor.cyanColor()

    playButton.layer.backgroundColor = UIColor.whiteColor().CGColor
    playButton.layer.cornerRadius = 5

    let initSignalExample = [0.0, 1.0, 2.0, 1.0, 0.0]


    lineChartSubView.frame = CGRectMake(0, 0, screenWidth, screenHeight)
    lineChartSubView.backgroundColor = UIColor.whiteColor()
    lineChartSubView.setXLabels(["0","1","2","3","4"], withWidth: 1)
    lineChartSubView.showCoordinateAxis = true
    lineChartSubView.showLabel = true
    lineChartSubView.delegate = self

    var signalObtainedValues = PNLineChartData()

    signalObtainedValues.color = UIColor.greenColor()
    signalObtainedValues.itemCount = UInt(initSignalExample.count)
    signalObtainedValues.getData = ({(index: UInt) -> PNLineChartDataItem in
        var yValue:CGFloat = CGFloat(initSignalExample[Int(index)])
        var item = PNLineChartDataItem(y: yValue)
        return item
    })

    lineChartSubView.chartData = [signalObtainedValues]
    lineChartSubView.strokeChart()

}

Now the problem is that the graph does not fit in the subview, but maybe I will open another question since the original post is solved. Thank you very much!




回答3:


How about this?

signalObtainedValues.getData = ({(index: Int) -> PNLineChartDataItem in
var yValue:CGFloat = signalObtainedValues[index]
var item = PNLineChartDataItem(y: yValue)
return item})



回答4:


I think the problem is that you forgot to add subview, the graph did not show.

lineChartSubView.chartData = [signalObtainedValues]
lineChartSubView.strokeChart()

self.view.addSubview(lineChartSubView)


来源:https://stackoverflow.com/questions/29033812/how-do-i-use-getdata-to-plot-a-linechart-with-objc-pnchart-library-in-swift

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!