Getting the right interval on the x-axis in IOS-Charts - swift

I am trying to exclusively display the points which I have data for on the x-axis. As shown in the example below, I only got data for point zero, but -1 and 1 are being displayed as well. How can I get rid of them?
func setChart(_ xValues: [String], yValuesLineChart: [Double], yValuesBarChart: [Double]) {
var yVals1 : [ChartDataEntry] = [ChartDataEntry]()
var yVals2 : [BarChartDataEntry] = [BarChartDataEntry]()
for i in 0..<xValues.count {
yVals1.append(ChartDataEntry(x: Double(i), y: yValuesLineChart[i]))
yVals2.append(BarChartDataEntry(x: Double(i), y: yValuesBarChart[i]))
}
let lineChartSet = LineChartDataSet(values: yVals1, label: "")
let barChartSet: BarChartDataSet = BarChartDataSet(values: yVals2, label: "")
combinedChartView.drawBarShadowEnabled = false
let data = CombinedChartData()
data.barData = BarChartData(dataSet: barChartSet)
data.lineData = LineChartData(dataSet: lineChartSet)
combinedChartView.xAxis.granularityEnabled = true
combinedChartView.xAxis.granularity = 1.0
combinedChartView.xAxis.decimals = 0
combinedChartView.leftAxis.axisMinimum = 0
combinedChartView.rightAxis.axisMinimum = 0
combinedChartView.chartDescription?.text = ""
combinedChartView.drawGridBackgroundEnabled = false
combinedChartView.xAxis.labelPosition = .bottom
combinedChartView.leftAxis.drawGridLinesEnabled = false
combinedChartView.rightAxis.drawGridLinesEnabled = false
combinedChartView.xAxis.drawGridLinesEnabled = false
combinedChartView.leftAxis.drawZeroLineEnabled = false
combinedChartView.rightAxis.drawZeroLineEnabled = false
barChartSet.axisDependency = .right
lineChartSet.axisDependency = .left
combinedChartView.rightAxis.axisMaximum = barChartSet.yMax*1.4
combinedChartView.leftAxis.axisMaximum = lineChartSet.yMax*1.2
combinedChartView.data = data
combinedChartView.animate(xAxisDuration: 2.0, yAxisDuration: 2.0, easingOption: .easeInCubic)
}

Write an extension for your ViewController that will just display an empty string if you have no value.
extension YourChartViewController:IAxisValueFormatter {
func stringForValue(_ value: Double, axis: AxisBase?) -> String {
if value == 0.0
return ""
} else {
return String(Int(value))
}
}
}

Related

NSLayoutManager for Line Numbering in UITextVIew

