ios-charts horizontal bar charts issues - ios

I experience a number of issues with the horizontal bar chart since I updated to the last version of ios-chart (3.0.0).
First thing is that I had labels for the x axis on the charts. With the new version of ios-charts I had to write my own formatter nevertheless only every second label get displayed now. The second problem is that the bar does not reach the value indicated on the y-axis. What I mean by that is that if I give the bar a value of 4 the height of the bar is actually not long enough to reach the 4.0 label on the y-axis. Those 2 issues are illustrated in this picture.
picture of the problems
Here is my code for the value formatter:
#objc(BarChartFormatter)
public class BarChartFormatter: NSObject, IAxisValueFormatter{
var labelArray : [String] = ["text1", "text2", "text3", "text4", "text5", "text6", "text7", "text8", "text9", "text10"]
public func stringForValue(_ value: Double, axis: AxisBase?) -> String {
return labelArray[Int(value)]
}
}
And here is the code for the bar chart
horizontalBarChartView.noDataText = "You need to provide data for the chart."
horizontalBarChartView.isUserInteractionEnabled = false
horizontalBarChartView.drawGridBackgroundEnabled = false
horizontalBarChartView.drawValueAboveBarEnabled = false
horizontalBarChartView.legend.enabled = false
horizontalBarChartView.drawBarShadowEnabled = false
horizontalBarChartView.chartDescription?.text = ""
horizontalBarChartView.setExtraOffsets(left: 0, top: 0, right: 0, bottom: 0)
// Right y axis
let barRightAxis = horizontalBarChartView.leftAxis
barRightAxis.drawGridLinesEnabled = false
barRightAxis.enabled = false
let formato:BarChartFormatter = BarChartFormatter()
let xaxis:XAxis = XAxis()
// Left y axis
let barLeftAxis = horizontalBarChartView.rightAxis
let count = 5
barLeftAxis.setLabelCount(count, force: true)
barLeftAxis.drawGridLinesEnabled = false
barLeftAxis.axisLineWidth = 2
barLeftAxis.axisLineColor = UIColor.white
barLeftAxis.labelTextColor = UIColor.white
barLeftAxis.axisMinimum = 0.0
barLeftAxis.axisMaximum = 4.0
barLeftAxis.granularityEnabled = true
barLeftAxis.granularity = 1.0
barLeftAxis.decimals = 0
// x axis
let barXaXis = horizontalBarChartView.xAxis
barXaXis.drawGridLinesEnabled = false
barXaXis.axisLineColor = UIColor.white
barXaXis.axisLineWidth = 2
barXaXis.labelTextColor = UIColor.white
barXaXis.labelPosition = .bottomInside
barXaXis.granularityEnabled = true
barXaXis.granularity = 1.0
barXaXis.decimals = 0
var dataEntries: [BarChartDataEntry] = []
var colors: [UIColor] = []
let theScoreVec = [1.0, 2.0, 3.0, 4.0, 3.0, 0.0, 2.0, 0.0, 1.0, 4.0]
for i in 0..<10 {
let theScore = theScoreVec[i]
if (theScore == 0.0){
colors.append(UIColor.clear)
let dataEntry = BarChartDataEntry(x: Double(i), y : Double(4.0))
dataEntries.append(dataEntry)
} else {
colors.append(UIColor.red)
let dataEntry = BarChartDataEntry(x: Double(i), y: Double(theScore))
dataEntries.append(dataEntry)
}
}
xaxis.valueFormatter = formato
barXaXis.valueFormatter = xaxis.valueFormatter
for i in 0..<10{
formato.stringForValue(Double(i), axis: xaxis)
}
xaxis.valueFormatter = formato
barXaXis.valueFormatter = xaxis.valueFormatter
let chartDataSet = BarChartDataSet(values: dataEntries, label: "Completion")
chartDataSet.colors = colors
let chartData = BarChartData(dataSet: chartDataSet)
chartData.setDrawValues(false)
horizontalBarChartView.data = chartData
Here I also use some kind of hack because when one enters a value of 0.0 for a BarChartDataEntry the bars and the x axis have a significant offset. Therefore I create bars with a fake value and give them a transparent color.
Do one you had a similar issue with the library and know where it comes from ? Or maybe has even solved it ?
Thanks in advance for the help.

