x-Axis value alignment with y-Axis value is wrong Charts-iOS - ios

I have an issue plotting the x-axis against its corresponding values there is no major customisation done except the values are being plotted on the right axis and axis dependency is set to right
Below is the screenshot
Setup code:
let xAxis = evalutionTrendView?.trendGraphView.xAxis
xAxis?.labelPosition = .bottom
xAxis?.drawGridLinesEnabled = false
xAxis?.drawAxisLineEnabled = true
//xAxis?.axisLineColor = Utilities.axisBaseLineColor
xAxis?.forceLabelsEnabled = true
xAxis?.avoidFirstLastClippingEnabled = false
xAxis?.labelFont = UIFont.SFProText.Regular(12.0)
xAxis?.labelTextColor = Utilities.axisValueColor
xAxis?.granularity = 1
xAxis?.granularityEnabled = true
xAxis?.valueFormatter = XaxisValueFormatter()
let rightAxis = evalutionTrendView?.trendGraphView.rightAxis
rightAxis?.gridColor = Utilities.axisBaseLineColor
rightAxis?.gridLineWidth = 1.0
rightAxis?.axisMaximum = 100
rightAxis?.axisMinimum = 0
rightAxis?.axisLineColor = .clear
rightAxis?.labelFont = UIFont.SFProText.Regular(12.0)
rightAxis?.labelTextColor = Utilities.axisValueColor
evalutionTrendView?.trendGraphView?.leftAxis.enabled = false
final class XaxisValueFormatter: AxisValueFormatter{
func stringForValue(_ value: Double, axis: AxisBase?) -> String {
let date = Date(timeIntervalSince1970: TimeInterval(value))
print("x-axis: \(date.dayMonthSlash), value:\(value)")
return date.dayMonthSlash
}
}
Library code:
https://github.com/danielgindi/Charts
Anyone has faced similar issue using with above library with respect to x-axis alignment ?

Related

Convert decimal to integer on line chart

I am using this lib chart : https://github.com/danielgindi/Charts
I have one line chart. Which will display values on x axis. But now it's showing in decimal like 22.0. But i want like 22
Here is my code :
func updateGraphMaster(xAxisLabel: String) {
var lineChartEntry = [ChartDataEntry]()
for num in 0..<chartDataDoubles.count {
let value = ChartDataEntry(x: Double(num), y: chartDataDoubles[num])
lineChartEntry.append(value)
}
let lineChartDataSet = LineChartDataSet(entries: lineChartEntry, label: xAxisLabel)
lineChartDataSet.colors = [NSUIColor.white]
lineChartDataSet.highlightEnabled = true
lineChartDataSet.highlightColor = UIColor.white
lineChartDataSet.drawVerticalHighlightIndicatorEnabled = false
lineChartDataSet.drawHorizontalHighlightIndicatorEnabled = false
lineChartDataSet.drawValuesEnabled = true
lineChartDataSet.drawCirclesEnabled = false
lineChartDataSet.drawCircleHoleEnabled = false
let gradient = getGradientFilling()
lineChartDataSet.fill = Fill.fillWithLinearGradient(gradient, angle: 90.0)
lineChartDataSet.drawFilledEnabled = true
let data = LineChartData()
data.addDataSet(lineChartDataSet)
data.setDrawValues(false)
data.setValueTextColor(NSUIColor.white)
let formatter = NumberFormatter()
formatter.maximumFractionDigits = 0
formatter.numberStyle = .none
formatter.locale = .current
//lineChartDataSet.valueFormatter = DefaultValueFormatter(formatter: formatter)
data.setValueFormatter(DefaultValueFormatter(formatter: formatter))
chartView.data = data
chartView.xAxis.valueFormatter = DefaultAxisValueFormatter(formatter: formatter)
}
Here i using setValueFormatter and append the data to chart view. But still it's showing in decimal . Not in integer.
if you want to edit the data set value format itself not the axis, try this:
data.valueFormatter = DefaultValueFormatter(decimals: 0)
I hope It works!
It seems that you have more than 1 data set to show on chart?
Your question was unclear to me until you showed us a screenshot
You were not asking for the actual drawn values to be formatted, you were asking to format the value displayed by the label of the marker that appears when you click a point. For that implementation, I had to presume you used the custom class BalloonMarker from the Charts-Demo, which does not format the value of its text before being displayed. I was able to reproduce your issue and fix it: note the lines 184-187 of BalloonMarker.swift:
184 open override func refreshContent(entry: ChartDataEntry, highlight: Highlight)
185 {
186 setLabel(String(entry.y))
187 }
Line 186 needs to be replaced with
186 setLabel(String(format: "%.0f", entry.y))
That should fix your issue. I include my reproduction and fix for you below:
Reproduction of your issue
With Fix
Additionally, if you wish to ensure your x-axis shows only integers you need to do the following:
let formatter = NumberFormatter()
formatter.maximumFractionDigits = 0
formatter.numberStyle = .none
formatter.locale = .current
chartView.xAxis.valueFormatter = DefaultAxisValueFormatter(formatter: formatter)
You want to set formatter.maximumFractionDigits to zero.

