iOS-Charts X Axis values are repeating indefinitely when setVisibleXRangeMaximum is set

折月煮酒 提交于 2021-01-28 08:24:04

问题


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

the result I am getting is like the following:

it scrolls for indefinite amount, I do not know when 11/10/2016 will come. What's wrong with this?


回答1:


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

}

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



来源:https://stackoverflow.com/questions/57326384/ios-charts-x-axis-values-are-repeating-indefinitely-when-setvisiblexrangemaximum

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!