Related

How Charts BarChartView Custom Adjusted

Hi using cocoapods charts. Trying to pivot bar-chart from right to left. with hidden bottom x-axis values.
Charts
https://cocoapods.org/pods/Charts
Below is code which I tried.
totalExpenseAmount = 33 -> Double
timesheetAmount = 300 -> Double
self.setBarChart(expenseAmount: totalExpenseAmount, timesheetAmount: totalTimesheetAmount)
// MARK: - DRAW CHART
func setBarChart(expenseAmount: Double, timesheetAmount: Double){
var dataEntries: [BarChartDataEntry] = []
barChartView.backgroundColor = UIColor.white
for i in 0..<2 {
let dataEntry = BarChartDataEntry(x: Double(i), y: i == 0 ? expenseAmount : timesheetAmount)
dataEntries.append(dataEntry)
}
let chartDataSet = BarChartDataSet(entries: dataEntries)
chartDataSet.colors = [UIColor.init(hexString: "#008CA1") , UIColor.init(hexString: "#EF776C")]
let chartData = BarChartData()
chartData.barWidth = Double(0.25)
chartData.append(chartDataSet)
chartData.setDrawValues(true)
barChartView.xAxis.labelPosition = .bottom
barChartView.xAxis.drawGridLinesEnabled = false
barChartView.chartDescription.enabled = false
barChartView.legend.enabled = false
barChartView.rightAxis.enabled = false
barChartView.leftAxis.drawGridLinesEnabled = true
barChartView.leftAxis.drawLabelsEnabled = true
barChartView.data = chartData
barChartView.leftAxis.spaceBottom = 0.0
barChartView.notifyDataSetChanged()
}
I tried to pivot bar chart from right to left. with Hidden bottom x-axis values.
Issue is second bar chart for 33 value not shown.
Unable to drawn bar chart from right to left.
Unable to hide the x-axis labels values ( -0.3 0.0 0.3 0.6 0.9 1.2 1.5)
Any one worked on charts please provide your inputs, Its deeply appreciated your input's.

iOS Charts issue for Line Chart. Missing Alignment while zooming