How to remove static string "DataSet" from Legends of Pie Chart for danielgindi/Charts ios?

I am using danielgindi/Charts for iOS/Swift. There is an extra Legend Entry with label "DataSet" displays in Pie Chart as seen in this image:
When I traced, I found there are two entries in the array of LegendEntry found in the PieChartView legend, i.e. PieChartView.legend.entries, where as I have only one object in my array.
Here is the code:
let dataSet = PieChartDataSet()
dataSet.drawIconsEnabled = false
dataSet.setColor(AppColors.selectedMenuItem)
dataSet.sliceSpace = 3
dataSet.iconsOffset = CGPoint(x: 0, y: 40)
dataSet.selectionShift = 5
var totalRevenuePer:Double = 0.0
_ = arrRevenue.map({ (objRevenue) -> Void in
if let percentage = Double(objRevenue.per ?? "0.0"), percentage != 0.0{
dataSet.append(PieChartDataEntry(value: percentage, label: "\((objRevenue.rev_center_name ?? "") + " " + objRevenue.revenue.currencyString())"))
totalRevenuePer += percentage
}
})
var colors = AppColors.TenderColors
if totalRevenuePer < 100{ colors.append(.clear) }
dataSet.colors = colors
let data = PieChartData(dataSet: dataSet)
data.setValueFormatter(PercentageFormatter())
data.setValueFont(NSUIFont.systemFont(ofSize: 11))
data.setValueTextColor(.white)
pieChart.data = data
pieChart.highlightValue(nil)
let legend = pieChart.legend
legend.textColor = .white
legend.entries.last?.label = ""
pieChart.animate(yAxisDuration: 1.4, easingOption: .easeInOutQuad)
// Refresh chart with new data
pieChart.notifyDataSetChanged()
Appreciate any help, thank you.
It's a property of PieChartDataSet
The default value, if you don't set your own, is "DataSet"
let dataSet = PieChartDataSet()
// provide your own
dataSet.label = "My Label"
// or, no label
dataSet.label = ""

Force to show min/max on x axis

I am working with library. Anybody know if is it possible to force show min and max label on x-axis.
What I have:
What I want to achieve:
My implementation:
private func prepareXAxis() {
lineChart.xAxis.labelPosition = .bottom
lineChart.xAxis.valueFormatter = ChartXAxisDateValueFormatter()
lineChart.xAxis.labelFont = UIFont.pmd_robotoRegular(ofSize: 13.0)
lineChart.xAxis.labelTextColor = UIColor.pmd_darkGrey
}
And implementation of my own ValueFormatter:
import Foundation
import Charts
class ChartXAxisDateValueFormatter: NSObject, IAxisValueFormatter {
func stringForValue(_ value: Double, axis: AxisBase?) -> String {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "hh:mm\ndd MMM"
return dateFormatter.string(from: Date(timeIntervalSince1970: value))
}
}
Edit
I added this code but first and last label on x-axis is still skipped:
lineChart.xAxis.axisMinimum = lineDataSet.xMin
lineChart.xAxis.axisMaximum = lineDataSet.xMax
lineChart.xAxis.avoidFirstLastClippingEnabled = false
lineChart.xAxis.granularity = 1.0
I checked lineDataSet.xMin and lineDataSet.xMax. They have valid values.
You need to set below property for not skip 1st and last value
//Set up XAxis into chart.
lineChart.xAxis.axisMinimum = 0
lineChart.xAxis.avoidFirstLastClippingEnabled = NO
lineChart.xAxis.granularity = 1.0
Hope this will helps.
I found a solution. The lost line:
combinedChart.xAxis.forceLabelsEnabled = true
I also changed type of chart from LineChart to CombinedChartView.

