问题
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