I am having very hard time while implementing line chart. I am using latest Charts pod. When I zoom chart its not work properly. X-axis missing its coordinate.
I have attached both images.
// Make sure that only 1 x-label per index is shown
updatedCampaignEndDateArray = ["", "20-11", "28-11", "03-12", "04-12", "31-12"]
self.chartView.xAxis.granularityEnabled = true
self.chartView.xAxis.granularity = 1.0
self.chartView.xAxis.labelPosition = .top
self.chartView.xAxis.labelCount = self.updatedCampaignEndDateArray.count
self.chartView.xAxis.drawLabelsEnabled = true
self.chartView.xAxis.drawLimitLinesBehindDataEnabled = true
self.chartView.xAxis.avoidFirstLastClippingEnabled = true
self.chartView.xAxis.labelFont = UIFont.systemFont(ofSize: 8.0)
self.chartView.xAxis.setLabelCount(self.updatedCampaignEndDateArray.count, force: true)
self.chartView.xAxis.valueFormatter = DefaultAxisValueFormatter(block: {(index, _) in
return self.updatedCampaignEndDateArray[Int(index)]
})
self.chartView.xAxis.wordWrapEnabled = false
self.chartView.legend.form = .line
self.chartView.animate(xAxisDuration: 0.5)
acceptedArrayWithAddition = [0, 8, 0, 503, 551]
let values = (0..<self.pointCount + 1).map { (i) -> ChartDataEntry in
return ChartDataEntry(x: Double(i), y: Double(acceptedArrayWithAddition[Int(i)]))
let set = LineChartDataSet(values: values, label: "Leads")

IOS Bar Charts - How to show values (1.0,2.0 etc) label upon Bar Chart & show particular values (like 3 - 7) on Bar Chart Scroll

I am working On a Bar Chart in iOS Swift
Code:
let chartDataSet: BarChartDataSet!
chartDataSet = BarChartDataSet(values: dataEntries, label: "Rupee Date-->")
chartDataSet.colors = [AppColors.barChartColor]
chartDataSet.highlightColor = AppColors.barChartHighlightColor
chartDataSet.valueTextColor = UIColor.black
chartDataSet.values = dataEntries
let chartData = BarChartData(dataSet: chartDataSet)
chartData.setDrawValues(true)
cell.barChartView.drawValueAboveBarEnabled = true
cell.barChartView.xAxis.valueFormatter = IndexAxisValueFormatter(values:monthDateArray as! [String])
cell.barChartView.animate(xAxisDuration: 1.0, yAxisDuration: 1.0)
cell.barChartView.data = chartData
cell.barChartView.xAxis.granularity = 1.0
cell.barChartView.setVisibleXRange(minXRange: 7, maxXRange: 7)
cell.barChartView.leftAxis.axisMinimum = 0
cell.barChartView.drawValueAboveBarEnabled = true
Questions
How to show values above bars, like 4.0, 3.0 etc.
The bar always opens at 0 position. I want the bar to open always at the current date position, and on scrolling, we can show all data.
Try this extension:-
//Bar chart extensio to set custom xAxia and yAxis
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: [String], label: String) {
var dataEntries: [BarChartDataEntry] = []
for i in 0..<yValues.count {
let dataEntry = BarChartDataEntry(x: Double(i), y: Double(yValues[i])!)
dataEntries.append(dataEntry)
}
let chartDataSet = BarChartDataSet(values: dataEntries, label: label)
chartDataSet.colors = [NSUIColor(red: 0/255.0, green: 110/255.0, blue: 194/255.0, alpha: 1.0)]
chartDataSet.valueFont = NSUIFont.systemFont(ofSize: 13)
let chartData = BarChartData(dataSet: chartDataSet)
let chartFormatter = BarChartFormatter(labels: xValues)
let xAxis = XAxis()
xAxis.valueFormatter = chartFormatter
self.xAxis.valueFormatter = xAxis.valueFormatter
self.drawValueAboveBarEnabled = true
self.data = chartData
}
}
Call function:-
#IBOutlet var chartView: BarChartView!
...
chartView.setBarChartData(xValues: dates, yValues: Leads, label: "Leads")
Where dates and Leads are array of strings
Answer for Question 1
By Mr. Mahajan Code and some with this Functionality:-
Code:
cell.barChartView.xAxis.valueFormatter = IndexAxisValueFormatter(values:monthDateArray as! [String])
cell.barChartView.animate(xAxisDuration: 1.0, yAxisDuration: 1.0)
cell.barChartView.xAxis.granularity = 1.0
cell.barChartView.setVisibleXRange(minXRange: 7, maxXRange: 7)
cell.barChartView.leftAxis.axisMinimum = 0
cell.barChartView.xAxis.granularityEnabled = true
cell.barChartView.xAxis.drawGridLinesEnabled = false
cell.barChartView.xAxis.labelPosition = .bottom
cell.barChartView.chartDescription?.text = ""
cell.barChartView.rightAxis.enabled = false
cell.barChartView.animate(xAxisDuration: 2.0, yAxisDuration: 2.0, easingOption: .easeInOutQuart)
Answer for Question 2
Code:
let date = Date()
let formatter = DateFormatter()
formatter.dateFormat = "dd"
let result = formatter.string(from: date)
var myDoubleX = Double(result)
myDoubleX = myDoubleX! - 1.5
cell.barChartView.moveViewToX(myDoubleX!)
SWIFT 4.2
For the Daniel Gindi Chart if you want to add two different value at the top of the bar candle if you have noticed there are one stand alone properties in the BarChartDataEntry named icon you can convert your text in to image and add that image as an icon to populate at the top of the bar candle.
Here I have done the same thing with the CandleStickChartView and it's Base class is BarLineChartViewBase. You can access this properties in the BarChart too.
Let's focus on the code.
Here I have an array of the BloodPressure Readings which is having Systolic and Diastolic Value. and circulate the loop to make a CandleChartDataEntry / BarChartDataEntry
for (index, bloodPressure) in bloodPressureData.enumerated() {
let systolicDouble = bloodPressure.value.systolic.doubleValue.rounded(toPlaces: 0)
let diastolicDouble = bloodPressure.value.diastolic.doubleValue.rounded(toPlaces: 0)
let high = max(Int(systolicDouble), Int(diastolicDouble))
let low = min(Int(systolicDouble), Int(diastolicDouble))
let imageLabel = " \(Int(systolicDouble))-\(Int(diastolicDouble)) "
let label = UILabel(frame: CGRect(x: 0, y: 0, width: 40, height: 10))
label.numberOfLines = 0
label.textAlignment = .center
label.textColor = UIColor.black
label.backgroundColor = UIColor.clear
label.layer.cornerRadius = 3.0
label.font = UIFont(name: "Montserrat-Regular", size: 8.0)
label.text = imageLabel
label.sizeToFit()
let image = UIImage.imageWithLabel(label: label)
let dataEntry = CandleChartDataEntry(x: Double(index), shadowH: CGFloat(high), shadowL: CGFloat(low), open: CGFloat(high), close: CGFloat(low), icon: image)
let dataBarEntry = BarChartDataEntry(x: Double(index), y: CGFloat(high), icon: image)
entries.append(dataEntry)
}
Here I have created a separate UIImage extension which is rendering UILabel in to UIImage
extension UIImage {
class func imageWithLabel(label: UILabel) -> UIImage {
UIGraphicsBeginImageContextWithOptions(label.bounds.size, false, 0.0)
label.layer.render(in: UIGraphicsGetCurrentContext()!)
let img = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return img!
}
}
by that extension you can covert your text in to image and add that image as an icon while you are preparing your BarChartDataEntry/CandleChartDataEntry
Note: To make it clearly visible at the top of the candle you need to set the offset of the icon by using this property
let set1 = CandleChartDataSet(entries: entries, label: "Blood Pressure")
set1.iconsOffset = CGPoint(x: 0, y: -8)
set1.drawValuesEnabled = false // Disable drawable value
Here I am attaching the outcome of it:
Thank you
😄