How to format xAxis labels iOS charts

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

Many Gradient Fill in same lineChart Swift for iOS-Charts

let gradientColors = [UIColor.cyanColor().CGColor, UIColor.clearColor().CGColor] // Colors of the gradient
let colorLocations:[CGFloat] = [1.0, 0.0] // Positioning of the gradient
let gradient = CGGradientCreateWithColors(CGColorSpaceCreateDeviceRGB(), gradientColors, colorLocations) // Gradient Object
set.fill = ChartFill.fillWithLinearGradient(gradient!, angle: 90.0) // Set the Gradient
set.drawFilledEnabled = true // Draw the Gradient
Result
I want to have many fill depending of xAxis value like this :
It's possible to do this ??
Solution:
The solution is to use many dataset, from the second one, the first value for each data need to be same the last value of the previous dataset so at the end it will look like you have one dataset
ex:
let dollars1 = [1453.0,2352,5431,1442] // last value = first value of next dataset
let dollars2 = [1442.0,2234,8763,4453] // last value = first value of next dataset
let dollars3 = [4453.0,3456,7843,5678] // last value = first value of next dataset
func setChartData(months : [String]) {
var yVals1 : [ChartDataEntry] = [ChartDataEntry]()
for var i = 0; i < months.count; i++ {
yVals1.append(ChartDataEntry(value: dollars1[i], xIndex: i))
}
let set1: LineChartDataSet = LineChartDataSet(yVals: yVals1, label: "First Set")
set1.axisDependency = .Left // Line will correlate with left axis values
set1.setColor(UIColor.redColor().colorWithAlphaComponent(0.5))
set1.setCircleColor(UIColor.redColor())
set1.lineWidth = 2.0
set1.circleRadius = 6.0
set1.fillAlpha = 1
set1.fillColor = UIColor.redColor()
set1.drawFilledEnabled = true
var yVals2 : [ChartDataEntry] = [ChartDataEntry]()
for var i = 0; i < months.count; i++ {
yVals2.append(ChartDataEntry(value: dollars2[i], xIndex: i))
}
let set2: LineChartDataSet = LineChartDataSet(yVals: yVals2, label: "Second Set")
set2.axisDependency = .Left // Line will correlate with left axis values
set2.setColor(UIColor.greenColor().colorWithAlphaComponent(0.5))
set2.setCircleColor(UIColor.greenColor())
set2.lineWidth = 2.0
set2.circleRadius = 6.0
set2.fillAlpha = 1
set2.fillColor = UIColor.greenColor()
set2.drawFilledEnabled = true
var yVals3 : [ChartDataEntry] = [ChartDataEntry]()
for var i = 0; i < months.count; i++ {
yVals3.append(ChartDataEntry(value: dollars3[i], xIndex: i))
}
let set3: LineChartDataSet = LineChartDataSet(yVals: yVals3, label: "Second Set")
set3.axisDependency = .Left // Line will correlate with left axis values
set3.setColor(UIColor.blueColor().colorWithAlphaComponent(0.5))
set3.setCircleColor(UIColor.blueColor())
set3.lineWidth = 2.0
set3.circleRadius = 6.0
set3.fillAlpha = 65 / 255.0
set3.fillColor = UIColor.blueColor()
set3.drawFilledEnabled = true
//3 - create an array to store our LineChartDataSets
var dataSets : [LineChartDataSet] = [LineChartDataSet]()
dataSets.append(set1)
dataSets.append(set2)
dataSets.append(set3)
//4 - pass our months in for our x-axis label value along with our dataSets
let data: LineChartData = LineChartData(xVals: months, dataSets: dataSets)
data.setValueTextColor(UIColor.whiteColor())
//5 - finally set our data
self.lineChartView.data = data
}
Yes its possible to do that gradient fill you want ,just replace below line and add some color so you can check.
set.fill = ChartFill.fillWithLinearGradient(gradient!, angle: 90.0)
Set the angle 180 so it will work
set.fill = ChartFill.fillWithLinearGradient(gradient!, angle: 180.0)

Resources