Correct data not showing in ios Charts - ios

Im using Charts Version 3.0.1. Im currently teaching myself Swift by converting my Rails project. I have no knowledge of Objective C so please bear with me; I've done ok so far.
My code below is/may not be formatted correctly as Im missing the days array in the PieChart:
Numbers seem not to be correct. The code:
#IBOutlet weak var chartView: PieChartView!
override func viewDidLoad() {
super.viewDidLoad()
let days = ["Mo", "Tu", "Wed", "Thur", "Fri", "Sat", "Sun"]
let gross = [11.00, 90.95, 250.00, 40.90, 60.88, 99.99, 25.00]
setChart(dataPoints: days, values: gross)
}
func setChart(dataPoints: [String], values: [Double]) {
var dataEntries: [ChartDataEntry] = []
for i in 0..<dataPoints.count {
let dataEntry = ChartDataEntry(x: values[i], y: Double(i))
dataEntries.append(dataEntry)
}
let pieChartDataSet = PieChartDataSet(values: dataEntries, label: "Gross Income")
pieChartDataSet.sliceSpace = 2.0
let pieChartData = PieChartData(dataSets: [pieChartDataSet]) // somewhere here confuses me.
var colors: [UIColor] = []
for _ in 0..<dataPoints.count {
let red = Double(arc4random_uniform(256))
let green = Double(arc4random_uniform(256))
let blue = Double(arc4random_uniform(256))
let color = UIColor(red: CGFloat(red/255), green: CGFloat(green/255), blue: CGFloat(blue/255), alpha: 1)
colors.append(color)
}
pieChartDataSet.colors = colors
chartView.data = pieChartData
}
Have I missed out something? Your second eye would be highly appreciated.

You have changed x & y values and hence index is coming as your pie chart's value. Also, please use PieChartDataEntry.
(working code on my box)
override func viewDidLoad() {
super.viewDidLoad()
let days = ["Mo", "Tu", "Wed", "Thur", "Fri", "Sat", "Sun"]
let gross = [11.00, 90.95, 250.00, 40.90, 60.88, 99.99, 25.00]
setChart(days: days, gross: gross)
}
func setChart(days: [String], gross: [Double]) {
var dataEntries: [ChartDataEntry] = []
for i in 0..<days.count {
let dataEntry = PieChartDataEntry(value : gross[i], label : days[i])
dataEntries.append(dataEntry)
}
let pieChartDataSet = PieChartDataSet(values: dataEntries, label: "Gross Income")
pieChartDataSet.sliceSpace = 2.0
let pieChartData = PieChartData(dataSets: [pieChartDataSet])
var colors: [UIColor] = []
for _ in 0..<days.count {
let red = Double(arc4random_uniform(256))
let green = Double(arc4random_uniform(256))
let blue = Double(arc4random_uniform(256))
let color = UIColor(red: CGFloat(red/255), green: CGFloat(green/255), blue: CGFloat(blue/255), alpha: 1)
colors.append(color)
}
pieChartDataSet.colors = colors
pieChartView.data = pieChartData
}
Try this and let me know.

Related

iOS Charts show only one chart segment

I try to setup a pie chart from Charts library with two items. My code if following
lazy var pieChart : PieChartView = {
let pie = PieChartView()
pie.data?.setValueTextColor(UIColor.abClear())
pie.chartDescription?.enabled = false
pie.legend.enabled = false
return pie
}()
override func viewDidLoad() {
super.viewDidLoad()
let months = ["Jan", "Feb"]
let unitsSold = [10.0, 10.0]
setChart(dataPoints: months, values: unitsSold)
}
func setChart(dataPoints: [String], values: [Double]) {
var dataEntries: [ChartDataEntry] = []
for i in 0..<dataPoints.count {
let dataEntry = ChartDataEntry(x: values[i], y: Double(i))
dataEntries.append(dataEntry)
}
let pieChartDataSet = PieChartDataSet(values: dataEntries, label: "")
pieChartDataSet.drawValuesEnabled = false
let pieChartData = PieChartData(dataSet: pieChartDataSet)
pieChart.data = pieChartData
pieChartDataSet.colors = [UIColor.red, UIColor.blue]
}
The problem is that chart draws only one item - blue one. Looks like this
What am I doing wrong ?
I checked your code. The problem is the values you are setting for x and y in ChartDataEntry. Change your code in the function setChart(dataPoints: [String], values: [Double]):
for i in 0..<dataPoints.count {
let dataEntry = ChartDataEntry(x: Double(i), y: values[i])//ChartDataEntry(x: values[i], y: Double(i))
dataEntries.append(dataEntry)
}