I am attempting to create an iOS LineNumberLayoutManger in Swift to be used in a TextKit 2 UITextView. My problem is the line number variable is being overwritten when I enter a new line with the return key. The revised code sample below can be copied and pasted into an Xcode project in a ViewController to run. Any suggestions very much appreciated.
// ViewController.swift
// tester11
//
// Created by ianshortreed on 2022/07/15.
//
import UIKit
var currentRect:CGRect!
var cgPoint:CGPoint!
extension String {
func substring(with range: NSRange) -> String {
let startIndex = index(self.startIndex, offsetBy: range.location)
let endIndex = index(startIndex, offsetBy: range.length)
//return substring(with: startIndex ..< endIndex)
return String(self[startIndex..<endIndex])
}
}
extension Collection {
var enumerated: Zip2Sequence<PartialRangeFrom<Int32>, Self> { zip(1..., self) }
}
class ViewController: UIViewController, UITextViewDelegate {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
createTextView()
}
func createTextView() {
var textView: UITextView!
var textStorage: NSTextStorage!
// 1
let attrs = [NSAttributedString.Key.font: UIFont.preferredFont(forTextStyle: .body), .foregroundColor: UIColor.label]
let attrString = NSAttributedString(string: "Press the return key to add a new line.", attributes: attrs)
textStorage = NSTextStorage()
textStorage.append(attrString)
let newTextViewRect = view.bounds
// 2
//let layoutManager = LineNumberLayoutManager()
let layoutManager = LineNumberLayoutManager()
// 3
let containerSize = CGSize(width: newTextViewRect.width, height: .greatestFiniteMagnitude)
let container = NSTextContainer(size: containerSize)
container.widthTracksTextView = true
layoutManager.addTextContainer(container)
textStorage.addLayoutManager(layoutManager)
// 4
textView = UITextView(frame: newTextViewRect, textContainer: container)
textView.delegate = self
textView.isScrollEnabled = true
textView.textContainerInset = .zero
textView.textContainer.lineFragmentPadding = 9.5
//textView.layoutManager.usesFontLeading = false
textView.keyboardDismissMode = .interactive
textView.textContainerInset = UIEdgeInsets(top: 50, left: 10, bottom: 0, right: 10)
textView.typingAttributes = [NSAttributedString.Key.foregroundColor: UIColor.black, NSAttributedString.Key.font: UIFont.systemFont(ofSize: 17)]
textView.textAlignment = NSTextAlignment.justified
textView.allowsEditingTextAttributes = true
textView.isSelectable = true
textView.isUserInteractionEnabled = true
textView.dataDetectorTypes = .all
view.addSubview(textView)
// 5
textView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
textView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
textView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
textView.topAnchor.constraint(equalTo: view.topAnchor),
textView.bottomAnchor.constraint(equalTo: view.bottomAnchor)
])
}
class LineNumberLayoutManager: NSLayoutManager {
let lineSize = CGSize(width: 8, height: 8)
var lineColor = UIColor(red:1.00, green:1.00, blue:1.00, alpha:1.0)
override func drawGlyphs(forGlyphRange glyphsToShow: NSRange, at origin: CGPoint) {
var linenumber = 0
super.drawGlyphs(forGlyphRange: glyphsToShow, at: origin)
guard let textStorage = self.textStorage else { return }
enumerateLineFragments(forGlyphRange: glyphsToShow) { [self] (rect, usedRect, textContainer, glyphRange, _) in
linenumber += 1
let origin = CGPoint(x: 10, y: usedRect.origin.y + 48 + (usedRect.size.height - self.lineSize.height) / 2)
var newLineRange = NSRange(location: 0, length: 0)
if glyphRange.location > 0 {
newLineRange.location = glyphRange.location - 1
newLineRange.length = 1
}
var isNewLine = true
if newLineRange.length > 0 {
isNewLine = textStorage.string.substring(with: newLineRange) == "\n"
}
if isNewLine {
let str = textStorage.string.components(separatedBy: .newlines)
"\(linenumber)\(str)".draw(in:CGRect(origin: origin, size: lineSize))
}
}
}
}
}

Displaying Data in ios Charts

