How do I add values to my graph in core plot swift? - ios

let graph = CPTXYGraph(frame: hostview.bounds)
hostview.hostedGraph = graph
graph.paddingLeft = 0.0
graph.paddingTop = 0.0
graph.paddingRight = 0.0
graph.paddingBottom = 0.0
graph.axisSet = nil
That is my code so far. I would like to plot a function. f(x) = x^2 + 10 should be the function value in this case. I want the x-axis and the y-axis to start at 0 and end at 100.
Can someone help me with implementing this f(x)?

Your initialization logic of the graph should look like below. Use this in viewDidLoad
func initPlot() {
let graph = CPTXYGraph(frame: hostView.bounds)
graph.plotAreaFrame?.masksToBorder = false
hostView.hostedGraph = graph
graph.backgroundColor = UIColor.white.cgColor
graph.paddingBottom = 40.0
graph.paddingLeft = 40.0
graph.paddingTop = 40.0
graph.paddingRight = 40.0
//configure title
let title = "f(x) = x*x + 10"
graph.title = title
//configure axes
let axisSet = graph.axisSet as! CPTXYAxisSet
if let x = axisSet.xAxis {
x.majorIntervalLength = 20
x.minorTicksPerInterval = 1
}
if let y = axisSet.yAxis {
y.majorIntervalLength = 5
y.minorTicksPerInterval = 5
}
let xMin = 0.0
let xMax = 100.0
let yMin = 0.0
let yMax = 100.0
guard let plotSpace = graph.defaultPlotSpace as? CPTXYPlotSpace else { return }
plotSpace.xRange = CPTPlotRange(locationDecimal: CPTDecimalFromDouble(xMin), lengthDecimal: CPTDecimalFromDouble(xMax - xMin))
plotSpace.yRange = CPTPlotRange(locationDecimal: CPTDecimalFromDouble(yMin), lengthDecimal: CPTDecimalFromDouble(yMax - yMin))
//create the plot
plot = CPTScatterPlot()
plot.dataSource = self
graph.add(plot, to: graph.defaultPlotSpace)
}
Additionally you need to implement CPTScatterPlotDataSource, where you define the numberOfRecords and respective X and Y values
extension ViewController: CPTScatterPlotDataSource {
func numberOfRecords(for plot: CPTPlot) -> UInt {
return 100
}
func number(for plot: CPTPlot, field: UInt, record: UInt) -> Any? {
switch CPTScatterPlotField(rawValue: Int(field))! {
case .X:
return record
case .Y:
return (record * record) + 10
default:
return 0
}
}
}

Related

How do I draw yaxis min value as different color on certain limit?