Horizontal Bar chart labels positioned at the center

I have this simple implementation of charts for iOS. And I'm looking for a way to align the labels at the center of each bar.
What I've accomplished so far was to position the labels inside each bar. I'm stuck at this point, as I don't see any way to achieve centering the label.
Here is a screenshot of what I've accomplished.
A snippet of the code used to setup this view.
func prepareHorizontalBarChart() {
var entries1 = [BarChartDataEntry]()
var entries2 = [BarChartDataEntry]()
var entries3 = [BarChartDataEntry]()
let values:[String] = ["1/22", "1/25", "1/30"]
let bar1 = BarChartDataEntry(x: Double(0), y: Double(4), icon: nil, data: "1/22" as AnyObject)
entries1.append(bar1)
let bar2 = BarChartDataEntry(x: Double(1), y: Double(6))
entries2.append(bar2)
let bar3 = BarChartDataEntry(x: Double(2), y: Double(2))
entries3.append(bar3)
let set1 = BarChartDataSet(values: entries1, label: "test")
set1.drawIconsEnabled = false
let set2 = BarChartDataSet(values: entries2, label: "test")
set1.drawIconsEnabled = false
let set3 = BarChartDataSet(values: entries3, label: "test")
set1.drawIconsEnabled = false
set1.colors = [UIColor.purple]
set2.colors = [UIColor.magenta]
set3.colors = [UIColor.red]
let data = BarChartData(dataSets: [set1, set2, set3])
data.setValueFont(UIFont(name: "HelveticaNeue-Light", size: 10))
data.barWidth = 0.2
let formatter = NumberFormatter()
formatter.numberStyle = .none
formatter.maximumFractionDigits = 0
formatter.multiplier = 1.0
let defaultValueFormatter = DefaultValueFormatter(formatter: formatter)
data.setValueFormatter(defaultValueFormatter)
horizontalBarChart.zoomOut()
horizontalBarChart.fitBars = true
horizontalBarChart.data = data
horizontalBarChart.xAxis.drawGridLinesEnabled = false // disable horizontal grid lines
// horizontalBarChart.xAxis.enabled = false
horizontalBarChart.chartDescription?.enabled = false
horizontalBarChart.xAxis.valueFormatter = IndexAxisValueFormatter(values: values)
horizontalBarChart.xAxis.labelPosition = .bottom
horizontalBarChart.rightAxis.enabled = false
horizontalBarChart.leftAxis.axisMinimum = 0
horizontalBarChart.legend.verticalAlignment = .top
horizontalBarChart.legend.horizontalAlignment = .center
horizontalBarChart.legend.orientation = .vertical
horizontalBarChart.drawValueAboveBarEnabled = false
horizontalBarChart.legend.enabled = false
horizontalBarChart.animate(xAxisDuration: 2.0, yAxisDuration: 2.0)
}
Goto Charts and look for HorizontalBarChartRender class, find a method called draw values and changed value for text alignment to center.
or: Search for these two lines
let x = transformed[k].x + (drawBelow ? negOffset : posOffset)
replace it with
let x = buffer.rects[k].origin.x + buffer.rects[k].size.width / 2.2
if !viewPortHandler.isInBoundsTop(rect.origin.y) { break }
comment out this line

