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

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
}
}

Related

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

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
}
}
}

How can I show first value and last value in line Chart

I'm using charts library and i'm trying to add first value and last value on line chart graph.Please let me know how can I achieve it. I have tried customising drawValue method in linechartrenderer but didn't worked.
Here is my code
var months = ["Dec 15", "Jun 16", "Dec 16", "Jun 17", "Dec 17", "Jun 18"]
var unitsSold = [50.0, 25.0, 50.0, 75.0, 100.0, 75.0]
Viewdidload:
setChart(dataPoints: months, values: unitsSold)
Method:
func setChart(dataPoints: [String], values: [Double]) {
var dataEntries: [ChartDataEntry] = []
for i in 0..<dataPoints.count {
let dataEntry = ChartDataEntry(x: Double(i), y: values[i], data: dataPoints[i] as AnyObject)
dataEntries.append(dataEntry)
}
let chartDataSet = LineChartDataSet(values: dataEntries, label: nil)
chartDataSet.setColor(UIColor(red: 53/255, green: 85/255, blue: 123/255, alpha: 1))
chartDataSet.circleRadius = 5
chartDataSet.circleHoleRadius = 2
chartDataSet.drawValuesEnabled = false
chartDataSet.drawCirclesEnabled = false
let chartData = LineChartData(dataSets: [chartDataSet])
defaultChartView.data = chartData
defaultChartView.xAxis.valueFormatter = IndexAxisValueFormatter(values: months)
defaultChartView.xAxis.labelPosition = .bottom
defaultChartView.xAxis.drawGridLinesEnabled = false
//lineChartView.xAxis.avoidFirstLastClippingEnabled = true
defaultChartView.xAxis.axisMinimum = 0
defaultChartView.xAxis.granularity = 1
defaultChartView.rightAxis.drawAxisLineEnabled = false
defaultChartView.rightAxis.drawLabelsEnabled = false
defaultChartView.rightAxis.enabled = false
defaultChartView.leftAxis.drawAxisLineEnabled = false
defaultChartView.leftAxis.axisMinimum = 0.0
defaultChartView.leftAxis.drawLabelsEnabled = false
//lineChartView.leftAxis.drawGridLinesEnabled = false
//lineChartView.leftAxis.granularityEnabled = false
defaultChartView.pinchZoomEnabled = true
defaultChartView.doubleTapToZoomEnabled = true
defaultChartView.legend.enabled = false
defaultChartView.chartDescription?.text = " "
}
viewDidLoad:
guard let firstMonth = months.first, let lastMonth = months.last else {
return
}
let myMonths = [firstMonth, lastMonth]
guard let firstValue = unitsSold.first, let lastValue = unitsSold.last else {
return
}
let myValues = [firstValue, lastValue]
setChart(dataPoints: myMonths, values: myValues)
Solution is go to linechartrenderer file and replace drawValues method
open override func drawValues(context: CGContext)
{
guard
let dataProvider = dataProvider,
let lineData = dataProvider.lineData
else { return }
if isDrawingValuesAllowed(dataProvider: dataProvider)
{
var dataSets = lineData.dataSets
let phaseY = animator.phaseY
var pt = CGPoint()
for i in 0 ..< dataSets.count
{
guard let dataSet = dataSets[i] as? ILineChartDataSet else { continue }
if !shouldDrawValues(forDataSet: dataSet)
{
continue
}
let valueFont = dataSet.valueFont
guard let formatter = dataSet.valueFormatter else { continue }
let trans = dataProvider.getTransformer(forAxis: dataSet.axisDependency)
let valueToPixelMatrix = trans.valueToPixelMatrix
let iconsOffset = dataSet.iconsOffset
// make sure the values do not interfear with the circles
var valOffset = Int(dataSet.circleRadius * 1.75)
if !dataSet.isDrawCirclesEnabled
{
valOffset = valOffset / 2
}
_xBounds.set(chart: dataProvider, dataSet: dataSet, animator: animator)
for j in stride(from: _xBounds.min, through: min(_xBounds.min + _xBounds.range, _xBounds.max), by: 1)
{
guard let e = dataSet.entryForIndex(j) else { break }
if(j == 0 || j == dataSet.entryCount - 1)
{
pt.x = CGFloat(e.x)
pt.y = CGFloat(e.y * phaseY)
pt = pt.applying(valueToPixelMatrix)
if (!viewPortHandler.isInBoundsRight(pt.x))
{
break
}
if (!viewPortHandler.isInBoundsLeft(pt.x) || !viewPortHandler.isInBoundsY(pt.y))
{
continue
}
if dataSet.isDrawValuesEnabled {
ChartUtils.drawText(
context: context,
text: formatter.stringForValue(
e.y,
entry: e,
dataSetIndex: i,
viewPortHandler: viewPortHandler),
point: CGPoint(
x: pt.x,
y: pt.y - CGFloat(valOffset) - valueFont.lineHeight),
align: .center,
attributes: [NSAttributedStringKey.font: valueFont, NSAttributedStringKey.foregroundColor: dataSet.valueTextColorAt(j)])
}
if let icon = e.icon, dataSet.isDrawIconsEnabled
{
ChartUtils.drawImage(context: context,
image: icon,
x: pt.x + iconsOffset.x,
y: pt.y + iconsOffset.y,
size: icon.size)
}
}
else{
}
}
}
}
}
Set below property of X axis
barChartView.xAxis.setLabelCount(2, force: true)