I am using iOS Charts to draw linechart but unable to draw the same graph as shown below in the image. I tried by setting leftAxis.axisMinimum = minValue but it also not working. If the given value is minimum on certain limit it should show in red color as shown in attached image.
func setLineChartWithDateFormat(graphPoints: [GraphPoints], linePosition: CGFloat, minValue: Double = 0, fillColor: UIColor = UIColor(red: 158.0/255.0, green: 188.0/255.0, blue: 136.0/255.0, alpha: 1)) {
var referenceTimeInterval: TimeInterval = 0
if let minTimeInterval = (graphPoints.map { ($0.getDateFromDateTime?.timeIntervalSince1970 ?? 0) }).min() {
referenceTimeInterval = minTimeInterval
}
let formatter = DateFormatter()
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.dateFormat = "MMM dd"
let xValuesNumberFormatter = ChartXAxisWithFormatter(referenceTimeInterval: referenceTimeInterval, dateFormatter: formatter)
// Define chart entries
var entries = [ChartDataEntry]()
var xAxisValues = [CGFloat]()
for object in graphPoints {
let timeInterval = object.getDateFromDateTime?.timeIntervalSince1970 ?? 0
let xValue = (timeInterval - referenceTimeInterval) / (3600 * 24)
xAxisValues.append(CGFloat(xValue))
let yValue = object.price ?? 0
let entry = ChartDataEntry(x: xValue, y: yValue)
entry.setValue(object.getDateFromDateTime, forKey: "data")
entries.append(entry)
}
var minValue = xAxisValues.min()
let chartDataSet = LineChartDataSet(entries: entries, label: "BPM")
chartDataSet.fillColor = fillColor
/// Data object that encapsulates all data associated with a LineChart.
let chartData = LineChartData()
chartData.addDataSet(chartDataSet)
chartData.setDrawValues(false)
chartDataSet.drawCirclesEnabled = false
chartDataSet.mode = .linear
chartDataSet.colors = [.white]
chartDataSet.fillFormatter = LineChartFillFormatter(value: minValue ?? 0)
// let gradientColors = [gradientColor1.cgColor, gradientColor2.cgColor] as CFArray
// let colorLocations: [CGFloat] = [0.7,0.0]
// guard CGGradient.init(colorsSpace: CGColorSpaceCreateDeviceRGB(), colors: gradientColors, locations: colorLocations) != nil else {
// print("Gradient Error")
// return
// }
chartDataSet.drawFilledEnabled = true
chartDataSet.fillAlpha = 1
chartDataSet.setDrawHighlightIndicators(true)
chartDataSet.drawHorizontalHighlightIndicatorEnabled = false
// lineChart.leftAxis.axisMinimum = minValue
///x axis for chart view
let xAxis: XAxis = self.lineChart.xAxis
xAxis.labelPosition = .bottomInside
xAxis.drawGridLinesEnabled = true //true, if want x Axis grid lines
xAxis.valueFormatter = xValuesNumberFormatter
xAxis.gridColor = gridColor
xAxis.axisLineColor = gridColor
xAxis.labelFont = BSFonts.getFontWithSize(fontType: .iBMPlexSansCond, fontSize: BSFontSize.small)
xAxis.labelTextColor = axisTextColor
xAxis.labelPosition = .bottom
xAxis.spaceMin = 0.5
xAxis.drawAxisLineEnabled = false
xAxis.drawLimitLinesBehindDataEnabled = true
xAxis.granularityEnabled = true
// xAxis.granularity = 2
xAxis.labelWidth = UIDevice.current.isIPad ? 30 : 20
// xAxis.labelCount = 4
///right axis for chart view
let rightAxis: YAxis = lineChart.rightAxis
rightAxis.enabled = false
///y axis of chart view
let leftAxis: YAxis = lineChart.leftAxis
leftAxis.labelPosition = .insideChart
leftAxis.drawGridLinesEnabled = true //true, if want y axis grid lines
leftAxis.drawLabelsEnabled = true
leftAxis.gridColor = gridColor
leftAxis.axisLineColor = gridColor
leftAxis.labelFont = BSFonts.getFontWithSize(fontType: .iBMPlexSansCond, fontSize: BSFontSize.small)
leftAxis.labelTextColor = axisTextColor
leftAxis.labelPosition = .outsideChart
//leftAxis.spaceBottom = 0.3
leftAxis.drawAxisLineEnabled = false
leftAxis.labelCount = 4
/// The data for the chart
lineChart.data = chartData
lineChart.doubleTapToZoomEnabled = false
lineChart.data?.highlightEnabled = true
}

How to make a line graph using CorePlot framework and swift 3?

