设置setVisibleXRangeMaximum时,iOS图表X轴值将无限期重复

时间:2019-08-02 12:19:25

标签: ios swift mpandroidchart ios-charts

我试图绘制一个图表,其中x轴为TimeInterval,Y轴为power consumption。每天都会有太多数据需要显示。因此,我想一次显示5个值。我是在为图表设置数据后设置self.chart.setVisibleXRangeMaximum(5)来实现的。尽管显示了5个x轴值,但是这些值会无限期地重复。就像第一天是2016年10月10日之后,无限滚动之后的所有x轴值都相同(请参见下面的屏幕截图)。其他一些SO回答说启用设置粒度将解决此问题,但是即使启用它也会显示第一点的重复不确定值。我该怎么解决?

我当前正在使用的代码(出于测试目的使用虚拟数据)

         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)
        }

我得到的结果如下:

result

它滚动不确定的数量,我不知道2016年11月10日将到来。怎么了?

1 个答案:

答案 0 :(得分:0)

结果是您无法将任何值设置为BarChartDataEntry的X值。因此,您应该做的是将索引0设置为用来保存模型的数组的长度,并在IAxisValueFormatter子类中保存时间戳记值。因此,当您覆盖stringForValue时,将从存储的属性中获取时间戳。因此,您的子类应如下所示:

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 loop index作为BarChartDataEntry的X值