-
-
Notifications
You must be signed in to change notification settings - Fork 6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Invert xAxis label #2504
Comments
you can use valueFormatter to reorder it. |
updated: I found a similar issue at stackoverflow, but the delegate method in valueFormatter do not provide the index of the value. @liuxuan30 I used the xAxis to show weekdays(start of week to the end) with a LineChartView in my case, if the left value smaller than the bright in xAxis, it works well, but if not, as the following example showed, the label in xAxis dissappeared normal aXis( (from 2018/7/22 to 2018/7/28)): 22 23 24 25 26 27 28 but the next week form 2018/8/29 to 2018/08/04 if I comment the Line of
how can I fixed it? |
You can reverse your dataset so that they are in the correct order. Your last value should have an x index of 0 and so on. |
@petester42 Well, it is not work well in my case. I should keep the weekday order for a week(e.g 7/28, 7/29/, 7/30, /7/31, 8/1/,8/2,/8/3) on the x Axis, so there was no an x index of 0. After step by step debugging, I found that when the entries of x Axis changes liked the [28,29,30,31,1,2,3], that the 1st one is bigger then the last one in digital, the entries value also changed in the I'd like to know if possible that render the x Axis with a string value from the input value, not the digital. just keep the original orders. import UIKit
import Charts
class ViewController: UIViewController {
@IBOutlet weak var chartView: BarChartView!
private(set) lazy var xAxis: XAxis = {
let xAxis = chartView.xAxis
xAxis.labelFont = .systemFont(ofSize: 11)
xAxis.labelTextColor = .darkText
xAxis.drawAxisLineEnabled = true
xAxis.labelPosition = .bottom
xAxis.drawGridLinesEnabled = false
xAxis.granularityEnabled = true
return xAxis
}()
private lazy var leftYAxis: YAxis = {
let leftAxis = chartView.leftAxis
leftAxis.drawGridLinesEnabled = false
leftAxis.granularityEnabled = false
return leftAxis
}()
override func viewDidLoad() {
super.viewDidLoad()
initChartView()
loadData()
}
func initChartView() {
chartView.chartDescription?.enabled = false
chartView.dragEnabled = true
chartView.setScaleEnabled(true)
chartView.pinchZoomEnabled = false
let l = chartView.legend
l.form = .circle
l.font = .systemFont(ofSize: 11)!
l.textColor = .darkText
l.horizontalAlignment = .center
l.verticalAlignment = .top
l.orientation = .horizontal
l.yEntrySpace = 20
l.drawInside = false
chartView.rightAxis.enabled = false
xAxis.labelCount = 7
leftYAxis.axisMinimum = 0
leftYAxis.axisMaximum = 70
}
func loadData() {
let allDays:[Double] = [28,29,30,31,1,2,3,4] // not show xlabel
//let allDays:[Double] = [16,17,18,19,20,21,22] // show x label
xAxis.axisMinimum = allDays.first ?? 0
xAxis.axisMaximum = allDays.last ?? 0
var values:[BarChartDataEntry] = []
for day in allDays {
let value = BarChartDataEntry(x: day, y: Double(Int.randomIntNumber(lower: 0, upper: 70)))
values.append(value)
}
let set = BarChartDataSet(values: values, label: "")
let data = BarChartData(dataSets: [set])
chartView.data = data
chartView.animate(xAxisDuration: 1.0)
}
}
extension Int {
public static func randomIntNumber(lower: Int = 0,upper: Int = Int(UInt32.max)) -> Int {
return lower + Int(arc4random_uniform(UInt32(upper - lower)))
}
} |
The reason that didn't work is that the axisMin is greater than the axis max. This is about what I meant when I meant use an index: import UIKit
import Charts
class ViewController: UIViewController {
@IBOutlet weak var chartView: BarChartView!
private(set) lazy var xAxis: XAxis = {
let xAxis = chartView.xAxis
xAxis.labelFont = .systemFont(ofSize: 11)
xAxis.labelTextColor = .darkText
xAxis.drawAxisLineEnabled = true
xAxis.labelPosition = .bottom
xAxis.drawGridLinesEnabled = false
xAxis.granularityEnabled = true
return xAxis
}()
private lazy var leftYAxis: YAxis = {
let leftAxis = chartView.leftAxis
leftAxis.drawGridLinesEnabled = false
leftAxis.granularityEnabled = false
return leftAxis
}()
override func viewDidLoad() {
super.viewDidLoad()
initChartView()
loadData()
}
func initChartView() {
chartView.chartDescription?.enabled = false
chartView.dragEnabled = true
chartView.setScaleEnabled(true)
chartView.pinchZoomEnabled = false
let l = chartView.legend
l.form = .circle
l.font = .systemFont(ofSize: 11)!
l.textColor = .darkText
l.horizontalAlignment = .center
l.verticalAlignment = .top
l.orientation = .horizontal
l.yEntrySpace = 20
l.drawInside = false
chartView.rightAxis.enabled = false
xAxis.labelCount = 7
leftYAxis.axisMinimum = 0
leftYAxis.axisMaximum = 70
}
func loadData() {
// let allDays:[Int] = [28,29,30,31,1,2,3,4] // not show xlabel
let allDays:[Int] = [28,29,30,31,32,33,34] // show x label
var values:[BarChartDataEntry] = []
for (index, day) in allDays.enumerated() {
let value = BarChartDataEntry(x: Double(index), y: Double(Int.randomIntNumber(lower: 0, upper: 70)), data: day as AnyObject)
values.append(value)
}
xAxis.valueFormatter = DayAxisFormatter(values);
let set = BarChartDataSet(values: values, label: "")
let data = BarChartData(dataSets: [set])
chartView.data = data
chartView.animate(xAxisDuration: 1.0)
}
}
extension Int {
public static func randomIntNumber(lower: Int = 0,upper: Int = Int(UInt32.max)) -> Int {
return lower + Int(arc4random_uniform(UInt32(upper - lower)))
}
}
class DayAxisFormatter: IAxisValueFormatter {
private let values: [BarChartDataEntry];
init(_ values: [BarChartDataEntry]) {
self.values = values
}
func stringForValue(_ value: Double, axis: AxisBase?) -> String {
let index = Int(value)
let entry = values[index];
guard let day = entry.data as! Int? else {
fatalError("whoops")
}
return "\(day)"
}
} Play around with something like that and you'll get something you need. |
As for the original question from @sahabe1, the same thing can be done just reverse your dataset. Same code as above but replace loadData with the following:
func loadData() {
// let allDays:[Int] = [28,29,30,31,1,2,3,4] // not show xlabel
let allDays:[Int] = [28,29,30,31,32,33,34] // show x label
var values:[BarChartDataEntry] = []
for (index, day) in allDays.reversed().enumerated() {
let value = BarChartDataEntry(x: Double(index), y: Double(Int.randomIntNumber(lower: 0, upper: 70)), data: day as AnyObject)
values.append(value)
}
xAxis.valueFormatter = DayAxisFormatter(values);
let set = BarChartDataSet(values: values, label: "")
let data = BarChartData(dataSets: [set])
chartView.data = data
chartView.animate(xAxisDuration: 1.0)
} |
Well, One more question, could you give me some tips that where should I start with to support |
In my first example I didn’t change the order. Without doing something like I just posted it’s not possible in charts. Charts is based on the numeric values only and not the semantic values such as days, dates, etc. 4 can’t come after 31, it doesn’t make sense in terms of a numerical graph. Look at that date label demos in the demo projects to get a better idea of how to work around this limitation. It’s a more complex example of what I just posted here. |
Thanks for the tips so much. I made a stupid mistake, all I want is just show the day string on the x Axis, not keep the data entry's x value as the day. private var lables: [String] = []
func loadData() {
let indexes: [Double] = [0,1,2,3,4,5,6]
xAxis.valueFormatter = self
lables = [28,29,30,31,1,2,3].map {"\($0)"}
xAxis.axisMinimum = Double(indexes.first ?? 0)
xAxis.axisMaximum = Double(indexes.last ?? 0)
var values:[BarChartDataEntry] = []
for index in indexes {
let value = BarChartDataEntry(x: index, y: Double(Int.randomIntNumber(lower: 0, upper: 70)))
values.append(value)
}
let set = BarChartDataSet(values: values, label: "")
let data = BarChartData(dataSets: [set])
chartView.data = data
chartView.animate(xAxisDuration: 1.0)
}
}
extension ViewController: IAxisValueFormatter {
func stringForValue(_ value: Double, axis: AxisBase?) -> String {
let index = Int(value)
return lables[index]
}
} |
Ho to invert xaxis label. currently it showing 0-----28 but my requirement is 28-----0
please see attachment
The text was updated successfully, but these errors were encountered: