设置 setVisibleXRangeMaximum 时,iOS 图表 X 轴值无限重复 [英] iOS-Charts X Axis values are repeating indefinitely when setVisibleXRangeMaximum is set
问题描述
我正在尝试绘制一个图表,其中 x 轴是 TimeInterval
,Y 轴是 功耗
.将有太多数据无法显示,因为每天都会有数据.出于这个原因,我想一次显示 5 个 x 值.我通过在设置图表数据后设置 self.chart.setVisibleXRangeMaximum(5)
来实现这一点.尽管显示了 5 个 x 轴值,但这些值会无限重复.就像第一天是 10/10/2016 之后的所有 x 轴值对于无限滚动都是相同的(见下面的截图).其他一些 SO 答案说,设置启用粒度会解决这个问题,但即使启用它后,它也会显示第一个点的重复不确定值.我该如何解决这个问题?
I am trying to draw a chart where the x-axis is TimeInterval
and Y-axis is power consumption
. There will be too much data to show as for each day there will be data. For that reason, I want to show 5 x values at a time. I achieved that by setting self.chart.setVisibleXRangeMaximum(5)
after setting data for the chart. Though 5 x-axis values are showing but the values are repeating for an indefinite time. Like if the first day is 10/10/2016 all the x-axis values after that are the same for indefinite scrolling (see below screenshot). Some other SO answers say that setting granularity enabled will fix that but even after enabling that it's showing the repeated indefinite value of the first point. How can I solve this?
我目前使用的代码(使用虚拟数据进行测试)
code I am using currently (using dummy data for testing purposes)
func setupChart(){
self.chart = BarChartView()
self.chart.translatesAutoresizingMaskIntoConstraints = false
self.chart.chartDescription?.enabled = false
self.chart.dragEnabled = true
self.chart.setScaleEnabled(true)
self.chart.pinchZoomEnabled = true
self.chart.delegate = self
self.chart.drawBarShadowEnabled = false
self.chart.drawValueAboveBarEnabled = true
let xAxis = self.chart.xAxis
xAxis.labelPosition = .bottom
xAxis.labelFont = .systemFont(ofSize: 10)
xAxis.granularityEnabled = true
xAxis.granularity = 1
xAxis.labelCount = 5
xAxis.drawGridLinesEnabled = false
xAxis.valueFormatter = DateValueFormatter() //DayAxisValueFormatter(chart: self.chart)
let leftAxisFormatter = NumberFormatter()
leftAxisFormatter.minimumFractionDigits = 0
leftAxisFormatter.maximumFractionDigits = 1
leftAxisFormatter.negativeSuffix = " KWH"
leftAxisFormatter.positiveSuffix = " KWH"
let leftAxis = self.chart.leftAxis
leftAxis.labelFont = .systemFont(ofSize: 10)
leftAxis.drawGridLinesEnabled = false
leftAxis.valueFormatter = DefaultAxisValueFormatter(formatter: leftAxisFormatter)
leftAxis.labelPosition = .outsideChart
leftAxis.spaceTop = 0.15
leftAxis.labelCount = 8
leftAxis.axisMinimum = 0 // FIXME: HUH?? this replaces startAtZero = YES
let l = self.chart.legend
l.horizontalAlignment = .left
l.verticalAlignment = .bottom
l.orientation = .horizontal
l.drawInside = false
l.form = .circle
l.formSize = 9
l.font = UIFont(name: "HelveticaNeue-Light", size: 11)!
l.xEntrySpace = 4
let marker = XYMarkerView(color: UIColor(white: 180/250, alpha: 1),
font: .systemFont(ofSize: 12),
textColor: .white,
insets: UIEdgeInsets(top: 8, left: 8, bottom: 20, right: 8),
xAxisValueFormatter: self.chart.xAxis.valueFormatter!)
marker.chartView = self.chart
marker.minimumSize = CGSize(width: 80, height: 40)
self.chart.marker = marker
self.chart.rightAxis.enabled = false
self.addSubview(self.chart)
let upperConstraintChart = NSLayoutConstraint(item: self.chart, attribute: NSLayoutAttribute.top, relatedBy: NSLayoutRelation.equal, toItem: self.titleLabel!, attribute: NSLayoutAttribute.bottom, multiplier: 1, constant: 20)
let leftConstraintChart = NSLayoutConstraint(item: self.chart, attribute: NSLayoutAttribute.left, relatedBy: NSLayoutRelation.equal, toItem: self, attribute: NSLayoutAttribute.left, multiplier: 1, constant: 10)
let rightConstraintChart = NSLayoutConstraint(item: self.chart, attribute: NSLayoutAttribute.right, relatedBy: NSLayoutRelation.equal, toItem: self, attribute: NSLayoutAttribute.right, multiplier: 1, constant: -10)
let bottomConstraintChart = NSLayoutConstraint(item: self.chart, attribute: NSLayoutAttribute.bottom, relatedBy: NSLayoutRelation.equal, toItem: self, attribute: NSLayoutAttribute.bottom, multiplier: 1, constant: -10)
NSLayoutConstraint.activate([upperConstraintChart,leftConstraintChart,rightConstraintChart,bottomConstraintChart])
self.setupDataForChart()
}
func setupDataForChart(){
var set1: BarChartDataSet! = nil
var values:[BarChartDataEntry] = []
for i in 10..<30 {
// Specify date components
let formatter = DateFormatter()
formatter.dateFormat = "dd/MM/yyyy"
let someDateTime = formatter.date(from: "\(i)/10/2016")
print("anuran x value \(someDateTime!.timeIntervalSince1970)")
values.append(BarChartDataEntry(x: someDateTime!.timeIntervalSince1970, y: Double(20)))
}
set1 = BarChartDataSet(values: values, label: "")
var colors:[UIColor] = []
for i in 0..<values.count {
var color = UIColor(netHex: "FFC300")
if i == values.count - 1 {
color = UIColor.cyan
}
colors.append(color)
}
set1.colors = colors
//set1.drawValuesEnabled = true
let data = BarChartData(dataSet: set1)
data.setValueFont(UIFont(name: "HelveticaNeue-Light", size: 10)!)
data.barWidth = 0.9
self.chart.legend.setCustom(entries: [LegendEntry(label: "Earlier", form: Legend.Form.circle, formSize: CGFloat.nan, formLineWidth: CGFloat.nan, formLineDashPhase: 10, formLineDashLengths: [CGFloat.nan], formColor: UIColor(netHex: "FFC300")),
LegendEntry(label: "Today", form: Legend.Form.circle, formSize: CGFloat.nan, formLineWidth: CGFloat.nan, formLineDashPhase: 10, formLineDashLengths: [CGFloat.nan], formColor: UIColor.cyan)])
self.chart.data = data
self.chart.setVisibleXRangeMaximum(5)
}
我得到的结果如下:
无限滚动,不知道11/10/2016什么时候来.这有什么问题吗?
it scrolls for indefinite amount, I do not know when 11/10/2016 will come. What's wrong with this?
推荐答案
事实证明您不能为 BarChartDataEntry
的 X 值设置任何值.因此,您应该做的是将索引 0 置于用于保存模型的数组的长度,并在 IAxisValueFormatter
子类中保存时间戳值.因此,当您覆盖 stringForValue
时,从存储的属性中获取时间戳.所以你的子类应该是这样的:
Turns out you can not set any value to the X value of the BarChartDataEntry
. So what you should do is put index 0 to length of the array you are using to hold your model and inside your IAxisValueFormatter
subclass hold the timestamp values. so when you override stringForValue
get the timestamp from the stored property. So your subclass should look like this:
import Foundation
import Charts
public class DateValueFormatter: NSObject, IAxisValueFormatter {
private let dateFormatter = DateFormatter()
var values:[TimeInterval]!
override init() {
super.init()
dateFormatter.dateFormat = "dd/MM/yy"
}
public func stringForValue(_ value: Double, axis: AxisBase?) -> String {
return dateFormatter.string(from: Date(timeIntervalSince1970: self.values![Int(value)]))
}
}
所以最重要的是你应该维护一个额外的数组来保存时间戳值并将正常的for循环索引
作为BarChartDataEntry
So bottom line is you should maintain one extra array to hold the timestamp value and put normal for loop index
as the X value of the BarChartDataEntry
这篇关于设置 setVisibleXRangeMaximum 时,iOS 图表 X 轴值无限重复的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!