Core Plot Swift BarPlot tickLocation always zero - ios

I'm trying to make a Bar Chart using core-plot under Swift, i have a problem making custom labels on xAxis, they're always in tickLocation zero.
Maybe someone can help me, this is my code.
import UIKit
class aaa: UIViewController, CPTPlotDataSource{
var items :[NSNumber] = [10,35,18, 20, 50, 5]
#IBOutlet var scrollView: UIScrollView!
#IBOutlet weak var lblTitle: UILabel!
#IBOutlet weak var lblChartName: UILabel!
#IBOutlet weak var vGraph: CPTGraphHostingView!
override func awakeFromNib() {
super.awakeFromNib()
}
override func viewDidLoad() {
super.viewDidLoad()
self.scrollView.contentSize = CGSizeMake(320, 568);
var id: Int=general.idListed
lblTitle.text=general.namListed
items = [10, 35, 18, 20, 50, 5]
var CPDBarWidth:CGFloat = 0.25
var CPDBarInitialX:CGFloat = 0.25
var graph = CPTXYGraph(frame: CGRectZero)
graph.plotAreaFrame.masksToBorder = false
graph.paddingBottom = 50.0
graph.paddingLeft = 50.0
graph.paddingTop = 50.0
graph.paddingRight = 50.0
graph.backgroundColor = UIColor.whiteColor().CGColor
var titleStyle = CPTMutableTextStyle()
titleStyle.color = CPTColor.blackColor()
titleStyle.fontName = "Helvetica-Bold"
titleStyle.fontSize = 16.0
var title : NSString = "January 19 - 24, 2015"
graph.title = title
graph.titleTextStyle = titleStyle
graph.titlePlotAreaFrameAnchor = CPTRectAnchorTop
graph.titleDisplacement = CGPointMake(0.0, 40.0)
var xMin : Float = 0
var xMax : Float = Float(items.count) + 1
var yMin : Float = 0
var yMax : Float = maxItemsValue(items) + 5
var plotSpace = graph.defaultPlotSpace as CPTXYPlotSpace
var xRange = plotSpace.yRange.mutableCopy() as CPTMutablePlotRange
var yRange = plotSpace.yRange.mutableCopy() as CPTMutablePlotRange
xRange.setLocationFloat(xMin)
xRange.setLengthFloat(xMax)
yRange.setLocationFloat(yMin)
yRange.setLengthFloat(yMax)
plotSpace.xRange = xRange
plotSpace.yRange = yRange
var aaplPlot = CPTBarPlot()
aaplPlot.barsAreHorizontal = false
var barLineStyle = CPTMutableLineStyle()
barLineStyle.lineColor = CPTColor.lightGrayColor()
barLineStyle.lineWidth = 1
aaplPlot.dataSource = self
aaplPlot.delegate = self
aaplPlot.barWidthScale = 1
aaplPlot.barOffsetScale = 1
aaplPlot.lineStyle = barLineStyle
graph.addPlot(aaplPlot)
var axisTitleStyle = CPTMutableTextStyle()
axisTitleStyle.color = CPTColor.redColor()
axisTitleStyle.fontName = "Helvetica-Bold"
axisTitleStyle.fontSize = 12.0
var axisLineStyle = CPTMutableLineStyle()
axisLineStyle.lineWidth = 4.0
axisLineStyle.lineColor = CPTColor.redColor()
var axisSet = CPTXYAxisSet()
graph.axisSet = axisSet
axisSet.xAxis.labelingPolicy = CPTAxisLabelingPolicyNone
axisSet.xAxis.title = "Days of Week"
axisSet.xAxis.titleTextStyle = axisTitleStyle
axisSet.xAxis.titleOffset = 30.0
axisSet.xAxis.majorTickLength = 4
axisSet.xAxis.minorTickLength = 0
axisSet.xAxis.tickDirection = CPTSignNegative
axisSet.xAxis.axisLineStyle = axisLineStyle
var customLabels : NSMutableArray = NSMutableArray (capacity: items.count)
var tickLocations : NSMutableArray = NSMutableArray (capacity: items.count)
var labels : [String] = ["MON","THU","WEN","THR","FRI","SAT"]
var next : Int = 0
var newLabel : CPTAxisLabel
for item in items {
var xlabel : String = labels[next]
next++;
var tstyle : CPTMutableTextStyle = CPTMutableTextStyle()
tstyle.color = CPTColor.blueColor()
tstyle.fontSize = 10
newLabel = CPTAxisLabel(text: xlabel, textStyle: tstyle);
newLabel.setTickLocationFloat(Float(next))
newLabel.offset = 5
customLabels.addObject(newLabel)
tickLocations.addObject(Float(next))
}
axisSet.xAxis.majorTickLocations = NSSet(array: tickLocations)
axisSet.xAxis.axisLabels = NSSet(array: customLabels)
self.vGraph.hostedGraph = graph
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
func maxItemsValue(items :[NSNumber])-> NSNumber{
var max : NSNumber=0
for item in items{
if item.floatValue > max.floatValue {
max = item
}
}
return max
}
func numberOfRecordsForPlot(plot: CPTPlot!) -> UInt {
return UInt(items.count)
}
func numberForPlot(plot: CPTPlot!, field fieldEnum: UInt, recordIndex idx: UInt) -> NSNumber! {
switch (fieldEnum) {
case 0:
if (idx < UInt(items.count)) {
return idx + 1
}
break;
case 1:
return items[Int(idx)]
default:
return 1
}
return 1
}
}

You need to set the tickLocation of each new label.
newLabel.tickLocation = next

Related

iOS Charts(Daniel Gindi) - Two LineChartDataSet with different color failed

I am trying to build a graph with 2 LineChartDataSet. At the first time, I build with one and then on every selected value, I want to do some different color to the right data set yet it seems like the last set sort of run over the settings and do it the opposite:
class GraphTableViewCell: UITableViewCell {
#IBOutlet weak var yieldLabel: UILabel!
#IBOutlet weak var yieldPercentLabel: UILabel!
#IBOutlet weak var lineChart: LineChartView!
#IBOutlet weak var graphButtonView: AssetGraphButtonView!
#IBOutlet weak var endDateLabel: UILabel!
#IBOutlet weak var startDateLabel: UILabel!
var selectionView: AssetGraphSelectionView!
var viewModel: GraphViewModelType!
var set: LineChartDataSet!
var set1: LineChartDataSet!
var marker = BalloonMarker(color: .red,
font: UIFont.systemFont(ofSize: 15),
textColor: .white,
insets: UIEdgeInsets(top: 5, left: 5, bottom: 10, right: 3))
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
override func layoutSubviews() {
super.layoutSubviews()
}
func config(with viewModel: GraphViewModelType) {
self.viewModel = viewModel
yieldLabel.attributedText = viewModel.titleAttributeText
yieldPercentLabel.attributedText = viewModel.yielAttributeText
startDateLabel.attributedText = viewModel.startDateAttributeText
endDateLabel.attributedText = viewModel.endDateAttributeText
graphButtonView.confgiureCell(with: self.viewModel.btnData)
setUpChart()
}
func setUpChart() {
lineChart.delegate = self
lineChart.noDataText = "No Data Available"
lineChart.rightAxis.enabled = false
lineChart.leftAxis.enabled = false
lineChart.xAxis.enabled = false
lineChart.legend.enabled = false
lineChart.xAxis.drawGridLinesEnabled = false
lineChart.drawMarkers = true
lineChart.doubleTapToZoomEnabled = false
lineChart.pinchZoomEnabled = false
lineChart.scaleXEnabled = false
lineChart.scaleYEnabled = false
marker.chartView = lineChart
marker.minimumSize = CGSize(width: 28, height: 20)
lineChart.marker = marker
let dataSets = viewModel.getLineChartDataSet()
let data = LineChartData(dataSets: dataSets)
data.setValueFont(.systemFont(ofSize: 7, weight: .light))
lineChart.data = data
}
extension GraphTableViewCell: ChartViewDelegate {
func chartValueSelected(_ chartView: ChartViewBase, entry: ChartDataEntry, highlight: Highlight) {
let transform = lineChart.getTransformer(forAxis: .left)
let point = transform.pixelForValues(x: highlight.x, y: highlight.y)
print("point : x = \(point.x) y = \(point.y)")
let color = self.lineChart.colorOfPoint(point: point)
marker.color = color
let dataSets = viewModel.chartValueSelected(entry: entry)
lineChart.data = dataSets
}
}
This is the viewModel:
final class GraphTableViewCellViewModel: GraphViewModelType {
var startDateAttributeText = NSMutableAttributedString()
var endDateAttributeText = NSMutableAttributedString()
var titleAttributeText = NSMutableAttributedString(string: "", attributes: [NSAttributedString.Key.font : UIFont(name: "Orion-Bold", size: 14)!, NSAttributedString.Key.foregroundColor : UIColor.black])
var yielAttributeText = NSMutableAttributedString(string: "\(String(format: "%.2f%%", abs(14)))", attributes: [NSAttributedString.Key.font : UIFont(name: "Orion-Bold", size: 14)!, NSAttributedString.Key.foregroundColor : UIColor.green])
let disposeBag = DisposeBag()
var btnData: [AssetGraphButtonViewViewModel]
var data: TwrGraph
var dataSet = [LineChartDataSet]()
var set: LineChartDataSet!
var set1: LineChartDataSet!
init(with data: TwrGraph) {
btnData = AssetGraphViewModel(security: nil).assetGraphData
self.data = data
startDateAttributeText = NSMutableAttributedString(string: data.startDate, attributes: [NSAttributedString.Key.font : UIFont(name: "Orion-Regular", size: 12)!, NSAttributedString.Key.foregroundColor : ColorName.warmGreyTwo])
endDateAttributeText = NSMutableAttributedString(string: data.endDate, attributes: [NSAttributedString.Key.font : UIFont(name: "Orion-Regular", size: 12)!, NSAttributedString.Key.foregroundColor : ColorName.warmGreyTwo])
}
func getChartDataPoints(dataPoints: [String], values: [Double]) -> [ChartDataEntry] {
var dataEntries: [ChartDataEntry] = []
for count in (0..<dataPoints.count) {
dataEntries.append(ChartDataEntry.init(x: Double(count), y: values[count]))
}
return dataEntries
}
func getLineChartDataSet() -> [LineChartDataSet] {
let dataWeeklyDate = self.data.weeklyGraph.map { $0.date }
let dataWeeklyYield = self.data.weeklyGraph.map { $0.yield }
let dataPoints = getChartDataPoints(dataPoints: dataWeeklyDate, values: dataWeeklyYield)
set = LineChartDataSet(entries: dataPoints, label:"")
setup(set)
return [set]
}
func setup(_ dataSet: LineChartDataSet) {
dataSet.drawHorizontalHighlightIndicatorEnabled = false
dataSet.drawVerticalHighlightIndicatorEnabled = true
dataSet.isDrawLineWithGradientEnabled = true
dataSet.fillAlpha = 0.15
dataSet.lineWidth = 2
dataSet.circleRadius = 0
dataSet.drawCircleHoleEnabled = false
dataSet.drawCirclesEnabled = false
dataSet.drawValuesEnabled = false
dataSet.highlightColor = .blue
let rightColor = [ChartColorTemplates.colorFromString("#FA3A7A"), ChartColorTemplates.colorFromString("#C257B1"),
ChartColorTemplates.colorFromString("#8B73E8")]
dataSet.colors = rightColor
dataSet.gradientPositions = [0, 40, 100]
let gradientColors = [ChartColorTemplates.colorFromString("#FC4684").cgColor,
ChartColorTemplates.colorFromString("#D8D8D8").cgColor]
let colorLocations:[CGFloat] = [1.0, 0.0]
if let gradient = CGGradient(colorsSpace: nil, colors: gradientColors as CFArray, locations: colorLocations) {
dataSet.fill = LinearGradientFill(gradient: gradient, angle: 90.0)
}
dataSet.drawFilledEnabled = true
}
func updateSetAfterTouch(_ dataSet: LineChartDataSet) {
dataSet.drawHorizontalHighlightIndicatorEnabled = false
dataSet.drawVerticalHighlightIndicatorEnabled = true
// dataSet.isDrawLineWithGradientEnabled = true
dataSet.fillAlpha = 0.15
dataSet.lineWidth = 2
dataSet.circleRadius = 0
dataSet.drawCircleHoleEnabled = false
dataSet.drawCirclesEnabled = false
dataSet.drawValuesEnabled = false
// dataSet.highlightColor = .blue
dataSet.colors = [.red]
}
func chartValueSelected(entry: ChartDataEntry) -> LineChartData {
return updateSet(with: entry)
}
func updateSet(with entry: ChartDataEntry) -> LineChartData {
var dataEntries: [ChartDataEntry] = []
var dataEntries1: [ChartDataEntry] = []
for count in (0..<self.data.weeklyGraph.count) {
if count < self.data.weeklyGraph.count && count < Int(entry.x) {
dataEntries.append(ChartDataEntry.init(x: Double(count), y: self.data.weeklyGraph[count].yield))
} else {
dataEntries1.append(ChartDataEntry.init(x: Double(count), y: self.data.weeklyGraph[count].yield))
}
}
set = LineChartDataSet(entries: dataEntries, label:"")
set1 = LineChartDataSet(entries: dataEntries1, label:"")
setup(set)
updateSetAfterTouch(set1)
let data = LineChartData(dataSets: [set1, set])
return data
}
}
As you can see when value is selected and I am using it to create two ChartDataEntry and the two LineChartDataSet that one continue the other (in the x axis ). This is the image when we first entering(looks fine):
This is the image when selecting:
After creating two LineChartDataSet add a different colour for each set.
func updateGraph(){
//create 2 ChartDataEntry arrays for both sets
var dataEntries : [ChartDataEntry] = []
var dataEntries1 : [ChartDataEntry] = []
//use ur condition here to devide the data in to two groups
for i in 0..<numbers.count {
if i < 3{
let value = ChartDataEntry(x: Double(i), y: numbers[i]) // here we set the X and Y status in a data chart entry
dataEntries.append(value)
}else{
let value = ChartDataEntry(x: Double(i), y: numbers[i]) // here we set the X and Y status in a data chart entry
dataEntries1.append(value)
}
}
//I add the last element of the first array to the begining of the first array to stop discontinue
dataEntries1.insert(dataEntries.last!, at: 0)
//create data set 1
let set1 = LineChartDataSet(entries: dataEntries, label: "Number")
set1.colors = [UIColor.blue]
//create data set 2
let set2 = LineChartDataSet(entries: dataEntries1, label: "Number")
set2.colors = [UIColor.red]
//This is the object that will be added to the chart
let data = LineChartData(dataSets: [set1, set2])
chtChart.data = data //finally - it adds the chart data to the chart and causes an update
}
My Output looks like follows.
Full ViewController Code
class ViewController: UIViewController {
#IBOutlet weak var txtTextBox: UITextField!
#IBOutlet weak var chtChart: LineChartView!
var numbers : [Double] = [] //This is where we are going to store all the numbers. This can be a set of numbers that come from a Realm database, Core data, External API's or where ever else
override func viewDidLoad() {
super.viewDidLoad()
var dataEntries : [ChartDataEntry] = []
numbers = [2,4,7,3,4,5,8,9,1,2,9]
for i in 0..<numbers.count{
let value = ChartDataEntry(x: Double(i), y: numbers[i]) // here we set the X and Y status in a data chart entry
dataEntries.append(value)
}
let dataSet = LineChartDataSet(entries: dataEntries, label: "Number")
dataSet.drawHorizontalHighlightIndicatorEnabled = false
dataSet.drawVerticalHighlightIndicatorEnabled = true
dataSet.drawHorizontalHighlightIndicatorEnabled = true
dataSet.fillAlpha = 0.15
dataSet.lineWidth = 2
dataSet.circleRadius = 0
dataSet.drawCircleHoleEnabled = false
dataSet.drawCirclesEnabled = false
dataSet.drawValuesEnabled = false
dataSet.highlightColor = .blue
dataSet.colors = [UIColor.green]
let data = LineChartData(dataSets: [dataSet])
chtChart.data = data
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
#IBAction func btnbutton(_ sender: Any) {
// let input = Double(txtTextBox.text!) //gets input from the textbox - expects input as double/int
// numbers.append(input!) //here we add the data to the array.
updateGraph()
txtTextBox.text = ""
}
func updateGraph(){
//create 2 ChartDataEntry arrays for both sets
var dataEntries : [ChartDataEntry] = []
var dataEntries1 : [ChartDataEntry] = []
//use ur condition here to devide the data in to two groups
for i in 0..<numbers.count {
if i < 3{
let value = ChartDataEntry(x: Double(i), y: numbers[i]) // here we set the X and Y status in a data chart entry
dataEntries.append(value)
}else{
let value = ChartDataEntry(x: Double(i), y: numbers[i]) // here we set the X and Y status in a data chart entry
dataEntries1.append(value)
}
}
//I add the last element of the first array to the begining of the first array to stop discontinue
dataEntries1.insert(dataEntries.last!, at: 0)
//create data set 1
let set1 = LineChartDataSet(entries: dataEntries, label: "Number")
set1.colors = [UIColor.blue]
set1.drawHorizontalHighlightIndicatorEnabled = false
set1.drawVerticalHighlightIndicatorEnabled = true
set1.drawHorizontalHighlightIndicatorEnabled = true
set1.fillAlpha = 0.15
set1.lineWidth = 2
set1.circleRadius = 0
set1.drawCircleHoleEnabled = false
set1.drawCirclesEnabled = false
set1.drawValuesEnabled = false
set1.highlightColor = .blue
//create data set 2
let set2 = LineChartDataSet(entries: dataEntries1, label: "Number")
set2.colors = [UIColor.red]
set2.drawHorizontalHighlightIndicatorEnabled = false
set2.drawVerticalHighlightIndicatorEnabled = true
set2.drawHorizontalHighlightIndicatorEnabled = true
set2.fillAlpha = 0.15
set2.lineWidth = 2
set2.circleRadius = 0
set2.drawCircleHoleEnabled = false
set2.drawCirclesEnabled = false
set2.drawValuesEnabled = false
set2.highlightColor = .blue
//This is the object that will be added to the chart
let data = LineChartData(dataSets: [set1, set2])
chtChart.data = data //finally - it adds the chart data to the chart and causes an update
}
}

Only one label appearing on a BarChart created with Charts

I want to create a BarChart with the Charts library. Everything is working good except the labels on the x axis. Only the first label "Jan" is appearing on the line. This is my code
override func viewWillAppear(_ animated: Bool) {
doBarChart()
}
func doBarChart(){
barChartView.drawBarShadowEnabled = false
barChartView.drawValueAboveBarEnabled = true
barChartView.chartDescription?.enabled = false
barChartView.maxVisibleCount = 60
let xAxis = barChartView.xAxis
xAxis.axisLineColor = UIColor.black
xAxis.labelPosition = .bottom
xAxis.drawAxisLineEnabled = true
xAxis.drawGridLinesEnabled = false
xAxis.granularity = 1.0
xAxis.labelCount = 1
// xAxis.setLabelCount(7, force: true)
let months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul",]
xAxis.valueFormatter = IndexAxisValueFormatter(values:months)
//Also, you probably want to add:
let leftAxis = barChartView.leftAxis;
leftAxis.enabled = false
leftAxis.drawAxisLineEnabled = false;
leftAxis.drawGridLinesEnabled = false;
leftAxis.axisMinimum = 0.0; // this replaces startAtZero = YES
let rightAxis = barChartView.rightAxis
rightAxis.enabled = false;
rightAxis.drawAxisLineEnabled = true;
rightAxis.drawGridLinesEnabled = false;
rightAxis.axisMinimum = 0.0; // this replaces startAtZero = YES
let l = barChartView.legend
l.enabled = false
barChartView.fitBars = true;
barChartView.animate(xAxisDuration: 0.2, yAxisDuration: 1.0, easingOptionX: .easeInExpo, easingOptionY: .easeInExpo)
setDataCount(count: 7, range: 50)
}
func setDataCount(count: Int, range: Double){
let barWidth = 7.0
let spaceForBar = 10.0
var yVals = [BarChartDataEntry]()
yVals.append(BarChartDataEntry(x: Double(0) * spaceForBar, y: 44.5))
yVals.append(BarChartDataEntry(x: Double(1) * spaceForBar, y: 78.1))
yVals.append(BarChartDataEntry(x: Double(2) * spaceForBar, y: 50.3))
yVals.append(BarChartDataEntry(x: Double(3) * spaceForBar, y: 56.6))
yVals.append(BarChartDataEntry(x: Double(4) * spaceForBar, y: 20.5))
yVals.append(BarChartDataEntry(x: Double(5) * spaceForBar, y: 44.3))
yVals.append(BarChartDataEntry(x: Double(6) * spaceForBar, y: 54.4))
var set1 : BarChartDataSet!
if let count = barChartView.data?.dataSetCount, count > 0{
set1 = barChartView.data?.dataSets[0] as! BarChartDataSet
set1.values = yVals
set1.colors = [UIColor.black,UIColor.orange,UIColor.red,UIColor.green,UIColor.yellow,UIColor.blue,UIColor.gray]
barChartView.data?.notifyDataChanged()
barChartView.notifyDataSetChanged()
}else{
set1 = BarChartDataSet(values: yVals, label: "DataSet")
set1.colors = [UIColor.black,UIColor.orange,UIColor.red,UIColor.green,UIColor.yellow,UIColor.blue,UIColor.gray]
var dataSets = [BarChartDataSet]()
dataSets.append(set1)
let data = BarChartData(dataSets: dataSets)
data.barWidth = barWidth;
barChartView.data = data
}
}
Add the following delegate method of "IAxisValueFormatter"
And assign these delegate.
class xyz : IAxisValueFormatter{
weak var axisFormatDelegate: IAxisValueFormatter?
//add these line in the func...
func doBarChart{
let xAxisValue = lineChartView.xAxis
xAxisValue.valueFormatter = axisFormatDelegate
lineChartView.xAxis.granularityEnabled = true
lineChartView.xAxis.granularity = 1.0
}
//add these method..
func stringForValue(_ value: Double, axis: AxisBase?) -> String {
return yvlaues[Int(value) % yvlaues.count]
}
}

How to Render a Pie Chart on childviews in iOS?

How to render pie charts on child views? In my story board having 4 child views. I am trying to show 4 different pie charts based on the selection ( I am using segmented control which has 4 segments ). I tried with sample data but not able to render pie chart ( as it showing no data available ). How to add pie chart data to child views?
[ Note:- I am using danielgindib library and swift 3 ]
Screenshot of my storyboard
Storyboard screenshot 1
Storyboard screenshot 2
SecondViewController.swift
import UIKit
import Charts
class SecondViewController: UIViewController, ChartViewDelegate{
var controllerName:String?
#IBOutlet weak var pChartViewA: PieChartView!
#IBOutlet weak var pChartViewB: PieChartView!
#IBOutlet weak var pChartViewC: PieChartView!
#IBOutlet weak var pChartViewD: PieChartView!
override func viewDidLoad() {
super.viewDidLoad()
self.pChartViewA.delegate = self
// self.pChartViewB.delegate = self
//self.pChartViewC.delegate = self
// self.pChartViewD.delegate = self
self.pChartViewA.alpha = 1
//self.pChartView.delegate = self
// Pie Chart
pChartViewA.noDataText = "You need to provide data for the chart."
let pys1 = Array(1..<10).map { x in return sin(Double(x) / 2.0 / 3.141 * 1.5) * 100.0 }
let pyse1 = pys1.enumerated().map { x, y in return PieChartDataEntry(value: y, label: String(x)) }
let pdata = PieChartData()
let pds1 = PieChartDataSet(values: pyse1, label: "Hello")
pds1.colors = ChartColorTemplates.vordiplom()
pdata.addDataSet(pds1)
let paragraphStyle: NSMutableParagraphStyle = NSParagraphStyle.default.mutableCopy() as! NSMutableParagraphStyle
paragraphStyle.lineBreakMode = .byTruncatingTail
paragraphStyle.alignment = .center
let centerText: NSMutableAttributedString = NSMutableAttributedString(string: "Sample Screening Pie")
self.pChartViewA.centerAttributedText = centerText
self.pChartViewA.data = pdata
self.pChartViewA.chartDescription?.text = "Piechart Demo"
}
#IBAction func ChangeComponent(_ sender: AnyObject) {
if sender.selectedSegmentIndex == 0 {
UIView.animate(withDuration: 0.5, animations: {
self.pChartViewA.alpha = 1
self.pChartViewB.alpha = 0
self.pChartViewC.alpha = 0
self.pChartViewD.alpha = 0
// Pie Chart
self.pChartViewA.noDataText = "You need to provide data for the chart."
let pys1 = Array(1..<10).map { x in return sin(Double(x) / 2.0 / 3.141 * 1.5) * 100.0 }
let pyse1 = pys1.enumerated().map { x, y in return PieChartDataEntry(value: y, label: String(x)) }
let pdata = PieChartData()
let pds1 = PieChartDataSet(values: pyse1, label: "Hello")
pds1.colors = ChartColorTemplates.vordiplom()
pdata.addDataSet(pds1)
let paragraphStyle: NSMutableParagraphStyle = NSParagraphStyle.default.mutableCopy() as! NSMutableParagraphStyle
paragraphStyle.lineBreakMode = .byTruncatingTail
paragraphStyle.alignment = .center
let centerText: NSMutableAttributedString = NSMutableAttributedString(string: "Sample Screening Pie")
self.pChartViewA.centerAttributedText = centerText
self.pChartViewA.data = pdata
self.pChartViewA.chartDescription?.text = "Piechart Demo"
})
} else if sender.selectedSegmentIndex == 1 {
UIView.animate(withDuration: 0.5, animations: {
self.pChartViewA.alpha = 0
self.pChartViewB.alpha = 1
self.pChartViewC.alpha = 0
self.pChartViewD.alpha = 0
})
}
else if sender.selectedSegmentIndex == 2 {
UIView.animate(withDuration: 0.5, animations: {
self.pChartViewA.alpha = 0
self.pChartViewB.alpha = 0
self.pChartViewC.alpha = 1
self.pChartViewD.alpha = 0
})
}
else if sender.selectedSegmentIndex == 3 {
UIView.animate(withDuration: 0.5, animations: {
self.pChartViewA.alpha = 0
self.pChartViewB.alpha = 0
self.pChartViewC.alpha = 0
self.pChartViewD.alpha = 1
})
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Thank you in advance.

iOS CorePlot point conversion

I am experimenting with Core Plot. I am trying to add a custom "goal" label over the graph at x: 2.0, y: 50.0 - basically label over the y == 50, its in a separate view, which means I need to convert my point from Core Plot to my UIView bounds. I have not found a combination of points conversions from layer/views that works across all iPhones screen sizes. In my pictures below iPhone 6s is the closest.
iPhone 6s+:
iPhone 6s:
iPhone 5s:
My view layout:
Here is my class:
class BarChartViewController: UIViewController, CPTBarPlotDataSource
{
private var barGraph : CPTXYGraph? = nil
#IBOutlet weak var textBox: UILabel!
#IBOutlet weak var graphHostingView: CPTGraphHostingView!
#IBOutlet weak var textBoxView: UIView!
override func viewDidLoad() {
super.viewDidLoad()
self.navigationController?.setNavigationBarHidden(false, animated: false)
self.title = "My results"
let newGraph = CPTXYGraph(frame: CGRectZero)
let theme = CPTTheme(named: kCPTPlainWhiteTheme)
newGraph.applyTheme(theme)
let hostingView = graphHostingView
hostingView.hostedGraph = newGraph
if let frameLayer = newGraph.plotAreaFrame
{
// Border
frameLayer.borderLineStyle = nil
frameLayer.cornerRadius = 0.0
frameLayer.masksToBorder = false
// Paddings
newGraph.paddingLeft = 0.0
newGraph.paddingRight = 0.0
newGraph.paddingTop = 0.0
newGraph.paddingBottom = 0.0
frameLayer.paddingLeft = 70.0
frameLayer.paddingTop = 20.0
frameLayer.paddingRight = 20.0
frameLayer.paddingBottom = 80.0
}
// Plot space
let plotSpace = newGraph.defaultPlotSpace as? CPTXYPlotSpace
plotSpace?.yRange = CPTPlotRange(location: 0.0, length: 100.0)
plotSpace?.xRange = CPTPlotRange(location: 0.0, length: 4.0)
let axisSet = newGraph.axisSet as? CPTXYAxisSet
if let x = axisSet?.xAxis {
x.axisLineStyle = nil
x.majorTickLineStyle = nil
x.minorTickLineStyle = nil
x.majorIntervalLength = 5.0
x.orthogonalPosition = 0.0
x.title = "X Axis"
x.titleLocation = 7.5
x.titleOffset = 55.0
// Custom labels
x.labelRotation = CGFloat(M_PI_4)
x.labelingPolicy = .None
let customTickLocations = [0.5, 1.5, 2.5]
let xAxisLabels = ["Label A", "Label B", "Label C"]
var labelLocation = 0
var customLabels = Set<CPTAxisLabel>()
for tickLocation in customTickLocations
{
let newLabel = CPTAxisLabel(text: xAxisLabels[labelLocation], textStyle: x.labelTextStyle)
labelLocation += 1
newLabel.tickLocation = tickLocation
newLabel.offset = x.labelOffset + x.majorTickLength
newLabel.rotation = 0 //CGFloat(M_PI_4)
customLabels.insert(newLabel)
}
x.axisLabels = customLabels
}
if let y = axisSet?.yAxis
{
y.axisLineStyle = nil
y.majorGridLineStyle = CPTMutableLineStyle()
var style = y.majorTickLineStyle?.mutableCopy() as? CPTMutableLineStyle
//style!.lineColor = CPTColor(CGColor: UIColor.blackColor()) //UIColor.blackColor())
style!.lineWidth = 10.0
y.minorGridLineStyle = CPTMutableLineStyle()
style = y.minorTickLineStyle?.mutableCopy() as? CPTMutableLineStyle
//style.lineColor = UIColor.redColor()
style!.lineWidth = 10.0
style!.lineCap = .Round
y.majorTickLength = 10.0
y.majorIntervalLength = 50.0
y.orthogonalPosition = 0.0
y.title = "Y Axis"
y.titleOffset = 45.0
y.titleLocation = 150.0
y.labelRotation = 0
y.labelingPolicy = .None
let customTickLocations = [50, 100]
let yAxisLabels = ["50", "100"]
var labelLocation = 0
var customLabels = Set<CPTAxisLabel>()
for tickLocation in customTickLocations
{
let newLabel = CPTAxisLabel(text: yAxisLabels[labelLocation], textStyle: y.labelTextStyle)
labelLocation += 1
newLabel.tickLocation = tickLocation
newLabel.offset = y.labelOffset + y.majorTickLength
newLabel.rotation = 0 //CGFloat(M_PI_4)
customLabels.insert(newLabel)
}
y.axisLabels = customLabels
var nums = Set<NSNumber>()
nums.insert(NSNumber(double: 50.0))
y.majorTickLocations = nums
}
// First bar plot
let barPlot1 = CPTBarPlot.tubularBarPlotWithColor(CPTColor.yellowColor(), horizontalBars: false)
barPlot1.baseValue = 0.0
barPlot1.dataSource = self
//barPlot1.barOffset = 0.5
barPlot1.identifier = "Bar Plot 1"
let textStyle = CPTMutableTextStyle()
textStyle.color = CPTColor.redColor()
textStyle.fontSize = 10.0
barPlot1.labelTextStyle = textStyle
newGraph.addPlot(barPlot1, toPlotSpace: plotSpace)
self.barGraph = newGraph
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
self.view.layoutIfNeeded()
let point: [Double] = [2.0, 50.0]
let plotPoint = UnsafeMutablePointer<Double>(point)
var dataPoint = self.barGraph?.defaultPlotSpace?.plotAreaViewPointForDoublePrecisionPlotPoint(plotPoint, numberOfCoordinates: 2)
//dataPoint = graphHostingView.layer.convertPoint(dataPoint!, fromLayer: self.barGraph!.plotAreaFrame!.plotArea)
dataPoint = graphHostingView.layer.convertPoint(dataPoint!, toLayer: graphHostingView.layer.superlayer)
//dataPoint = barGraph?.convertPoint(dataPoint!, fromLayer: graphHostingView.layer)
dataPoint = self.textBoxView.convertPoint(dataPoint!, fromView: graphHostingView)
print(dataPoint!)
for item in (self.textBoxView?.constraints)!
{
if let id = item.identifier
{
if id == "goalX"
{
print(item.constant)
item.constant = CGFloat((dataPoint?.x)!) - item.constant
}
else if id == "goalY"
{
print(item.constant)
item.constant = CGFloat((dataPoint?.y)!) - item.constant
}
}
}
barGraph?.titleDisplacement = CGPoint(x: dataPoint!.x * -1, y: dataPoint!.y * -1)
barGraph?.titlePlotAreaFrameAnchor = .TopLeft
self.textBoxView?.layoutIfNeeded()
}
}
Based on some other questions I have seen about CorePlot I know I need to convert it from CorePlot layer to my new view. I left some of my experiments in viewWillAppear() to see what I have tried. None of the solutions on SO seemed to work and I am new to iOS so probably missing something. Any ideas of what conversions I need to do to get my label to show up properly across all screen sizes?
You're on the right track with the point conversion. This is how I would do it:
// Update layer layout if needed
self.view.layoutIfNeeded()
graphHostingView.layer.layoutIfNeeded()
// Point in data coordinates
let point: [Double] = [2.0, 50.0]
// Data point in plot area layer coordinates
var dataPoint = self.barGraph?.defaultPlotSpace?.plotAreaViewPointForPlotPoint(point)
// Convert data point to graph hosting view coordinates
dataPoint = graphHostingView.layer.convertPoint(dataPoint!, fromLayer: self.barGraph!.plotAreaFrame!.plotArea)
Use this to update the constraints on the text box relative to the graph hosting view.

iOS Core Plot with Swift - Formatting Axis

Hi I am new to core plot and I have this issue and its bugging me for sometime..
The issue is that both X and Y axis won't show the axis label, axis tile, axis majorlengthinterval, etc.. Basically, I cannot set the axis properties except axis line style. The following is my code.
class testVC: UIViewController, CPTPlotDataSource, CPTPlotDelegate, CPTPlotSpaceDelegate {
var hostView: CPTGraphHostingView!
let xData = ["2","4"]
let yData = ["1","2"]
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
func symbolForScatterPlot(aPlot: CPTScatterPlot, recordIndex index: UInt) -> CPTPlotSymbol {
let dotStyle = CPTPlotSymbol()
dotStyle.size = CGSizeMake(6, 6)
dotStyle.fill = CPTFill(color: CPTColor.blueColor())
dotStyle.symbolType = CPTPlotSymbolType.Ellipse
return dotStyle
}
#IBAction func plotClick(sender: AnyObject) {
let frame = self.view.frame
//add graph
let graph = CPTXYGraph(frame: CGRect(x: 0, y: 50, width: frame.width, height: frame.height - 250))
graph.paddingBottom = 10
graph.paddingLeft = 10
graph.paddingRight = 10
graph.paddingTop = 10
graph.title = "Scatter Plot"
//hostView
hostView = CPTGraphHostingView(frame: graph.frame)
self.view.addSubview(hostView)
//add scatter plot and plot space
var scatterPlot = CPTScatterPlot()
scatterPlot = CPTScatterPlot(frame: hostView.frame)
scatterPlot.delegate = self
scatterPlot.dataSource = self
let plotSpace = graph.defaultPlotSpace as! CPTXYPlotSpace
plotSpace.delegate = self
plotSpace.allowsUserInteraction = true
plotSpace.xRange = CPTPlotRange(location: 0, length: 10)
plotSpace.yRange = CPTPlotRange(location: 0, length: 18)
scatterPlot.dataLineStyle = nil //hide line
graph.addPlot(scatterPlot)
//set axis
let axes: CPTXYAxisSet = CPTXYAxisSet(layer: graph.axisSet!); let x = axes.xAxis; let y = axes.yAxis
let lineStyle = CPTMutableLineStyle()
lineStyle.lineWidth = 3
x!.axisLineStyle = lineStyle; y!.axisLineStyle = lineStyle
x!.title = "X"; y!.title = "Y"
x!.orthogonalPosition = 0; y!.orthogonalPosition = 0
x!.majorIntervalLength = 1; y!.majorIntervalLength = 1
x!.minorTickLength = 4; y!.minorTickLength = 4
hostView.hostedGraph = graph
}
func numberOfRecordsForPlot(plot: CPTPlot) -> UInt {
return 2
}
func numberForPlot(plot: CPTPlot, field fieldEnum: UInt, recordIndex idx: UInt) -> AnyObject? {
if fieldEnum == 0 {
return xData[Int(idx)]
} else {
return yData[Int(idx)]
}
}
You're not setting the axis properties on the one belonging to the graph—you're setting up a copy which then goes away. Try this instead:
let axes = graph.axisSet as? CPTXYAxisSet

Resources