I am creating an ios Chart that is based off of documents in Firestore. Here is my code:
import UIKit
import Charts
import Firebase
import FirebaseFirestoreSwift
import FirebaseAuth
class YearChartViewController: UIViewController, ChartViewDelegate {
enum valetTimeCategory: String{
typealias RawValue = String
case Year = "Year"
case Month = "Month"
case DaysOfWeeks = "Day1"
case CalendarDays = "Day2"
case Hour = "Hour"
}
var selectedCategory = valetTimeCategory.Year.rawValue
private var yearListener: ListenerRegistration!
#IBOutlet weak var segmentedController: UISegmentedControl!
var timeRetrieval = [timeData]()
var timeRetrievalYear = [yearTimeData]()
var barChart = BarChartView()
var pieChart = PieChartView()
lazy var companyUser = ""
#IBOutlet weak var localeIdLabel: UILabel!
private var timeDataCollection: CollectionReference!
var documentName1 = ""
override func viewDidLoad() {
super.viewDidLoad()
barChart.delegate = self
pieChart.delegate = self
localeIdLabel.text = companyUser
timeDataCollection = Firestore.firestore().collection("users").document(companyUser ).collection("time_data")
}
#IBAction func valetTimeCategory3(_ sender: Any) {
switch segmentedController.selectedSegmentIndex {
case 0:
selectedCategory = valetTimeCategory.Year.rawValue
case 1:
selectedCategory = valetTimeCategory.Month.rawValue
case 2:
selectedCategory = valetTimeCategory.DaysOfWeeks.rawValue
case 3: selectedCategory = valetTimeCategory.CalendarDays.rawValue
case 4: selectedCategory = valetTimeCategory.Hour.rawValue
default:
valetTimeCategory.Year.rawValue
}
self.yearListener.remove()
setListener()
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
setListener()
}
func setListener() {
barChart.frame = CGRect(x: 0, y: 0, width: 250, height: 250)
barChart.center = view.center
view.addSubview(barChart)
var entries = [BarChartDataEntry]()
yearListener = timeDataCollection.whereField(selectedCategory, isNotEqualTo: "Yaguay").order(by: selectedCategory).addSnapshotListener{ (querySnapshot, error) in
if let err = error {
debugPrint("Error fetching docs: \(err)")
} else {
self.timeRetrieval.removeAll()
guard let snap = querySnapshot else { return }
for document in snap.documents {
let FirebaseData = document.data()
let tiempoEs1 = FirebaseData["Year"] as? String ?? ""
let tiempoEs2 = FirebaseData["Month"] as? String ?? ""
let tiempoEs3 = FirebaseData["Day1"] as? String ?? ""
let tiempoEs4 = FirebaseData["Hour"] as? String ?? ""
let tiempoEs5 = FirebaseData["Day2"] as? String ?? ""
let documentIdThird = document.documentID
let newTimeRetrieval = timeData(timeContinuum1: tiempoEs1, timeContinuum2: tiempoEs2, timeContinuum3: tiempoEs3, timeContinuum4: tiempoEs4, timeContinuum5: tiempoEs5, documentId3: documentIdThird);
let newYearRetrieval = yearTimeData(timeContinuumYear: tiempoEs1)
self.timeRetrieval.append(newTimeRetrieval)
self.timeRetrievalYear.append(newYearRetrieval);
if self.selectedCategory == valetTimeCategory.Year.rawValue {
let q = Int(tiempoEs1)
let b = q?.nonzeroBitCount
entries.append(BarChartDataEntry(x: Double(q!), y: Double(self.timeRetrieval.count)));
let set = BarChartDataSet(entries: entries
)
set.colors = ChartColorTemplates.joyful()
let data = BarChartData(dataSet: set)
self.barChart.data = data
let format = NumberFormatter()
format.numberStyle = .decimal
let formatter = DefaultValueFormatter(formatter: format)
data.setValueFormatter(formatter)
self.barChart.legendRenderer.computeLegend(data: BarChartData(dataSet: set))
self.barChart.chartDescription?.text = "Years"
self.yearListener.remove()
}
if self.selectedCategory == valetTimeCategory.Month.rawValue {
let d = tiempoEs2.hashValue.nonzeroBitCount
entries.append(BarChartDataEntry(x: Double(d), y: Double(self.timeRetrieval.count)));
let set = BarChartDataSet(entries: entries, label: "\(self.selectedCategory)"
)
print(self.selectedCategory)
set.colors = ChartColorTemplates.joyful()
let data = BarChartData(dataSet: set)
self.barChart.data = data
self.yearListener.remove()
}
if self.selectedCategory == valetTimeCategory.DaysOfWeeks.rawValue {
let d = tiempoEs3.hashValue.nonzeroBitCount
entries.append(BarChartDataEntry(x: Double(d), y: Double(self.timeRetrieval.count)));
let set = BarChartDataSet(entries: entries, label: "\(self.selectedCategory)"
)
print(self.selectedCategory)
set.colors = ChartColorTemplates.joyful()
let data = BarChartData(dataSet: set)
self.barChart.data = data
self.yearListener.remove()
}
if self.selectedCategory == valetTimeCategory.CalendarDays.rawValue {
let q = Int(tiempoEs5)
let b = q?.nonzeroBitCount
entries.append(BarChartDataEntry(x: Double(b!), y: Double(self.timeRetrieval.count)));
let set = BarChartDataSet(entries: entries, label: "\(self.selectedCategory)"
)
print(self.selectedCategory)
set.colors = ChartColorTemplates.joyful()
let data = BarChartData(dataSet: set)
self.barChart.data = data
self.yearListener.remove()
}
if self.selectedCategory == valetTimeCategory.Hour.rawValue {
let q = tiempoEs4.hashValue.nonzeroBitCount
entries.append(BarChartDataEntry(x: Double(q), y: Double(self.timeRetrieval.count)));
let set = BarChartDataSet(entries: entries, label: "\(self.selectedCategory)"
)
print(self.selectedCategory)
set.colors = ChartColorTemplates.joyful()
let data = BarChartData(dataSet: set)
self.barChart.data = data
self.yearListener.remove()
}
}
}
}
}
#IBAction func monthButton1Tapped(_ sender: Any) {
self.companyUser = localeIdLabel.text!
performSegue(withIdentifier: "Month", sender: self)
}
#IBAction func logout(_ sender: Any) {
let auth = Auth.auth()
do {
try auth.signOut()
transitionToHome()
} catch let signOutError as Error {
debugPrint(signOutError)
}
}
func transitionToHome() {
let homeViewController = storyboard?.instantiateViewController(identifier: Constants.Storyboard.homeViewController)
view.window?.rootViewController = homeViewController
view.window?.makeKeyAndVisible()
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let vc = segue.destination as! MonthChartViewController
vc.documentName = self.companyUser
}
}
Hopefully the random, nonsensical names aren't too distracting, but my problem is my Bar Chart isn't exactly displaying the right data. When I run the code, it displays:
Chart Image
There are 22 items (documents) in my collection. So it explicitly displays 22 objects, and if you count the numbers on each bar, the count on each bar is the correct number in each category (5 for 2020 and 17 for 2021). I don't know how to get my bar chart to explicitly display "17" and "5" for each category, please help if you know how to solve this.
timeRetrieval is appending additional entries each loop without clearing the previous entries. This is why the second bar has exactly the sum total.
You have a line self.timeRetrieval.removeAll() that is above the start of your for loop. Moving this line inside the loop should resolve this behavior.