How do I display labels on bottom axis (xVals) correctly on iOS Chart?

I have been following very simple tutorial of iOS Charts.
The values in my chart are now showing correctly, however the label on the bottom is not showing.
override func viewDidLoad() {
results = ["Won", "Drawn", "Lost"]
let games = [totalWins, totalDraws, totalLosses]
setChart(dataPoints: results, values: games)
}
// CHART FUNCTION ************
func setChart(dataPoints: [String], values: [Double]){
barChartView.noDataText = "you need to provide some data for the chart."
var dataEntries: [BarChartDataEntry] = Array()
for i in 0..<dataPoints.count {
let dataEntry = BarChartDataEntry(x: Double(i), y: values[i])
dataEntries.append(dataEntry)
}
let chartDataSet = BarChartDataSet(values: dataEntries, label: "Games Played")
//let chartData = BarChartData(xVals: self.results, dataSet: dataEntries)
let chartData = BarChartData()
self.barChartView.xAxis.labelPosition = XAxis.LabelPosition.bottom
barChartView.leftAxis.granularityEnabled = true
barChartView.rightAxis.enabled = false
barChartView.leftAxis.granularity = 1.0
chartData.addDataSet(chartDataSet)
barChartView.data = chartData
}
// END OF CHART FUNCTION ***********
As you can see it is displaying numbers, rather than "Won, Drawn, Lost"
I believe this is because I need to assign the labels in a command like this:
let chartData = BarChartData(xVals: self.results, dataSet: dataSet)
chartView.data = chartData
But I get errors and I don't know what needs to go in dataSet as I took that solution from another thread and can't seem to amend it to work.
Temp image:
You have interchanges x and y values.
let dataEntry = BarChartDataEntry(x: Double(i), y: values[i])
And to get the X-Axis at the bottom, you have to add the following.
self.barChartView.xAxis.labelPosition = XAxis.LabelPosition.bottom
Please find my working code for a sample dataset.
class BarChartViewController: UIViewController {
#IBOutlet weak var barChartView: BarChartView!
override func viewDidLoad() {
super.viewDidLoad()
let values = [11.00, 90.95, 250.00, 40.90, 60.88, 99.99, 25.00]
setChart(values: values)
}
func setChart(values: [Double]) {
var daysEntries: [BarChartDataEntry] = []
for i in 0..<values.count {
let dataEntry = BarChartDataEntry(x : Double(i), y : values[i])
daysEntries.append(dataEntry)
}
let data = BarChartData()
let ds1 = BarChartDataSet(values: daysEntries, label: "Days")
ds1.colors = [NSUIColor.red]
data.addDataSet(ds1)
self.barChartView.data = data
self.barChartView.gridBackgroundColor = NSUIColor.white
self.barChartView.chartDescription?.text = "Barchart Days and Gross"
self.barChartView.rightAxis.enabled = true
self.barChartView.xAxis.labelPosition = XAxis.LabelPosition.bottom
self.barChartView.xAxis.axisRange = 5.0
}
override func viewWillAppear(_ animated: Bool) {
self.barChartView.animate(xAxisDuration: 1.0, yAxisDuration: 1.0)
}
}
Thanks
Sriram
I had the same issue and I fixed it with these three lines :
self.xAxis.granularity = 1
self.xAxis.granularityEnabled = true
self.xAxis.labelCount = // number of points on X axis
// xAxis.labelFont = UIFont.systemFont(ofSize: 13.0)
// xAxis.labelTextColor = .lightGray
xAxis.labelPosition = .bottom
xAxis.setLabelCount(dataPoints.count, force: false)
if xAxis.labelPosition == .bottom {
xAxis.valueFormatter = IndexAxisValueFormatter(values: dataPoints)
}
xAxis.granularity = 1.0
I hope this would help you with controlling the xAxis label positions.
First method
chartView.setExtraOffsets(left: 20, top: 0, right: 0, bottom: 0)
Second method
chartView.xAxis.avoidFirstLastClippingEnabled = true