I can't understand how to make a line plot with CorePlot 2.2 with Swift 3 (Xcode 8, iOS 10).
Can someone explain how to do it?
Particularly, I don't understand how the last function numbers (line 97-103(last lines)) works:
import UIKit
import CorePlot
class dottedLine: UIViewController {
#IBOutlet var hostView: CPTGraphHostingView!
var plot: CPTScatterPlot!
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
initPlot()
}
let xValues: [NSNumber] = [1,2,3,4]
let yValues: [NSNumber] = [1,5,4,3]
func initPlot() {
configureHostView()
configureGraph()
configureChart()
configureAxes()
}
func configureHostView() {
hostView.allowPinchScaling = false
}
func configureGraph() {
// 1 - Create the graph
let graph = CPTXYGraph(frame: hostView.bounds)
graph.plotAreaFrame?.masksToBorder = false
hostView.hostedGraph = graph
// 2 - Configure the graph
//graph.apply(CPTTheme(named: CPTThemeName.plainWhiteTheme))
//graph.fill = CPTFill(color: CPTColor.clear())
graph.paddingBottom = 30.0
graph.paddingLeft = 30.0
graph.paddingTop = 0.0
graph.paddingRight = 0.0
// 3 - Set up styles
let titleStyle = CPTMutableTextStyle()
titleStyle.color = CPTColor.black()
titleStyle.fontName = "HelveticaNeue-Bold"
titleStyle.fontSize = 16.0
titleStyle.textAlignment = .center
graph.titleTextStyle = titleStyle
let title = "Just title"
graph.title = title
graph.titlePlotAreaFrameAnchor = .top
graph.titleDisplacement = CGPoint(x: 0.0, y: -16.0)
// 4 - Set up plot space
let xMin = 0.0
let xMax = 5.0
let yMin = 0.0
let yMax = 15.0
guard let plotSpace = graph.defaultPlotSpace as? CPTXYPlotSpace else { return }
plotSpace.xRange = CPTPlotRange(locationDecimal: CPTDecimalFromDouble(xMin), lengthDecimal: CPTDecimalFromDouble(xMax - xMin))
plotSpace.yRange = CPTPlotRange(locationDecimal: CPTDecimalFromDouble(yMin), lengthDecimal: CPTDecimalFromDouble(yMax - yMin))
}
func configureChart() {
// 1 - Set up the plot
plot = CPTScatterPlot()
// 2 - Set up style
let plotLineStile = CPTMutableLineStyle()
plotLineStile.lineWidth = 1
plotLineStile.lineColor = CPTColor.black()
plot.dataLineStyle = plotLineStile
// 3- Add plots to graph
guard let graph = hostView.hostedGraph else { return }
plot.dataSource = self
plot.delegate = self
graph.add(plot, to: graph.defaultPlotSpace)
}
func configureAxes() {
}
}
extension dottedLine: CPTScatterPlotDataSource, CPTScatterPlotDelegate {
func numberOfRecords(for plot: CPTPlot) -> UInt {
// number of points
return UInt(xValues.count)
}
func scatterPlot(_ plot: CPTScatterPlot, plotSymbolWasSelectedAtRecord idx: UInt, with event: UIEvent) {
}
/* func numbers(for plot: CPTPlot, field fieldEnum: UInt, recordIndexRange indexRange: NSRange) -> [Any]? {
print("xxxxxxx")
switch CPTScatterPlotField(rawValue: Int(fieldEnum))! {
case .X:
return xValues[index] as NSNumber
case .Y:
return yValues[indexRange] as NSNumber
}
} */
/* func symbols(for plot: CPTScatterPlot, recordIndexRange indexRange: NSRange) -> [CPTPlotSymbol]? {
return xValues
} */
func number(for plot: CPTPlot, field: UInt, record: UInt) -> Any? {
switch CPTScatterPlotField(rawValue: Int(field))! {
case .X:
return 2 as NSNumber
case .Y:
return 3 as NSNumber
}
}
}
For a scatter plot, this method will be called once for the x-value and once for the y-value at each index.
Here is that method from the DatePlot example app:
func number(for plot: CPTPlot, field: UInt, record: UInt) -> Any?
{
switch CPTScatterPlotField(rawValue: Int(field))! {
case .X:
return (oneDay * Double(record)) as NSNumber
case .Y:
return self.plotData[Int(record)] as NSNumber
}
}

Setting Up CorePlot Crosshair in Swift