Multiple labels xAxis iOS-Charts

I have troubles with the library and i can't find a solution, hope you can help.
When I put data on the chart everything about drawing axis and shapes goes well but the labels on my xAxis multiplies itself and i don't know why, look i let you my code and a problem's picture, maybe it sounds weird but in order to show the problem i created a barChart with just one data.
func setChart(values: [Double]) {
let formato:BarChartFormatter = BarChartFormatter()
formato.setArray(self.listadoLabels)
let xaxis:XAxis = XAxis()
max = values.maxElement()
barChartView.noDataText = "You need to provide data for the chart."
var dataEntries: [BarChartDataEntry] = []
for i in 0..<values.count {
let dataEntry = BarChartDataEntry(x: Double(i), y:values[i])
dataEntries.append(dataEntry)
formato.stringForValue(Double(i), axis: xaxis)
}
xaxis.valueFormatter = formato
let chartDataSet = BarChartDataSet(values: dataEntries, label: "Units Sold")
chartDataSet.colors = ChartColorTemplates.joyful()
barChartView.fitBars = true //Para que las barras inicial y final se muestren completas
barChartView.xAxis.valueFormatter = xaxis.valueFormatter
barChartView.xAxis.labelPosition = .Bottom
barChartView.leftAxis.axisMinimum = 0
barChartView.leftAxis.axisMaximum = max + 2
barChartView.rightAxis.enabled = false
barChartView.drawValueAboveBarEnabled = false
barChartView.descriptionText = ""
barChartView.xAxis.drawGridLinesEnabled = false
barChartView.animate(xAxisDuration: 1.0, yAxisDuration: 1.0)
let chartData = BarChartData()
chartData.addDataSet(chartDataSet)
barChartView.data = chartData
}
Most of code is just styling, and i have one class for the xAxis format because you need one to put labels in the xAxis, this is the code:
public func stringForValue(value: Double, axis: AxisBase?) -> String {
return "Label1"
}
I'm just sending one value of 5512, and the result is, don't pay attention to segmentTab and button:
I was in the same situation you were, i couldn't find an exact solution, but this one worked for me:
barChart?.xAxis.wordWrapEnabled = true
barChart?.xAxis.setLabelCount(5, force: true)
I also centered my bars to match the labels
let dataEntry = BarChartDataEntry(x: Double(i) + 0.5, y: Double(count))
In my case my chart can't have more than 5 bars so i used 5, but you could pass a variable with the number of bars and set the "LabelCount" to that number, when you zoom in it will still repeat the labels, but they won't be overlapped and won't look as bad.
I know it is not exactly the answer you were looking for but hope it helps

Resources