Pie chart using Charts library with swift

I am integrating pie chart in my app using Charts library and getting issue with chart data my code is
import UIKit
import Charts
class ViewController: UIViewController {
#IBOutlet weak var pieChartView: PieChartView!
override func viewDidLoad() {
super.viewDidLoad()
let months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun"]
let unitsSold = [10.0, 4.0, 6.0, 3.0, 12.0, 16.0]
setChart(dataPoints: months, values: unitsSold)
}
func setChart(dataPoints: [String], values: [Double]) {
var dataEntries: [ChartDataEntry] = []
for i in 0..<dataPoints.count {
let dataEntry1 = ChartDataEntry(x: Double(i), y: values[i], data: dataPoints[i] as AnyObject)
dataEntries.append(dataEntry1)
}
print(dataEntries[0].data)
let pieChartDataSet = PieChartDataSet(values: dataEntries, label: "Units Sold")
let pieChartData = PieChartData(dataSet: pieChartDataSet)
pieChartView.data = pieChartData
var colors: [UIColor] = []
for _ in 0..<dataPoints.count {
let red = Double(arc4random_uniform(256))
let green = Double(arc4random_uniform(256))
let blue = Double(arc4random_uniform(256))
let color = UIColor(red: CGFloat(red/255), green: CGFloat(green/255), blue: CGFloat(blue/255), alpha: 1)
colors.append(color)
}
pieChartDataSet.colors = colors
}
}
and when run app I getting something this
but I need pie chart in full data records like in below screen shot
Update for this question.
func updateChartData() {
let chart = PieChartView(frame: self.view.frame)
// 2. generate chart data entries
let track = ["Income", "Expense", "Wallet", "Bank"]
let money = [650, 456.13, 78.67, 856.52]
var entries = [PieChartDataEntry]()
for (index, value) in money.enumerated() {
let entry = PieChartDataEntry()
entry.y = value
entry.label = track[index]
entries.append( entry)
}
// 3. chart setup
let set = PieChartDataSet( values: entries, label: "Pie Chart")
// this is custom extension method. Download the code for more details.
var colors: [UIColor] = []
for _ in 0..<money.count {
let red = Double(arc4random_uniform(256))
let green = Double(arc4random_uniform(256))
let blue = Double(arc4random_uniform(256))
let color = UIColor(red: CGFloat(red/255), green: CGFloat(green/255), blue: CGFloat(blue/255), alpha: 1)
colors.append(color)
}
set.colors = colors
let data = PieChartData(dataSet: set)
chart.data = data
chart.noDataText = "No data available"
// user interaction
chart.isUserInteractionEnabled = true
let d = Description()
d.text = "iOSCharts.io"
chart.chartDescription = d
chart.centerText = "Pie Chart"
chart.holeRadiusPercent = 0.2
chart.transparentCircleColor = UIColor.clear
self.view.addSubview(chart)
}
The reason all the information isn't showing up is because you are using a parent initialiser when creating the entry point.
Instead of
let dataEntry1 = ChartDataEntry(x: Double(i), y: values[i], data: dataPoints[i] as AnyObject)
try this instead
let dataEntry1 = PieChartDataEntry(value: Double(i), label: dataPoints[i], data: dataPoints[i] as AnyObject)
The PieChartDataEntry is specifically for Pie charts so you should see the month show up in the chart.
Hopefully this gets you on the right track

danielgindi/iOSCharts chartValueSelected not called