Core Plot Pie charts don't show

So I have the following code, followed by the Core plot tutorial by Ray Wenderlich over here but adjusted for my own purposes which looks like this:
class CategoryAnalysis:UIViewController{
var collection:String?
var categories = [Category](){
didSet{
CoreDataHelper.retrieveCategories()
}
}
var categoryTotals:[Double] = []
var colors:[CPTColor] = [CPTColor.red(),CPTColor.blue(),CPTColor.cyan(),CPTColor.orange(),CPTColor.yellow(),CPTColor.darkGray(),CPTColor.green(),CPTColor.purple(),CPTColor.lightGray(),CPTColor.brown(),CPTColor.darkGray()]
#IBOutlet weak var hostView: CPTGraphHostingView!
override func viewDidLoad() {
self.categories = CoreDataHelper.retrieveCategories()
categoryTotals.removeAll()
print (collection)
for category in categories{
categoryTotals.append(ExpensesAdditions().retrieveCategoryAnalysis(collectionName: collection!, category: String(describing: category)))
}
super.viewDidLoad()
print(categoryTotals)
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(false)
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(false)
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
initPlot()
}
func initPlot() {
configureHostView()
configureGraph()
configureChart()
configureLegend()
}
func configureHostView() {
hostView.allowPinchScaling = false
}
func configureGraph() {
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
// 2 - Create text style
let textStyle: CPTMutableTextStyle = CPTMutableTextStyle()
textStyle.color = CPTColor.black()
textStyle.fontName = "HelveticaNeue-Bold"
textStyle.fontSize = 16.0
textStyle.textAlignment = .center
// 3 - Set graph title and text style
graph.title = "Category Analysis"
graph.titleTextStyle = textStyle
graph.titlePlotAreaFrameAnchor = CPTRectAnchor.top
}
func configureChart() {
let graph = hostView.hostedGraph!
// 2 - Create the chart
let pieChart = CPTPieChart()
pieChart.delegate = self
pieChart.dataSource = self
pieChart.pieRadius = (min(hostView.bounds.size.width, hostView.bounds.size.height) * 0.7) / 2
pieChart.identifier = NSString(string: graph.title!)
pieChart.startAngle = CGFloat(M_PI_4)
pieChart.sliceDirection = .clockwise
pieChart.labelOffset = -0.6 * pieChart.pieRadius
// 3 - Configure border style
let borderStyle = CPTMutableLineStyle()
borderStyle.lineColor = CPTColor.white()
borderStyle.lineWidth = 2.0
pieChart.borderLineStyle = borderStyle
// 4 - Configure text style
let textStyle = CPTMutableTextStyle()
textStyle.color = CPTColor.white()
textStyle.textAlignment = .center
pieChart.labelTextStyle = textStyle
// 5 - Add chart to graph
graph.add(pieChart)
}
func configureLegend() {
}
}
extension CategoryAnalysis: CPTPieChartDataSource, CPTPieChartDelegate {
func numberOfRecords(for plot: CPTPlot) -> UInt {
return UInt(categories.count)
}
func number(for plot: CPTPlot, field fieldEnum: UInt, record idx: UInt) -> Any? {
if categoryTotals[Int(idx)] == 0{
return 0
}
else {
return categoryTotals[Int(idx)]
}
}
func dataLabel(for plot: CPTPlot, record idx: UInt) -> CPTLayer? {
let value = ExpensesAdditions().convertToMoney(categoryTotals[Int(idx)])
if categoryTotals[Int(idx)] == 0{
let layer2 = CPTTextLayer(text: "")
return layer2
}
else{
let name = String(describing:categories[Int(idx)])
let layer = CPTTextLayer(text: String(format: name, value))
layer.textStyle = plot.labelTextStyle
return layer
}
}
func sliceFill(for pieChart: CPTPieChart, record idx: UInt) -> CPTFill? {
if categoryTotals[Int(idx)]==0{
return CPTFill(color: CPTColor.black())
}
else {
return CPTFill(color: colors[Int(idx)])
}
}
func legendTitle(for pieChart: CPTPieChart, record idx: UInt) -> String? {
return nil
}
}
But when I run this, all I get greeted with, is an empty screen that looks like this instead of a pie chart.
Can someone tell me what is wrong with my code? I'd this something to do with the Swift version as I am currently on Xcode 9
Make sure the hosting view is set up properly. You can inspect hostView in the debugger and make sure it is not nil.
The number(for:field:record:) method signature looks ok, but you need to cast the returned values to NSNumber.
Do you really need to completely rebuild the graph in viewDidLayoutSubviews()? Once the graph is built, Core Plot will take care of layout updates whenever the hosting view bounds change.