I am attempting to create a crosshair (vertical line) for my graph in Swift. I have looked over the various Objective-C examples of how to do this, and have mimicked them in the code below:
class viewController: UIViewController {
#IBOutlet weak var graphView: CPTGraphHostingView!
var plot1: CPTScatterPlot!
var plot2: CPTScatterPlot!
var plot3: CPTScatterPlot!
var plotDataSource1: CPTFunctionDataSource?
var plotDataSource2: CPTFunctionDataSource?
var plotDataSource3: CPTFunctionDataSource?
var markerAnnotation: CPTPlotSpaceAnnotation?
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
initPlot()
}
func initPlot() {
configureHostView()
configureGraph()
configureChart()
configureAxes()
}
func configureHostView() {
graphView.allowPinchScaling = true
print("host con called")
}
func configureGraph() {
// 1 - Create the graph
let graph = CPTXYGraph(frame: graphView.bounds)
graph.plotAreaFrame?.masksToBorder = true
graphView.hostedGraph = graph
// 2 - Configure the graph
graph.applyTheme(CPTTheme(named: kCPTPlainWhiteTheme))
graph.fill = CPTFill(color: CPTColor.clearColor())
graph.paddingBottom = 0.0
graph.paddingLeft = 0.0
graph.paddingTop = 0.0
graph.paddingRight = 0.0
// 3 - Set up styles
let titleStyle = CPTMutableTextStyle()
titleStyle.color = CPTColor.blackColor()
titleStyle.fontName = "HelveticaNeue-Bold"
titleStyle.fontSize = 16.0
titleStyle.textAlignment = .Center
graph.titleTextStyle = titleStyle
// 4 - Set up plot space
let xMin = -10.0
let xMax = 10.0
let yMin = -10.0
let yMax = 10.0
guard let plotSpace = graph.defaultPlotSpace as? CPTXYPlotSpace else { return }
plotSpace.allowsUserInteraction = true
plotSpace.xRange = CPTPlotRange(locationDecimal: CPTDecimalFromDouble(xMin), lengthDecimal: CPTDecimalFromDouble(xMax - xMin))
plotSpace.yRange = CPTPlotRange(locationDecimal: CPTDecimalFromDouble(yMin), lengthDecimal: CPTDecimalFromDouble(yMax - yMin))
print("graph con called")
}
func configureChart() {
// 1 - Set up the three plots
plot1 = CPTScatterPlot()
plot2 = CPTScatterPlot()
plot3 = CPTScatterPlot()
// 2 - Set up line style
let lineStyle1 = CPTMutableLineStyle()
lineStyle1.lineColor = CPTColor.blueColor()
lineStyle1.lineWidth = 0.5
let lineStyle2 = CPTMutableLineStyle()
lineStyle2.lineColor = CPTColor.redColor()
lineStyle2.lineWidth = 0.5
let lineStyle3 = CPTMutableLineStyle()
lineStyle3.lineColor = CPTColor.greenColor()
lineStyle3.lineWidth = 0.5
// 3 - Add plots to graph
guard let graph = graphView.hostedGraph else { return }
plot1.delegate = self
plot2.delegate = self
plot3.delegate = self
//let function: CPTDataSourceFunction? = cos
let block1 = {(x: Double) -> Double in
return sin(x)
}
let block2 = {(x: Double) -> Double in
return 1/x
}
let block3 = {(x: Double) -> Double in
return log(x)
}
//if (block != nil) {
plotDataSource1 = CPTFunctionDataSource(forPlot: plot1, withBlock: block1)
plot1.dataSource = plotDataSource1
//}
plotDataSource2 = CPTFunctionDataSource(forPlot: plot2, withBlock: block2)
plot2.dataSource = plotDataSource2
plotDataSource3 = CPTFunctionDataSource(forPlot: plot3, withBlock: block3)
plot3.dataSource = plotDataSource3
plot1.dataLineStyle = lineStyle1
plot2.dataLineStyle = lineStyle2
plot3.dataLineStyle = lineStyle3
graph.addPlot(plot1, toPlotSpace: graph.defaultPlotSpace)
graph.addPlot(plot2, toPlotSpace: graph.defaultPlotSpace)
graph.addPlot(plot3, toPlotSpace: graph.defaultPlotSpace)
print("chart con called")
}
func configureAxes() {
// 1 - Configure styles
let axisLineStyle = CPTMutableLineStyle()
axisLineStyle.lineWidth = 2.0
axisLineStyle.lineColor = CPTColor.blackColor()
let majorGridLineStyle: CPTMutableLineStyle = CPTMutableLineStyle()
majorGridLineStyle.lineWidth = 0.75
majorGridLineStyle.lineColor = CPTColor.grayColor()
let minorGridLineStyle: CPTMutableLineStyle = CPTMutableLineStyle()
minorGridLineStyle.lineWidth = 0.25
minorGridLineStyle.lineColor = CPTColor.whiteColor()
guard let axisSet = graphView.hostedGraph?.axisSet as? CPTXYAxisSet else { return }
// 3 - Configure the x-axis
let axisStyle = CPTMutableTextStyle()
axisStyle.fontSize = 6.0
//
let crosshair = CPTXYAxis()
crosshair.hidden = false
crosshair.coordinate = CPTCoordinate.Y
crosshair.plotSpace = graphView.hostedGraph?.defaultPlotSpace
crosshair.axisConstraints = CPTConstraints(lowerOffset: 10.0)
crosshair.labelingPolicy = CPTAxisLabelingPolicy.None
crosshair.separateLayers = true
crosshair.preferredNumberOfMajorTicks = 6
crosshair.minorTicksPerInterval = 0
let cStyle: CPTMutableLineStyle = CPTMutableLineStyle()
cStyle.lineWidth = 4.0
cStyle.lineColor = CPTColor.orangeColor()
crosshair.axisLineStyle = cStyle
crosshair.majorTickLineStyle = nil
//
let x: CPTXYAxis = axisSet.xAxis!
x.labelingPolicy = .Automatic
x.title = ""
x.labelTextStyle = axisStyle
let y: CPTXYAxis = axisSet.yAxis!
y.labelingPolicy = .Automatic
y.title = ""
y.labelTextStyle = axisStyle
axisSet.axes = [x, y, crosshair]
let hitAnnotationTextStyle: CPTMutableTextStyle = CPTMutableTextStyle()
hitAnnotationTextStyle.color = CPTColor.blackColor()
hitAnnotationTextStyle.fontName = "Helvetica-Bold"
hitAnnotationTextStyle.fontSize = 6
let textLayer: CPTTextLayer = CPTTextLayer(text: "Annotation", style: hitAnnotationTextStyle)
textLayer.cornerRadius = 3.0
textLayer.paddingLeft = 2.0
textLayer.paddingTop = 2.0
textLayer.paddingRight = 2.0
textLayer.paddingBottom = 2.0
textLayer.hidden = false
let graph = CPTXYGraph(frame: graphView.bounds)
let plotSpace = graph.defaultPlotSpace as? CPTXYPlotSpace
let annotation: CPTPlotSpaceAnnotation = CPTPlotSpaceAnnotation(plotSpace: plotSpace!, anchorPlotPoint: [0, 0])
annotation.contentLayer = textLayer
graph.addAnnotation(annotation)
self.markerAnnotation = annotation
print("axes con called")
}
}
extension viewController: CPTPlotSpaceDelegate, CPTPlotDataSource, CPTScatterPlotDelegate {
func numberOfRecordsForPlot(plot: CPTPlot) -> UInt {
print("1")
return (self.plotDataSource1?.dataPlot.cachedDataCount)!
}
func numbersForPlot(plot: CPTPlot, field fieldEnum: UInt, recordIndex index: UInt) -> AnyObject {
print("2")
return (self.plotDataSource1?.dataPlot.cachedDoubleForField(UInt(fieldEnum), recordIndex: UInt(index)))!
}
func plotSpace(space: CPTPlotSpace, willDisplaceBy displacement: CGPoint) -> CGPoint {
print("3")
return CGPointMake(0.0, 0.0)
}
func plotSpace(space: CPTPlotSpace, willChangePlotRangeTo newRange: CPTPlotRange, forCoordinate coordinate: CPTCoordinate) -> CPTPlotRange? {
print("4")
var updatedRange: CPTPlotRange? = nil
let xySpace: CPTXYPlotSpace = (space as! CPTXYPlotSpace)
switch coordinate {
case CPTCoordinate.X:
updatedRange = xySpace.xRange
case CPTCoordinate.Y:
updatedRange = xySpace.yRange
default:
break
}
return updatedRange!
}
func plotSpace(space: CPTPlotSpace, shouldHandlePointingDeviceDownEvent event: UIEvent, atPoint point: CGPoint) -> Bool {
print("5")
let xySpace: CPTXYPlotSpace = (space as! CPTXYPlotSpace)
let graphy = xySpace.graph!
let crosshair = graphy.axisSet!.axes![2] as? CPTXYAxis
var plotPoint = space.plotPointForEvent(event)
let annotation: CPTPlotSpaceAnnotation = self.markerAnnotation!
let textLayer: CPTTextLayer = (annotation.contentLayer as! CPTTextLayer)
var xNumber = plotPoint![CPTCoordinate.X.rawValue]
var yNumber = plotPoint![CPTCoordinate.Y.rawValue]
if xySpace.xRange.containsNumber(xNumber) {
let x: Int = Int(Double(xNumber))
let y: Int = Int(Double(yNumber))
xNumber = x
yNumber = y
let xValue: String = (graphView.hostedGraph!.axisSet?.axes?[0].labelFormatter!.stringForObjectValue(xNumber)!)!
let yValue: String = (graphView.hostedGraph!.axisSet?.axes?[1].labelFormatter!.stringForObjectValue(yNumber)!)!
textLayer.text = "\(xValue), \(yValue)"
textLayer.hidden = false
annotation.anchorPlotPoint = [xNumber, yNumber]
crosshair!.orthogonalPosition = xNumber
crosshair!.hidden = false
} else {
textLayer.hidden = true
crosshair!.hidden = true
}
return false
}
func plotSpace(space: CPTPlotSpace, shouldHandlePointingDeviceDraggedEvent event: UIEvent, atPoint point: CGPoint) -> Bool {
print("6")
return self.plotSpace(space, shouldHandlePointingDeviceDraggedEvent: event, atPoint: point)
}
func plotSpace(space: CPTPlotSpace, shouldHandlePointingDeviceUpEvent event: UIEvent, atPoint point: CGPoint) -> Bool {
print("7")
return false
}
}
The data I am trying to index is created from a CPTFunctionDataSource, so what I am trying to do might be more complicated. Any assistance is appreciated...