I am using danielgindi/iOSCharts library to crate combined line&bar charts like below.
My chart is rendered correctly and it has user interactions like tap and pinch zoom. Also chart is able to detect my tap gesture. But somehow
func chartValueSelected(chartView: ChartViewBase, entry: ChartDataEntry, dataSetIndex: Int, highlight: Highlight){
print("###################")
}
cannot be called. Really need some help here.
What I want to implement is that both balloon mark with same X value would show if I click on either a bar or a point on line. (both mark in above two pictures will display at same time when I tap a bar or a point)
Below is my entire controller code:
class FirstViewController: UIViewController,ChartViewDelegate {
#objc(ChartFormatter)
public class ChartFormatter: NSObject, IAxisValueFormatter{
var months: [String]! = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
public func stringForValue(_ value: Double, axis: AxisBase?) -> String {
return months[Int(value)]
}
}
#IBOutlet weak var chartView: CombinedChartView!
var lineChartData = LineChartData()
var barChartData = BarChartData()
override func viewDidLoad() {
super.viewDidLoad()
chartView.delegate = self
chartView.chartDescription?.enabled = true
chartView.dragEnabled = true
chartView.setScaleEnabled(true)
chartView.pinchZoomEnabled = true
chartView.drawGridBackgroundEnabled = false
let xAxis:XAxis = chartView.xAxis
xAxis.labelPosition = .bottom
xAxis.labelFont = UIFont.systemFont(ofSize: 11.0)
xAxis.labelTextColor = UIColor.black
xAxis.drawGridLinesEnabled = true
xAxis.drawAxisLineEnabled = false
xAxis.drawLabelsEnabled = false
let leftAxis:YAxis = chartView.leftAxis;
leftAxis.labelTextColor = UIColor(red: 1, green: 165/255, blue: 0, alpha: 1)
leftAxis.axisMaximum = 5.0
leftAxis.axisMinimum = -5.0
leftAxis.drawGridLinesEnabled = false
leftAxis.drawZeroLineEnabled = true
leftAxis.granularityEnabled = true
leftAxis.drawLabelsEnabled = false
let rightAxis:YAxis = chartView.rightAxis
rightAxis.enabled = false
let credit: [Double] = [1.0, 4.0, 2.0, 3.0, 3.0, 1.0, 3.0, 0.0, 0.0, 0.0, 0.0]
let gpa: [Double] = [-1.0, -4.0, -1.5, -1.4, -1.3, -1.0, -3.0, 0.0, 0.0, 0.0, 0.0]
let chartDescription = ""
let marker = BalloonMarker(color: UIColor(white: 180/255, alpha: 1.0), font: UIFont.systemFont(ofSize:12.0), textColor: UIColor.white, insets: UIEdgeInsetsMake(8.0, 8.0, 20.0, 8.0))
marker.chartView = chartView
marker.minimumSize = CGSize(width:80.0, height:40.0)
chartView.marker = marker
self.setLineChart(dataPoints: gpa, chartDescription: chartDescription)
self.setBarChart(dataPoints: credit)
self.setChartData()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func setLineChart(dataPoints: [Double], chartDescription: String) {
let formatter:ChartFormatter = ChartFormatter()
let xaxis:XAxis = XAxis()
var dataEntries: [ChartDataEntry] = Array()
for i in 0..<dataPoints.count {
let dataEntry = ChartDataEntry(x: Double(i), y: dataPoints[i])
dataEntries.append(dataEntry)
formatter.stringForValue(Double(i), axis: xaxis)
}
let lineChartDataSet = LineChartDataSet(values: dataEntries, label: "Credit")
self.lineChartData = LineChartData(dataSet: lineChartDataSet)
xaxis.valueFormatter = formatter
chartView.xAxis.valueFormatter = xaxis.valueFormatter
xaxis.drawGridLinesEnabled = false
lineChartDataSet.mode = .linear
lineChartDataSet.drawCirclesEnabled = false
lineChartDataSet.drawValuesEnabled = false
lineChartDataSet.colors = [UIColor.brown]
chartView.descriptionText = chartDescription
}
func setBarChart(dataPoints: [Double]) {
let formatter:ChartFormatter = ChartFormatter()
let xaxis:XAxis = XAxis()
var dataEntries: [BarChartDataEntry] = Array()
for i in 0..<dataPoints.count {
let dataEntry = BarChartDataEntry(x: Double(i), y: dataPoints[i])
dataEntries.append(dataEntry)
formatter.stringForValue(Double(i), axis: xaxis)
}
let barChartDataSet = BarChartDataSet(values: dataEntries, label: "GPA")
self.barChartData = BarChartData(dataSet: barChartDataSet)
xaxis.valueFormatter = formatter
chartView.xAxis.valueFormatter = xaxis.valueFormatter
xaxis.drawGridLinesEnabled = false
barChartDataSet.drawValuesEnabled = false
}
func setChartData() {
let data:CombinedChartData = CombinedChartData()
data.lineData = self.lineChartData
data.barData = self.barChartData
chartView.data = data
chartView.data?.highlightEnabled = true
//chartView.autoScaleMinMaxEnabled = true
//chartView.setNeedsDisplay()
}
#objc func chartValueSelected(chartView: ChartViewBase, entry: ChartDataEntry, dataSetIndex: Int, highlight: Highlight){
print("###################")
}
#objc func chartValueNothingSelected(chartView: ChartViewBase){
NSLog("chartValueNothingSelected");
}
}
Chiming in very late here, but the method signature has changed in Swift 3.0 (see this answer), and no longer includes dataSetIndex.
You should be able to see this firing in the console by changing your function signature (and implementation) to the following:
func chartValueSelected(chartView: ChartViewBase, entry: ChartDataEntry, highlight: Highlight){
print("###################")
}
Now it's
func chartValueSelected(_ chartView: ChartViewBase, entry: ChartDataEntry, highlight: Highlight){
print("Point: \(entry.x) Value: \(entry.y)")
}

Swift BAD ACCESS Code = 2

I'm trying to create an app that displays headlines from the NY Times politics section on 2/3 of a view on an AppleTV and shows a line chart above a pie chart on the other 1/3 of the view. I've written two separate programs, one that shows the headlines and one that shows the charts, but when trying to combine them I'm running into this error of
"BAD ACCESS"
at the line.
pieChartView!.holeColor = UIColor(hue: 0.0111, saturation: 0.15, brightness: 1, alpha: 1.0)
pieChartView!.descriptionText = ""
Any insight would be appreciated, thanks!
import UIKit
import Charts
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
#IBOutlet weak var table: UITableView!
#IBOutlet weak var pieChartView: PieChartView?
#IBOutlet weak var lineChartView: LineChartView?
let baseURL = "http://api.nytimes.com/svc/topstories/v1/politics.json?api-key=dd56f74b26c444f497b4588fd2944146"
var headlines = [String]()
var bernieSanders = [String]()
var hillaryClinton = [String]()
var donaldTrump = [String]()
var bernieCount: Double = 0.0
var hillaryCount: Double = 0.0
var donaldCount: Double = 0.0
var headlineCount = [Double]()
override func viewDidLoad() {
super.viewDidLoad()
let candidates = ["Sanders", "Clinton", "Trump"]
self.getJSON()
sleep(2)
setChart(candidates, values: headlineCount)
sleep(2)
self.table.registerClass(UITableViewCell.self, forCellReuseIdentifier: "cell")
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func getJSON() {
let url = NSURL(string: baseURL)
let request = NSURLRequest(URL: url!)
let session = NSURLSession(configuration: NSURLSessionConfiguration.defaultSessionConfiguration())
let task = session.dataTaskWithRequest(request){ (data, response, error) -> Void in
if error == nil {
let SwiftyJSON = JSON(data: data!)
let theTitle = SwiftyJSON["results"].arrayValue
for title in theTitle {
let titles = title["title"].stringValue
self.headlines.append(titles)
}
for headline in self.headlines {
if headline.lowercaseString.rangeOfString("sanders") != nil {
self.bernieSanders.append(headline)
}
if headline.lowercaseString.rangeOfString("clinton") != nil {
self.hillaryClinton.append(headline)
}
if headline.lowercaseString.rangeOfString("trump") != nil {
self.donaldTrump.append(headline)
}
}
self.bernieCount = Double(self.bernieSanders.count)
self.hillaryCount = Double(self.hillaryClinton.count)
self.donaldCount = Double(self.donaldTrump.count)
self.headlineCount.append(self.bernieCount)
self.headlineCount.append(self.hillaryCount)
self.headlineCount.append(self.donaldCount)
print("Number Of Headlines That Mention Each Candidate")
print("Bernie: \(self.bernieCount)")
print("Hillary: \(self.hillaryCount)")
print("Donald: \(self.donaldCount)\n")
print(self.headlines)
}
else {
print("there was an error")
}
}
task.resume()
}
// From the UITAbleViewDataSource
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return headlines.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = self.table.dequeueReusableCellWithIdentifier("cell")! as UITableViewCell
cell.textLabel!.text = self.headlines[indexPath.row]
cell.textLabel!.font = UIFont(name:"Avenir", size:25)
return cell
}
// From the UITableViewDelegate
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
print("You tapped on cell # \(indexPath.row)")
}
func setChart(dataPoints: [String], values: [Double]) {
var dataEntries: [ChartDataEntry] = []
for i in 0..<dataPoints.count {
let dataEntry = ChartDataEntry(value: (values[i]), xIndex: i)
dataEntries.append(dataEntry)
}
let pieChartDataSet = PieChartDataSet(yVals: dataEntries, label: "")
let pieChartData = PieChartData(xVals: dataPoints, dataSet: pieChartDataSet)
pieChartView!.backgroundColor = UIColor(hue: 0.0111, saturation: 0.15, brightness: 1, alpha: 1.0)
pieChartView!.holeColor = UIColor(hue: 0.0111, saturation: 0.15, brightness: 1, alpha: 1.0)
pieChartView!.descriptionText = ""
pieChartView!.data = pieChartData
let blue = UIColor(hue: 0.6194, saturation: 1, brightness: 0.89, alpha: 1.0)
let lightblue = UIColor(hue: 0.5222, saturation: 1, brightness: 0.92, alpha: 1.0)
let red = UIColor(hue: 0, saturation: 1, brightness: 0.86, alpha: 1.0)
let colors: [UIColor] = [blue, lightblue, red]
// for _ in 0..<dataPoints.count {
// let red = Double(arc4random_uniform(256))
// let green = Double(arc4random_uniform(256))
// let blue = Double(arc4random_uniform(256))
//
// let color = UIColor(red: CGFloat(red/255), green: CGFloat(green/255), blue: CGFloat(blue/255), alpha: 1)
// colors.append(color)
// }
//
pieChartDataSet.colors = colors
let lineChartDataSet = LineChartDataSet(yVals: dataEntries, label: "NY Times Headlines")
let lineChartData = LineChartData(xVals: dataPoints, dataSet: lineChartDataSet)
lineChartDataSet.colors = [NSUIColor(hue: 0.3194, saturation: 1, brightness: 0.66, alpha: 1.0)]
lineChartDataSet.circleColors = [NSUIColor(hue: 0.3194, saturation: 1, brightness: 0.66, alpha: 1.0)]
lineChartView!.backgroundColor = UIColor(hue: 0.0111, saturation: 0.15, brightness: 1, alpha: 1.0)
lineChartView!.descriptionText = ""
lineChartView!.xAxis.labelPosition = .Bottom
lineChartView!.data = lineChartData
}
}
as #vadian suggested, I needed to set the class of the custom view accordingly.
For people who may also strand in this cryptic error: My Problem was that I changed the class of an outlet, but forgot to change it in the Storyboard-View. After the correct declaration of view and outlet, the error was gone.

Resources