How to format xAxis labels iOS charts

Im implementing a barchart and I've managed to assign the data and labels. However, when i load the barchart, it only shows 3/7 of my labels and I'm not sure why.
the labels show up when i interact with the chart but they go glitchy.
I'm sorry if i haven't explained myself well but i have uploaded a .gif showing my problem.
I really need some help with the formatting of the labels on the xAxis. it would be much appreciated.
Thanks in advance.
gif of problem
i think you have used this library(https://github.com/danielgindi/Charts) ... i have set x-Axis using delegate method of chart
func ChartView()
{
xAxis.drawGridLinesEnabled = false
xAxis.drawLabelsEnabled = true
xAxis.labelPosition = .Bottom
xAxis.axisMinimum = 0.0
xAxis.labelCount = ITEM_COUNT
xAxis.granularity = 1.0
xAxis.valueFormatter = self
self.updateChartData()
}
func updateChartData()
{
self.chartView.data = nil
self.setChartData()
}
func generateLineData() -> LineChartData
{
let d = LineChartData()
let entries = NSMutableArray()
var weightstr = String()
var datestr = String()
entries.addObject(ChartDataEntry(x: Double(index), y: ( Double(dic[setvalue]as! String)!)))
let set = LineChartDataSet(values: entries as? [ChartDataEntry] , label: "X-title")
set.setColor(colorWithHexString("#FE1643"))
set.lineWidth = 2.5
set.setCircleColor( UIColor.whiteColor())
set.circleHoleColor = NSUIColor.greenColor()
set.circleRadius = 5.0
set.circleHoleRadius = 2.5
set.fillColor = UIColor.redColor()
set.mode = .HorizontalBezier
set.valueTextColor = UIColor.lightGrayColor()
set.drawValuesEnabled = true
set.valueFont = UIFont(name: "Exo-Regular", size: FOntSIZE(10.0))!
set.axisDependency = .Left
d.addDataSet(set)
return d
}
func setChartData()
{
let data = CombinedChartData()
data.lineData = self.generateLineData()
self.chartView.xAxis.axisMaximum = Double(months.count)-1
self.chartView.data = data
}
func chartValueSelected(chartView: ChartViewBase, entry: ChartDataEntry, highlight: Highlight)
{
print("chartValueSelected")
}
func chartValueNothingSelected(chartView: ChartViewBase)
{
print("chartValueNothingSelected")
}
func stringForValue(value: Double, axis: AxisBase?) -> String
{
return months[Int(round(value)) % months.count] as! String
}

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...

Resources