ios-charts xaxis labels not lining up

I have created a grouped bar chart with pretty simple values. I have 5 labels which I would like spread out along the xaxis and 3 bar groups to coincide with each xaxis label.
The graph right now shows 1 xaxis label and 1 bar. (they may be out of frame, it's hard to tell.) I need each case to sync up with the correct msArrayAxis label.
Here is the code:
var msArrayXAxis = ["0-20", "20-50", "50-100", "100-200", "<200"]
barchartView.isUserInteractionEnabled = false
barchartView.noDataText = "You need to provide data for the chart."
barchartView.legend.enabled = false
barchartView.chartDescription?.text = ""
barchartView.xAxis.labelPosition = XAxis.LabelPosition.bottom
barchartView.xAxis.valueFormatter = IndexAxisValueFormatter(values: msArrayXAxis)
barchartView.xAxis.axisMinimum = 0
barchartView.xAxis.granularity = 2
barchartView.xAxis.setLabelCount(5, force: true)
barchartView.xAxis.spaceMin = 0.3
// barchartView.extraBottomOffset = 1
barchartView.xAxis.labelWidth = 1
barchartView.xAxis.avoidFirstLastClippingEnabled = true
barchartView.rightAxis.drawGridLinesEnabled = false
barchartView.rightAxis.drawAxisLineEnabled = false
barchartView.rightAxis.drawLabelsEnabled = false
func parsedArrayCount(case1: Array<Double>,case2: Array<Double>,case3: Array<Double>,case4: Array<Double>, case5: Array<Double>) -> [BarChartDataEntry] {
var dataEntries1: [BarChartDataEntry] = []
NSLog("Parsing array count")
let dataEntry = BarChartDataEntry(x: Double(0), y:Double(case1.count))
dataEntries1.append(dataEntry)
let dataEntry2 = BarChartDataEntry(x: Double(1), y:Double(case2.count))
dataEntries1.append(dataEntry2)
let dataEntry3 = BarChartDataEntry(x: Double(2), y:Double(case3.count))
dataEntries1.append(dataEntry3)
let dataEntry4 = BarChartDataEntry(x: Double(3), y:Double(case4.count))
dataEntries1.append(dataEntry4)
let dataEntry5 = BarChartDataEntry(x: Double(1), y:Double(case5.count))
dataEntries1.append(dataEntry5)
return dataEntries1
}
func updateGraph(array: Array<name>?) {
var dataEntries1: [BarChartDataEntry] = []
var dataEntries2: [BarChartDataEntry] = []
var dataEntries3: [BarChartDataEntry] = []
barchartView.clear()
rArray.removeAll()
nameArray.removeAll()
if array != nil && array!.count > 0 {
for i in 0..<array!.count {
rArray.append(array![i].r)
nameArray.append(array![i].name)
}
NSLog("updating graph..")
let name = Analyzer.sharedInstance.nameArray(names: rArray.map{String($0)}, Name: nameArray)
let cData = parserArrays(rArray: name.first.map {Double($0)!})
let wData = parserArrays(rArray: name.last.map {Double($0)!})
let vData = parserArrays(rArray: name.middle.map {Double($0)!})
dataEntries1 = parsedArrayCount(case1: cData.case1, case2: cData.case2, case3: cData.case3, case4: cData.case4, case5: cData.case5)
dataEntries2 = parsedArrayCount(case1: wData.case1, case2: wData.case2, case3: wData.case3, case4: wData.case4, case5: wData.case5)
dataEntries3 = parsedArrayCount(case1: vData.case1, case2: vData.case2, case3: vData.case3, case4: vData.case4, case5: vData.case5)
let chartDataSet = BarChartDataSet(values: dataEntries1, label: "")
chartDataSet.colors = [UIColor.Blue()]
let chartDataSet1 = BarChartDataSet(values: dataEntries2, label: "")
chartDataSet1.colors = [UIColor.Green()]
let chartDataSet2 = BarChartDataSet(values: dataEntries3, label: "")
chartDataSet2.colors = [UIColor.Orange()]
NSLog("Data set1 \(dataEntries1)")
let groupSpace = 1.0
let barSpace = 0.05
let barWidth = 0.1
/* let xAxis = XAxis()
xAxis.valueFormatter = self
xAxis.drawGridLinesEnabled = true
xAxis.labelPosition = .bottom
xAxis.centerAxisLabelsEnabled = true
barchartView.xAxis.valueFormatter = xAxis.valueFormatter*/
let dataSets: [BarChartDataSet] = [chartDataSet,chartDataSet1]
let chartData = BarChartData(dataSets: dataSets)
chartData.setDrawValues(false)
chartData.barWidth = barWidth
chartData.groupBars(fromX:0.3, groupSpace: groupSpace, barSpace: barSpace)
// let gg = chartData.groupWidth(groupSpace: groupSpace, barSpace: barSpace)
// barchartView.xAxis.axisMaximum = Double(0) + gg * Double(msArrayXAxis.count)
barchartView.data = chartData
barchartView.animate(yAxisDuration: 0.5)
}
}
Please check :
var msArrayXAxis = ["0-20", "20-50", "50-100", "100-200", "<200"]
barChartView.isUserInteractionEnabled = false
barChartView.noDataText = "You need to provide data for the chart."
barChartView.legend.enabled = false
barChartView.chartDescription?.text = ""
barChartView.xAxis.labelPosition = XAxis.LabelPosition.bottom
barChartView.xAxis.valueFormatter = IndexAxisValueFormatter(values: msArrayXAxis)
barChartView.xAxis.axisMinimum = 0
barChartView.xAxis.granularity = 1
barChartView.xAxis.labelCount = msArrayXAxis.count
barChartView.xAxis.centerAxisLabelsEnabled = true
barChartView.xAxis.spaceMin = 0.3
barChartView.xAxis.labelWidth = 1
barChartView.rightAxis.drawGridLinesEnabled = false
barChartView.rightAxis.drawAxisLineEnabled = false
barChartView.rightAxis.drawLabelsEnabled = false
func parsedArrayCount(case1: Array<Double>,case2: Array<Double>,case3: Array<Double>,case4: Array<Double>, case5: Array<Double>) -> [BarChartDataEntry] {
var dataEntries1: [BarChartDataEntry] = []
NSLog("Parsing array count")
let dataEntry = BarChartDataEntry(x: Double(0), y:Double(case1.count))
dataEntries1.append(dataEntry)
let dataEntry2 = BarChartDataEntry(x: Double(1), y:Double(case2.count))
dataEntries1.append(dataEntry2)
let dataEntry3 = BarChartDataEntry(x: Double(2), y:Double(case3.count))
dataEntries1.append(dataEntry3)
let dataEntry4 = BarChartDataEntry(x: Double(3), y:Double(case4.count))
dataEntries1.append(dataEntry4)
let dataEntry5 = BarChartDataEntry(x: Double(1), y:Double(case5.count))
dataEntries1.append(dataEntry5)
return dataEntries1
}
func updateGraph() {
var dataEntries1: [BarChartDataEntry] = []
var dataEntries2: [BarChartDataEntry] = []
var dataEntries3: [BarChartDataEntry] = []
barChartView.clear()
NSLog("updating graph..")
let name = Analyzer.sharedInstance.nameArray(names: rArray.map{String($0)}, Name: nameArray)
let cData = parserArrays(rArray: name.first.map {Double($0)!})
let wData = parserArrays(rArray: name.last.map {Double($0)!})
let vData = parserArrays(rArray: name.middle.map {Double($0)!})
dataEntries1 = parsedArrayCount(case1: cData.case1, case2: cData.case2, case3: cData.case3, case4: cData.case4, case5: cData.case5)
dataEntries2 = parsedArrayCount(case1: wData.case1, case2: wData.case2, case3: wData.case3, case4: wData.case4, case5: wData.case5)
dataEntries3 = parsedArrayCount(case1: vData.case1, case2: vData.case2, case3: vData.case3, case4: vData.case4, case5: vData.case5)
let chartDataSet = BarChartDataSet(values: dataEntries1, label: "")
chartDataSet.colors = [UIColor.blue]
let chartDataSet1 = BarChartDataSet(values: dataEntries2, label: "")
chartDataSet1.colors = [UIColor.green]
let chartDataSet2 = BarChartDataSet(values: dataEntries3, label: "")
chartDataSet2.colors = [UIColor.orange]
NSLog("Data set1 \(dataEntries1)")
let groupSpace = 0.1
let barSpace = 0.05
let barWidth = 0.25
let dataSets: [BarChartDataSet] = [chartDataSet,chartDataSet1, chartDataSet2]
let chartData = BarChartData(dataSets: dataSets)
chartData.setDrawValues(false)
chartData.barWidth = barWidth
let gg = chartData.groupWidth(groupSpace: groupSpace, barSpace: barSpace)
barChartView.xAxis.axisMaximum = Double(0) + gg * Double(msArrayXAxis.count)
chartData.groupBars(fromX:0.0, groupSpace: groupSpace, barSpace: barSpace)
barChartView.notifyDataSetChanged()
barChartView.data = chartData
barChartView.animate(yAxisDuration: 0.5)
}

iOS Charts remove decimal from yValues

How to remove decimals from y values in iOS Charts?
Im using the latest iOS Charts release with Swift3
Thanks for every one who tried to help, here was the fix, adding the below code
let formatter = NumberFormatter()
formatter.numberStyle = .none
formatter.maximumFractionDigits = 0
formatter.multiplier = 1.0
chartData.valueFormatter = DefaultValueFormatter(formatter: formatter)
to the setBarChartData func
func setBarChartData(xValues: [String], yValues: [Double], label: String) {
var dataEntries: [BarChartDataEntry] = []
for i in 0..<yValues.count {
let dataEntry = BarChartDataEntry(x: Double(i), y: yValues[i])
dataEntries.append(dataEntry)
}
let chartDataSet = BarChartDataSet(values: dataEntries, label: label)
let chartData = BarChartData(dataSet: chartDataSet)
let formatter = NumberFormatter()
formatter.numberStyle = .none
formatter.maximumFractionDigits = 0
formatter.multiplier = 1.0
chartData.valueFormatter = DefaultValueFormatter(formatter: formatter)
let chartFormatter = BarChartFormatter(labels: xValues)
let xAxis = XAxis()
xAxis.valueFormatter = chartFormatter
self.xAxis.valueFormatter = xAxis.valueFormatter
self.data = chartData
}
Could also use:
let format = NumberFormatter()
format.numberStyle = .none
let formatter = DefaultValueFormatter(formatter: format)
data.setValueFormatter(formatter)
You need to set delegate for value formatter in DataSet like below
Obj-C :
//DataSet 1
LineChartDataSet *set1 = [[LineChartDataSet alloc] initWithValues:values label:#"outstanding"];
set1.valueFormatter = self;
Use below delegate method for formatting your value :
#pragma mark - IChartValueFormatter
- (NSString * _Nonnull)stringForValue:(double)value entry:(ChartDataEntry * _Nonnull)entry dataSetIndex:(NSInteger)dataSetIndex viewPortHandler:(ChartViewPortHandler * _Nullable)viewPortHandler{
//Format your value what you want here
return [NSString stringWithFormat:#"%0.f",value];
}
Confirm Protocol :
#interface YourViewController ()<ChartViewDelegate,IChartValueFormatter>
For Swift you need to create Extension of BarChart and use below methods in it
Swift :
extension BarChartView {
private class BarChartFormatter: NSObject, IAxisValueFormatter {
var labels: [String] = []
func stringForValue(_ value: Double, axis: AxisBase?) -> String {
return labels[Int(value)]
}
init(labels: [String]) {
super.init()
self.labels = labels
}
}
func setBarChartData(xValues: [String], yValues: [Double], label: String) {
var dataEntries: [BarChartDataEntry] = []
for i in 0..<yValues.count {
let dataEntry = BarChartDataEntry(x: Double(i), y: yValues[i])
dataEntries.append(dataEntry)
}
let chartDataSet = BarChartDataSet(values: dataEntries, label: label)
let chartData = BarChartData(dataSet: chartDataSet)
let chartFormatter = BarChartFormatter(labels: xValues)
let xAxis = XAxis()
xAxis.valueFormatter = chartFormatter
self.xAxis.valueFormatter = xAxis.valueFormatter
self.data = chartData
}
}
Call Above Extension Method like this :
func setChart(){
let months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
let unitsSold = [20.0, 4.0, 3.0, 6.0, 12.0, 16.0, 4.0, 18.0, 2.0, 4.0, 5.0, 4.0]
barChartView.setBarChartData(xValues: months, yValues: unitsSold, label: "Monthly Sales")
}
hope you will get your formatted value on line chart.
After lots of research and test. i was able to remove the decimal.
First unlock the pod chartViewBase
Remove two lines from the { } i.e 'digits' from chartViewBase pod.
Before:
if let formatter = defaultValueFormatter as? DefaultValueFormatter
{
// setup the formatter with a new number of digits
let digits = reference.decimalPlaces
formatter.decimals = digits
}
After:
if let formatter = defaultValueFormatter as? DefaultValueFormatter
{
}
It will look like following::

how to draw CombinedChart in ios-chart

I am using this lib for drawChart. Link: https://github.com/danielgindi/Charts
THis is my code. When i draw only CandleChart, it is OK.
But when I try to draw CombinedChart. I receiver this result.
This is my result
#IBOutlet weak var chart: CombinedChartView!
var date1 = [String]()
var open = [Double]()
var high = [Double]()
var low = [Double]()
var close = [Double]()
var volume = [Double]()
var adj_close = [Double]()
let gradientLayer = CAGradientLayer()
override func viewDidLoad() {
super.viewDidLoad()
loadVcs()
chart.delegate = self
chart.descriptionText = ""
chart.noDataTextDescription = ""
chart.drawGridBackgroundEnabled = false
chart.maxVisibleValueCount = 0
chart.pinchZoomEnabled = false
let xAxis = chart.xAxis
xAxis.labelPosition = ChartXAxis.XAxisLabelPosition.Bottom
xAxis.spaceBetweenLabels = 15
xAxis.drawLabelsEnabled = true
let leftAxis = chart.leftAxis
leftAxis.labelCount = 7
leftAxis.drawLabelsEnabled = false
leftAxis.drawAxisLineEnabled = false
let rightAxis = chart.rightAxis
rightAxis.drawGridLinesEnabled = true
rightAxis.enabled = true
setData()
}
override func viewWillAppear(animated: Bool) {
gradientLayer.frame = self.view.bounds
let color1 = UIColor.yellowColor().CGColor as CGColorRef
let color2 = UIColor(red: 1.0, green: 0, blue: 0, alpha: 1.0).CGColor as CGColorRef
let color3 = UIColor.clearColor().CGColor as CGColorRef
let color4 = UIColor(white: 0.0, alpha: 0.7).CGColor as CGColorRef
gradientLayer.colors = [color1, color2, color3, color4]
gradientLayer.locations = [0.0, 0.0, 1.0, 1.0]
// self.chart.layer.addSublayer(gradientLayer)
}
func loadVcs()
{
var csv :CSV?
do {
let path = NSBundle.mainBundle().pathForResource("FB", ofType: "csv")
csv = try CSV(name: path!)
if let data = csv {
for dict in data.rows
{
date1.insert(dict["Date"]!, atIndex: 0)
open.insert(Double(dict["Open"]!)!, atIndex: 0)
high.insert(Double(dict["High"]!)!, atIndex: 0)
low.insert(Double(dict["Low"]!)!, atIndex: 0)
close.insert(Double(dict["Close"]!)!, atIndex: 0)
volume.insert(Double(dict["Volume"]!)!, atIndex: 0)
adj_close.insert(Double(dict["Adj Close"]!)!, atIndex: 0)
}
}
} catch let error {
NSLog("\(error)")
}
}
func setData()
{
let data : CombinedChartData = CombinedChartData(xVals: date1)
data.candleData = generateCandleChartData(date1)
data.lineData = generateLineChartData(date1)
chart.data = data
}
func generateLineChartData(xVals : [String]) -> LineChartData
{
var d = LineChartData(xVals: xVals)
var lineVals = [ChartDataEntry]()
for i in 0 ..< date1.count
{
lineVals.append(ChartDataEntry(value: high[i], xIndex: i))
}
let lineChartDataSet : LineChartDataSet = LineChartDataSet(yVals: lineVals, label: "Line Data Set")
lineChartDataSet.setColor(UIColor.greenColor())
lineChartDataSet.lineWidth = 2.5
lineChartDataSet.drawCubicEnabled = true
lineChartDataSet.drawValuesEnabled = true
d.addDataSet(lineChartDataSet)
return d
}
func generateCandleChartData(xVals : [String]) -> CandleChartData
{
var d = CandleChartData(xVals: xVals)
var yVals = [ChartDataEntry]()
for i in 0 ..< date1.count
{
yVals.append(CandleChartDataEntry(xIndex: i, shadowH: high[i], shadowL: low[i], open: open[i] , close: close[i] ))
}
let set1 = CandleChartDataSet(yVals: yVals, label: "Data")
set1.axisDependency = ChartYAxis.AxisDependency.Left
set1.setColor(UIColor(white: (80/255), alpha: 1.0))
set1.shadowColor = UIColor.darkGrayColor()
set1.shadowWidth = 1
set1.decreasingColor = UIColor.redColor()
set1.decreasingFilled = true
set1.increasingColor = UIColor(red: 122/255, green: 242/255, blue: 84/255, alpha: 1)
set1.increasingFilled = true
set1.neutralColor = UIColor.blueColor()
d.addDataSet(set1)
return d
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func chartValueSelected(chartView: ChartViewBase, entry: ChartDataEntry, dataSetIndex: Int, highlight: ChartHighlight) {
NSLog("chartValueSelected")
}
func chartValueNothingSelected(chartView: ChartViewBase) {
NSLog("chartValueNoSelected")
}
Please help me :)
Please take a look at the ChartsDemo which is part of the library, there is combined chart for your reference.