how to pass time as xAxis data value in method numberForPlot using core plot?

I need to create graph which is "Heart rate vs time". in xAxis I am showing time which is in format of "HH:mm:ss" and at y Axis its decimal value. My code is as below :
data source for graph:
var graphData:[(String,Double)] = []
let data = ("17:56:35",Double(65))
let data1 = ("18:04:13",Double(95))
let data2 = ("18:8:35",Double(25))
self.graphData.append(data)
self.graphData.append(data1)
self.graphData.append(data2)
Set up graph and plot data code:
func setGraph() {
let tts = CPTMutableTextStyle()
tts.fontSize = 75.0
tts.color = CPTColor(CGColor: UIColor.blackColor().CGColor)
tts.fontName = "HelveticaNeue-Bold"
self.graph.titleTextStyle = tts
self.graph.title = "Heart Rate vs Time"
self.graph.applyTheme(CPTTheme(named:kCPTPlainWhiteTheme))
let plotSpace = graph.defaultPlotSpace as! CPTXYPlotSpace!
plotSpace.allowsUserInteraction = false
let xRange = plotSpace.xRange.mutableCopy() as! CPTMutablePlotRange
xRange.locationDouble = Double(0)
xRange.lengthDouble = Double(1000)
plotSpace.xRange = xRange
let yRange = plotSpace.yRange.mutableCopy() as! CPTMutablePlotRange
yRange.locationDouble = Double(0)
yRange.lengthDouble = Double(210)
plotSpace.yRange = yRange
graph.addPlotSpace(plotSpace)
graph.plotAreaFrame!.paddingTop = 0
graph.plotAreaFrame!.paddingRight = 0
graph.plotAreaFrame!.paddingBottom = graphOffset
graph.plotAreaFrame!.paddingLeft = graphOffset
graph.plotAreaFrame!.masksToBorder = false
// Grid line styles
let majorLineStyle = CPTMutableLineStyle()
majorLineStyle.lineWidth = 0.75
majorLineStyle.lineColor = CPTColor.redColor()
let minorLineStyle = CPTMutableLineStyle()
minorLineStyle.lineWidth = 0.25
minorLineStyle.lineColor = CPTColor.blackColor()
//Axis Line colors
let axisLineStyle = CPTMutableLineStyle()
axisLineStyle.lineWidth = 2.0
axisLineStyle.lineColor = CPTColor.blackColor()
//Axis Label colors
let labelTextStyle = CPTMutableTextStyle()
labelTextStyle.textAlignment = CPTTextAlignment.Left
labelTextStyle.color = CPTColor.blackColor()
//Axis title color
let titleTextStyle = CPTMutableTextStyle()
titleTextStyle.textAlignment = CPTTextAlignment.Left
titleTextStyle.color = CPTColor.blackColor()
titleTextStyle.fontSize = 15
let dataSourceLinePlot = CPTScatterPlot()
let lineStyle = CPTMutableLineStyle()
lineStyle.lineWidth = 3.0
lineStyle.lineColor = CPTColor.blueColor()
dataSourceLinePlot.dataLineStyle = lineStyle
dataSourceLinePlot.identifier = kPlotIdentifier
// dataSourceLinePlot.dataSource = self
let xts = CPTMutableTextStyle()
xts.color = CPTColor(componentRed: 255.0, green: 255.0, blue: 255.0, alpha: 1.0)
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "HH:mm:ss"
let timeformatter = CPTTimeFormatter(dateFormatter: dateFormatter)
timeformatter.referenceDate = NSDate()
let axisSet = graph.axisSet as! CPTXYAxisSet!
let xAxis = axisSet.xAxis as CPTXYAxis!
xAxis.axisTitle = CPTAxisTitle(text: "Elapsed Time", textStyle: xts)
xAxis.labelFormatter = timeformatter
xAxis.majorGridLineStyle = majorLineStyle
xAxis.minorGridLineStyle = minorLineStyle
xAxis.majorIntervalLength = NSNumber(double: 60.0)
let yAxis = axisSet.yAxis as CPTXYAxis!
yAxis.axisTitle = CPTAxisTitle(text: "Heart Rate", textStyle: xts)
let axisFormatter = NSNumberFormatter()
axisFormatter.maximumFractionDigits = 0
axisFormatter.minimumIntegerDigits = 1
yAxis.labelFormatter = axisFormatter
yAxis.titleOffset = 35.0
yAxis.majorIntervalLength = 20
yAxis.majorGridLineStyle = majorLineStyle
yAxis.minorGridLineStyle = minorLineStyle
graph.addPlot(dataSourceLinePlot)
self.IBviewGraph.hostedGraph = self.graph
}
To plot data :
func setGraphData() {
dispatch_sync(dispatch_get_main_queue(), {
let plot = CPTScatterPlot()
plot.dataSource = self
let actualPlotStyle = plot.dataLineStyle!.mutableCopy() as! CPTMutableLineStyle
actualPlotStyle.lineWidth = 2.0
actualPlotStyle.lineColor = CPTColor(CGColor: (UIColor.yellowColor().CGColor))
plot.dataLineStyle = actualPlotStyle
plot.interpolation = .Linear
self.graph.addPlot(plot)
})
}
Data source methods
func numberOfRecordsForPlot(plot: CPTPlot) -> UInt {
return 3
}
func numberForPlot(plot: CPTPlot, field: UInt, recordIndex: UInt) -> AnyObject?{
var num = NSNumber()
let index = Int(recordIndex)
switch field {
case 0://xaxis
return graphData[index].0
case 1://yaxis
return graphData[index].1
default:
break
}
print("coordintes = ",num)
return num
}
My graph is drown but only yAxis points are correct , its not considering xAxis value and so because of that points are at wrong position in graph. I think the value I am passing in method numberForPlot for xAxis is wrong , but don't know how to pass it. Give me some solution.
The x-values in the graphData array are strings. Core Plot expects the datasource to return a numeric value for each index. It's reading the hour from the time string and using that for the x-value.
The x-axis is configured to display numbers in the range 0 to 1,000. Therefore, you need to convert the time data to a number in that range. Keep track of the reference date used to format the axis labels (i.e., store it in an instance variable) and use that to convert the time data to an offset in seconds from the reference date.

Graph plot reference point is changing

I have a weird issue. I have some data on graph and when new data arrives I am inserting that into graph. But issue is new data plotting is starting from first point of already drawn plot not from last point of plot. The console prints the correct point but the plotting starts from first point of already drawn plot not from last point of already drawn plot. My code for graph set up is here :Code for graph set up and Code for Axis animation
code :
func setGraph() {
let tts = CPTMutableTextStyle()
tts.fontSize = 75.0
tts.color = CPTColor(CGColor: UIColor.blackColor().CGColor)
tts.fontName = "HelveticaNeue-Bold"
self.graph.titleTextStyle = tts
self.graph.title = "Heart Rate vs Time"
self.graph.applyTheme(CPTTheme(named:kCPTPlainWhiteTheme))
let plotSpace = graph.defaultPlotSpace as! CPTXYPlotSpace!
plotSpace.allowsUserInteraction = false
let xRange = plotSpace.xRange.mutableCopy() as! CPTMutablePlotRange
xRange.locationDouble = Double(0)
xRange.lengthDouble = Double(kMaxDataPoints)
plotSpace.xRange = xRange
let yRange = plotSpace.yRange.mutableCopy() as! CPTMutablePlotRange
yRange.locationDouble = Double(0)
yRange.lengthDouble = Double(210)
plotSpace.yRange = yRange
graph.addPlotSpace(plotSpace)
graph.plotAreaFrame!.paddingTop = 0
graph.plotAreaFrame!.paddingRight = 0
graph.plotAreaFrame!.paddingBottom = graphOffset
graph.plotAreaFrame!.paddingLeft = graphOffset
graph.plotAreaFrame!.masksToBorder = false
// Grid line styles
let majorLineStyle = CPTMutableLineStyle()
majorLineStyle.lineWidth = 0.75
majorLineStyle.lineColor = CPTColor.redColor()
let minorLineStyle = CPTMutableLineStyle()
minorLineStyle.lineWidth = 0.25
minorLineStyle.lineColor = CPTColor.blackColor()
//Axis Line colors
let axisLineStyle = CPTMutableLineStyle()
axisLineStyle.lineWidth = 2.0
axisLineStyle.lineColor = CPTColor.blackColor()
//Axis Label colors
let labelTextStyle = CPTMutableTextStyle()
labelTextStyle.textAlignment = CPTTextAlignment.Left
labelTextStyle.color = CPTColor.blackColor()
//Axis title color
let titleTextStyle = CPTMutableTextStyle()
titleTextStyle.textAlignment = CPTTextAlignment.Left
titleTextStyle.color = CPTColor.blackColor()
titleTextStyle.fontSize = 15
let dataSourceLinePlot = CPTScatterPlot()
let lineStyle = CPTMutableLineStyle()
lineStyle.lineWidth = 3.0
lineStyle.lineColor = CPTColor.blueColor()
dataSourceLinePlot.dataLineStyle = lineStyle
dataSourceLinePlot.identifier = kPlotIdentifier
// dataSourceLinePlot.dataSource = self
let xts = CPTMutableTextStyle()
xts.color = CPTColor(componentRed: 255.0, green: 255.0, blue: 255.0, alpha: 1.0)
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "HH:mm:ss"
let timeformatter = CPTTimeFormatter(dateFormatter: dateFormatter)
timeformatter.referenceDate = NSDate().dateByAddingTimeInterval(startTimeInterval)
currentdate = timeformatter.referenceDate
let axisSet = graph.axisSet as! CPTXYAxisSet!
let xAxis = axisSet.xAxis as CPTXYAxis!
xAxis.axisTitle = CPTAxisTitle(text: "Elapsed Time", textStyle: xts)
xAxis.labelFormatter = timeformatter
xAxis.majorGridLineStyle = majorLineStyle
xAxis.minorGridLineStyle = minorLineStyle
xAxis.majorIntervalLength = NSNumber(double: 30.0)
let yAxis = axisSet.yAxis as CPTXYAxis!
yAxis.axisTitle = CPTAxisTitle(text: "Heart Rate", textStyle: xts)
let axisFormatter = NSNumberFormatter()
axisFormatter.maximumFractionDigits = 0
axisFormatter.minimumIntegerDigits = 1
yAxis.labelFormatter = axisFormatter
yAxis.titleOffset = 35.0
yAxis.majorIntervalLength = 20
yAxis.majorGridLineStyle = majorLineStyle
yAxis.minorGridLineStyle = minorLineStyle
yAxis.axisConstraints = CPTConstraints(lowerOffset: 0.0)
graph.addPlot(dataSourceLinePlot)
self.IBviewGraph.hostedGraph = self.graph
setGraphData()
}
func setGraphData()
{
self.plot.dataSource = self
let actualPlotStyle = self.plot.dataLineStyle!.mutableCopy() as! CPTMutableLineStyle
actualPlotStyle.lineWidth = 2.0
actualPlotStyle.lineColor = CPTColor(CGColor: (UIColor.blueColor().CGColor))
self.plot.dataLineStyle = actualPlotStyle
self.plot.interpolation = .Curved
self.graph.addPlot(self.plot)
}
Now when i receive new data :
graphData.removeAtIndex(0)
plot.deleteDataInIndexRange(NSMakeRange(0, 1))
let location = currentIndex
let oldRange = CPTPlotRange(location: location , length: kMaxDataPoints)
let newRange = CPTPlotRange(location: location + 30, length: kMaxDataPoints)
CPTAnimation.animate(plotSpace, property: "xRange", fromPlotRange: oldRange, toPlotRange: newRange, duration: CGFloat(1.0 / kFrameRate))
graphData.append((newTime,data.1))
plot.insertDataAtIndex(UInt(graphData.count - 1), numberOfRecords: 1)

Resources