IOS 图表 - Y 轴缩放数字四舍五入到最接近的百、千等
IOS Charts - YAxis scaling number round to nearest hundred, thousands, etc
iOs 图表库 (3.6.0) 有没有办法用最接近的百、千等来缩放 Y 轴?
我可能遗漏了一些东西,但我的 Y 轴没有任何意义:
在这个例子中,我希望我的 Y 轴是这样的:
75 000
60 000
45 000
30 000
15 000
0
-15 000
我尝试使用 autoScaleMinMaxEnabled
,但它似乎不起作用。
我不明白如何让 y 轴使用四舍五入的数字?
感谢您的帮助
更新:
这是我根据要求使用的代码:
class GraphCustomView : LineChartView, ChartViewDelegate {
//MARK: Variables
var graphModel: [GraphModel] = []
// Initialize Chart
public func initializeChart(graphModel: [GraphModel], devise: String, withouthFill: Bool? = true) {
self.graphModel = [GraphModel]()
self.graphModel = graphModel
self.delegate = self
self.chartDescription?.enabled = false
// xAxis
self.xAxis.enabled = true
self.xAxis.drawGridLinesEnabled = false
self.xAxis.labelPosition = .bottom
self.xAxis.valueFormatter = DateValueFormatter(miniTime: graphModel.first!.miniDate)
self.xAxis.labelFont = UIFont(name: "Ubuntu", size: 8)!
self.xAxis.labelRotationAngle = -20
self.xAxis.granularityEnabled = true
self.xAxis.granularity = 1
// RightAxis
self.rightAxis.enabled = false
self.rightAxis.drawGridLinesEnabled = false
// LeftAxis
self.leftAxis.drawGridLinesEnabled = true
self.leftAxis.gridColor = .gray
self.leftAxis.gridLineDashLengths = [CGFloat(1.5)]
self.leftAxis.labelFont = UIFont(name: "Ubuntu", size: 8)!
// General chart settings
self.drawBordersEnabled = false
self.setScaleEnabled(true)
leftAxis.setLabelCount(7, force: true)
leftAxis.drawTopYLabelEntryEnabled = true
leftAxis.drawBottomYLabelEntryEnabled = true
// Legend
self.leftAxis.labelFont = UIFont(name: "Ubuntu", size: 11)!
self.xAxis.labelFont = UIFont(name: "Ubuntu", size: 11)!
let l = self.legend
l.form = .circle
l.horizontalAlignment = .right
l.verticalAlignment = .bottom
l.orientation = .horizontal
l.drawInside = false
l.font = UIFont(name: "Ubuntu", size: 8)!
// Overdrawn line
let minValue = graphModel.first!.minValue
let maxValue = graphModel.first!.maxValue
var range: Double = 0.0
if (maxValue - minValue != 0) {
range = (maxValue - minValue) / 7
}
if (graphModel.first!.minValue - (range * 2) < graphModel.first!.overdrawn && graphModel.first!.overdrawn < graphModel.first!.minValue) {
self.leftAxis.axisMinimum = graphModel.first!.overdrawn
}
let limit: ChartLimitLine = ChartLimitLine()
limit.label = "Overdrawn"
limit.limit = graphModel.first!.overdrawn
limit.valueTextColor = .red
limit.lineColor = .red
limit.lineDashLengths = [10, 5]
leftAxis.addLimitLine(limit)
// Marker/Tooltip
let marker = XYMarkerView(color: .darkGray,
font: UIFont(name: "Ubuntu", size: 12)!,
textColor: .white,
insets: UIEdgeInsets(top: 8, left: 8, bottom: 20, right: 8),
xAxisValueFormatter: DateValueFormatter(miniTime: graphModel.first!.miniDate),
yAxisValueFormatter: MarkerValueFormatter(devise: devise))
marker.chartView = self
marker.minimumSize = CGSize(width: 80, height: 40)
self.marker = marker
self.isMultipleTouchEnabled = true
self.highlightPerTapEnabled = true
self.highlightPerDragEnabled = true
// Add data to chart
self.updateChartData()
}
public func updateChartData() {
// Creating dataSets
var dataSets: [LineChartDataSet] = [LineChartDataSet]()
// We need to sort the data in order to add it to the graph
for graph in self.graphModel {
graph.chartData.sort(by: { [=12=].x < .x })
let dataSet : LineChartDataSet = LineChartDataSet(entries: graph.chartData, label: graph.name)
dataSet.circleRadius = 0
dataSet.colors = graph.color
dataSet.drawValuesEnabled = false
dataSet.lineWidth = 2
dataSet.mode = .cubicBezier
let leftAxis = self.leftAxis
leftAxis.drawLimitLinesBehindDataEnabled = true
dataSet.fillColor = graph.color.first!
dataSet.drawFilledEnabled = true
// Add to datasets
dataSets.append(dataSet)
}
// Styling data
let data = LineChartData(dataSets: dataSets)
data.setValueFont(UIFont(name: "Ubuntu", size: 7)!)
// Displaying graph
self.data = data
}
这是我用于此特定图表的数据:
[{\"pointDate\":\"2016-11-01T00:00:00\",\"pointValue\":45375.800000000003},{\"pointDate\":\"2016-11-01T00:00:00\",\"pointValue\":45375.800000000003},{\"pointDate\":\"2016-10-31T00:00:00\",\"pointValue\":54755.580000000002},{\"pointDate\":\"2016-10-30T00:00:00\",\"pointValue\":34324.199999999997},{\"pointDate\":\"2016-10-29T00:00:00\",\"pointValue\":43846.059999999998},{\"pointDate\":\"2016-10-28T00:00:00\",\"pointValue\":29243.779999999999},{\"pointDate\":\"2016-10-27T00:00:00\",\"pointValue\":28238.439999999999},{\"pointDate\":\"2016-10-26T00:00:00\",\"pointValue\":-11461.74},{\"pointDate\":\"2016-10-25T00:00:00\",\"pointValue\":-5756.5500000000002},{\"pointDate\":\"2016-10-24T00:00:00\",\"pointValue\":27565.939999999999},{\"pointDate\":\"2016-10-23T00:00:00\",\"pointValue\":40770.910000000003},{\"pointDate\":\"2016-10-22T00:00:00\",\"pointValue\":46875.870000000003},{\"pointDate\":\"2016-10-21T00:00:00\",\"pointValue\":44609.540000000001},{\"pointDate\":\"2016-10-20T00:00:00\",\"pointValue\":43970.769999999997},{\"pointDate\":\"2016-10-19T00:00:00\",\"pointValue\":43262.910000000003},{\"pointDate\":\"2016-10-18T00:00:00\",\"pointValue\":22016.080000000002},{\"pointDate\":\"2016-10-17T00:00:00\",\"pointValue\":45001.940000000002},{\"pointDate\":\"2016-10-16T00:00:00\",\"pointValue\":44443.739999999998},{\"pointDate\":\"2016-10-15T00:00:00\",\"pointValue\":61521.720000000001},{\"pointDate\":\"2016-10-14T00:00:00\",\"pointValue\":31674.16},{\"pointDate\":\"2016-10-13T00:00:00\",\"pointValue\":42767.040000000001},{\"pointDate\":\"2016-10-12T00:00:00\",\"pointValue\":55202.110000000001},{\"pointDate\":\"2016-10-11T00:00:00\",\"pointValue\":76274.100000000006},{\"pointDate\":\"2016-10-10T00:00:00\",\"pointValue\":39097.07},{\"pointDate\":\"2016-10-09T00:00:00\",\"pointValue\":13742.99},{\"pointDate\":\"2016-10-08T00:00:00\",\"pointValue\":9616.2199999999993},{\"pointDate\":\"2016-10-07T00:00:00\",\"pointValue\":1450.6099999999999},{\"pointDate\":\"2016-10-06T00:00:00\",\"pointValue\":5820.5},{\"pointDate\":\"2016-10-05T00:00:00\",\"pointValue\":-9522.75},{\"pointDate\":\"2016-10-04T00:00:00\",\"pointValue\":8317},{\"pointDate\":\"2016-10-03T00:00:00\",\"pointValue\":7923.6499999999996},{\"pointDate\":\"2016-10-02T00:00:00\",\"pointValue\":10249.889999999999},{\"pointDate\":\"2016-10-01T00:00:00\",\"pointValue\":2388.6799999999998},{\"pointDate\":\"2016-09-30T00:00:00\",\"pointValue\":0}]
代码用于格式化它:
for point in pointevo.pointEvolution {
let date = point.pointDate.toDate()
let timeInSecondes = date?.timeIntervalSince1970
if (firstTime) {
self.miniDate = timeInSecondes!
firstTime = false
minValue = point.pointValue
maxValue = point.pointValue
}
if (point.pointValue < minValue) {
minValue = point.pointValue
}
if (point.pointValue > maxValue) {
maxValue = point.pointValue
}
chartData.append(ChartDataEntry(x: (timeInSecondes! - miniDate) / (3600.0 * 24.0), y: point.pointValue))
if tempPointValue.firstIndex(of: point.pointValue) == nil {
tempPointValue.append(point.pointValue)
}
}
讨论后编辑
当我用你的数据测试你的代码时,我找到了问题的根源。在您的代码中,它是行:
leftAxis.setLabelCount(7, force: true)
如果 force 参数设置为 true - 它会覆盖默认的计算标签并强制标签为您的标签的确切数量指定,它将等距离传播。
如果不是强制它-当没有指定标签的确切数量时,我有 6 行(和标签)。所以现在就看你如何更好地使用它了。
如果 force 参数为 true 和 false (我设置这里 xaxis 和 overdraw 值到一些静态值)。
下面第一个回答其他情况。
你可以使用 IAxisValueFormatter 协议方法 stringForValue(_ value:, axis:)。你可以在这里四舍五入你的价值并放置额外的符号,比如货币符号,就像我一样。像这样:
extension ChartController: IAxisValueFormatter {
func stringForValue(_ value: Double, axis: AxisBase?) -> String {
if axis is XAxis {
// do something you need for X axis
return valueTransformedToString
} else {
// do something you need for Y axis
return valueTransformedToString
}
}
}
iOs 图表库 (3.6.0) 有没有办法用最接近的百、千等来缩放 Y 轴?
我可能遗漏了一些东西,但我的 Y 轴没有任何意义:
在这个例子中,我希望我的 Y 轴是这样的:
75 000
60 000
45 000
30 000
15 000
0
-15 000
我尝试使用 autoScaleMinMaxEnabled
,但它似乎不起作用。
我不明白如何让 y 轴使用四舍五入的数字?
感谢您的帮助
更新:
这是我根据要求使用的代码:
class GraphCustomView : LineChartView, ChartViewDelegate {
//MARK: Variables
var graphModel: [GraphModel] = []
// Initialize Chart
public func initializeChart(graphModel: [GraphModel], devise: String, withouthFill: Bool? = true) {
self.graphModel = [GraphModel]()
self.graphModel = graphModel
self.delegate = self
self.chartDescription?.enabled = false
// xAxis
self.xAxis.enabled = true
self.xAxis.drawGridLinesEnabled = false
self.xAxis.labelPosition = .bottom
self.xAxis.valueFormatter = DateValueFormatter(miniTime: graphModel.first!.miniDate)
self.xAxis.labelFont = UIFont(name: "Ubuntu", size: 8)!
self.xAxis.labelRotationAngle = -20
self.xAxis.granularityEnabled = true
self.xAxis.granularity = 1
// RightAxis
self.rightAxis.enabled = false
self.rightAxis.drawGridLinesEnabled = false
// LeftAxis
self.leftAxis.drawGridLinesEnabled = true
self.leftAxis.gridColor = .gray
self.leftAxis.gridLineDashLengths = [CGFloat(1.5)]
self.leftAxis.labelFont = UIFont(name: "Ubuntu", size: 8)!
// General chart settings
self.drawBordersEnabled = false
self.setScaleEnabled(true)
leftAxis.setLabelCount(7, force: true)
leftAxis.drawTopYLabelEntryEnabled = true
leftAxis.drawBottomYLabelEntryEnabled = true
// Legend
self.leftAxis.labelFont = UIFont(name: "Ubuntu", size: 11)!
self.xAxis.labelFont = UIFont(name: "Ubuntu", size: 11)!
let l = self.legend
l.form = .circle
l.horizontalAlignment = .right
l.verticalAlignment = .bottom
l.orientation = .horizontal
l.drawInside = false
l.font = UIFont(name: "Ubuntu", size: 8)!
// Overdrawn line
let minValue = graphModel.first!.minValue
let maxValue = graphModel.first!.maxValue
var range: Double = 0.0
if (maxValue - minValue != 0) {
range = (maxValue - minValue) / 7
}
if (graphModel.first!.minValue - (range * 2) < graphModel.first!.overdrawn && graphModel.first!.overdrawn < graphModel.first!.minValue) {
self.leftAxis.axisMinimum = graphModel.first!.overdrawn
}
let limit: ChartLimitLine = ChartLimitLine()
limit.label = "Overdrawn"
limit.limit = graphModel.first!.overdrawn
limit.valueTextColor = .red
limit.lineColor = .red
limit.lineDashLengths = [10, 5]
leftAxis.addLimitLine(limit)
// Marker/Tooltip
let marker = XYMarkerView(color: .darkGray,
font: UIFont(name: "Ubuntu", size: 12)!,
textColor: .white,
insets: UIEdgeInsets(top: 8, left: 8, bottom: 20, right: 8),
xAxisValueFormatter: DateValueFormatter(miniTime: graphModel.first!.miniDate),
yAxisValueFormatter: MarkerValueFormatter(devise: devise))
marker.chartView = self
marker.minimumSize = CGSize(width: 80, height: 40)
self.marker = marker
self.isMultipleTouchEnabled = true
self.highlightPerTapEnabled = true
self.highlightPerDragEnabled = true
// Add data to chart
self.updateChartData()
}
public func updateChartData() {
// Creating dataSets
var dataSets: [LineChartDataSet] = [LineChartDataSet]()
// We need to sort the data in order to add it to the graph
for graph in self.graphModel {
graph.chartData.sort(by: { [=12=].x < .x })
let dataSet : LineChartDataSet = LineChartDataSet(entries: graph.chartData, label: graph.name)
dataSet.circleRadius = 0
dataSet.colors = graph.color
dataSet.drawValuesEnabled = false
dataSet.lineWidth = 2
dataSet.mode = .cubicBezier
let leftAxis = self.leftAxis
leftAxis.drawLimitLinesBehindDataEnabled = true
dataSet.fillColor = graph.color.first!
dataSet.drawFilledEnabled = true
// Add to datasets
dataSets.append(dataSet)
}
// Styling data
let data = LineChartData(dataSets: dataSets)
data.setValueFont(UIFont(name: "Ubuntu", size: 7)!)
// Displaying graph
self.data = data
}
这是我用于此特定图表的数据:
[{\"pointDate\":\"2016-11-01T00:00:00\",\"pointValue\":45375.800000000003},{\"pointDate\":\"2016-11-01T00:00:00\",\"pointValue\":45375.800000000003},{\"pointDate\":\"2016-10-31T00:00:00\",\"pointValue\":54755.580000000002},{\"pointDate\":\"2016-10-30T00:00:00\",\"pointValue\":34324.199999999997},{\"pointDate\":\"2016-10-29T00:00:00\",\"pointValue\":43846.059999999998},{\"pointDate\":\"2016-10-28T00:00:00\",\"pointValue\":29243.779999999999},{\"pointDate\":\"2016-10-27T00:00:00\",\"pointValue\":28238.439999999999},{\"pointDate\":\"2016-10-26T00:00:00\",\"pointValue\":-11461.74},{\"pointDate\":\"2016-10-25T00:00:00\",\"pointValue\":-5756.5500000000002},{\"pointDate\":\"2016-10-24T00:00:00\",\"pointValue\":27565.939999999999},{\"pointDate\":\"2016-10-23T00:00:00\",\"pointValue\":40770.910000000003},{\"pointDate\":\"2016-10-22T00:00:00\",\"pointValue\":46875.870000000003},{\"pointDate\":\"2016-10-21T00:00:00\",\"pointValue\":44609.540000000001},{\"pointDate\":\"2016-10-20T00:00:00\",\"pointValue\":43970.769999999997},{\"pointDate\":\"2016-10-19T00:00:00\",\"pointValue\":43262.910000000003},{\"pointDate\":\"2016-10-18T00:00:00\",\"pointValue\":22016.080000000002},{\"pointDate\":\"2016-10-17T00:00:00\",\"pointValue\":45001.940000000002},{\"pointDate\":\"2016-10-16T00:00:00\",\"pointValue\":44443.739999999998},{\"pointDate\":\"2016-10-15T00:00:00\",\"pointValue\":61521.720000000001},{\"pointDate\":\"2016-10-14T00:00:00\",\"pointValue\":31674.16},{\"pointDate\":\"2016-10-13T00:00:00\",\"pointValue\":42767.040000000001},{\"pointDate\":\"2016-10-12T00:00:00\",\"pointValue\":55202.110000000001},{\"pointDate\":\"2016-10-11T00:00:00\",\"pointValue\":76274.100000000006},{\"pointDate\":\"2016-10-10T00:00:00\",\"pointValue\":39097.07},{\"pointDate\":\"2016-10-09T00:00:00\",\"pointValue\":13742.99},{\"pointDate\":\"2016-10-08T00:00:00\",\"pointValue\":9616.2199999999993},{\"pointDate\":\"2016-10-07T00:00:00\",\"pointValue\":1450.6099999999999},{\"pointDate\":\"2016-10-06T00:00:00\",\"pointValue\":5820.5},{\"pointDate\":\"2016-10-05T00:00:00\",\"pointValue\":-9522.75},{\"pointDate\":\"2016-10-04T00:00:00\",\"pointValue\":8317},{\"pointDate\":\"2016-10-03T00:00:00\",\"pointValue\":7923.6499999999996},{\"pointDate\":\"2016-10-02T00:00:00\",\"pointValue\":10249.889999999999},{\"pointDate\":\"2016-10-01T00:00:00\",\"pointValue\":2388.6799999999998},{\"pointDate\":\"2016-09-30T00:00:00\",\"pointValue\":0}]
代码用于格式化它:
for point in pointevo.pointEvolution {
let date = point.pointDate.toDate()
let timeInSecondes = date?.timeIntervalSince1970
if (firstTime) {
self.miniDate = timeInSecondes!
firstTime = false
minValue = point.pointValue
maxValue = point.pointValue
}
if (point.pointValue < minValue) {
minValue = point.pointValue
}
if (point.pointValue > maxValue) {
maxValue = point.pointValue
}
chartData.append(ChartDataEntry(x: (timeInSecondes! - miniDate) / (3600.0 * 24.0), y: point.pointValue))
if tempPointValue.firstIndex(of: point.pointValue) == nil {
tempPointValue.append(point.pointValue)
}
}
讨论后编辑
当我用你的数据测试你的代码时,我找到了问题的根源。在您的代码中,它是行:
leftAxis.setLabelCount(7, force: true)
如果 force 参数设置为 true - 它会覆盖默认的计算标签并强制标签为您的标签的确切数量指定,它将等距离传播。
如果不是强制它-当没有指定标签的确切数量时,我有 6 行(和标签)。所以现在就看你如何更好地使用它了。
如果 force 参数为 true 和 false (我设置这里 xaxis 和 overdraw 值到一些静态值)。
下面第一个回答其他情况。
你可以使用 IAxisValueFormatter 协议方法 stringForValue(_ value:, axis:)。你可以在这里四舍五入你的价值并放置额外的符号,比如货币符号,就像我一样。像这样:
extension ChartController: IAxisValueFormatter {
func stringForValue(_ value: Double, axis: AxisBase?) -> String {
if axis is XAxis {
// do something you need for X axis
return valueTransformedToString
} else {
// do something you need for Y axis
return valueTransformedToString
}
}
}