设置 setVisibleXRangeMaximum 时,iOS 图表 X 轴值无限重复 [英] iOS-Charts X Axis values are repeating indefinitely when setVisibleXRangeMaximum is set

查看:265
本文介绍了设置 setVisibleXRangeMaximum 时,iOS 图表 X 轴值无限重复的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试绘制一个图表,其中 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