IOS图表折线图视图双值不能转换为Int,因为它是无限的

时间:2018-04-20 11:28:27

标签: ios swift uitableview linechart ios-charts

我一直在为我的应用程序使用IOS Charts库。我有表视图单元格,包括折线图,饼图和条形图。我第一次进入应用程序时显示图表没有问题,但是当我将缩放放到折线图视图中时,我在AxisRendererBase类中遇到以下错误。 Fatal error: Double value cannot be converted to Int because it is either infinite or NaN。如果我禁用捏拉缩放它可以正常工作。我不明白这个问题,我的configureCell方法如下。

func configureLineChart(xTitle:IndexAxisValueFormatter, index:Int) {
    lineChartView.data?.setDrawValues(false)
    lineChartView.doubleTapToZoomEnabled = false
    lineChartView.chartDescription?.enabled = false
    lineChartView.animate(xAxisDuration: 1)
    lineChartView.xAxis.labelPosition = .bottom
    lineChartView.xAxis.drawGridLinesEnabled = false
    lineChartView.xAxis.labelRotationAngle = 45
    lineChartView.xAxis.labelFont = UIFont(name: "HelveticaNeue-Light", size: 8.0)!
    lineChartView.xAxis.valueFormatter = xTitle
    lineChartView.xAxis.labelCount = index
    lineChartView.xAxis.spaceMin = 0.5
    lineChartView.xAxis.spaceMax = 0.5
    lineChartView.xAxis.granularityEnabled = true
    lineChartView.xAxis.granularity = 1
    lineChartView.rightAxis.enabled = false
    //lineChartView.setScaleEnabled(false)
    lineChartView.notifyDataSetChanged()
    lineChartView.pinchZoomEnabled = true
}

当我尝试调试时,我的lldb中有以下图像。 IOS Charts fatal error image

我在StackOverFlow上搜索并尝试了其他答案。但是,我所尝试的并没有奏效。可能是什么原因以及如何解决?

编辑:在我的cellForRowAt方法

    let cell = grafikTableView.dequeueReusableCell(withIdentifier: "chartCell") as? ChartsCell

    cell?.lineChartView.data = MainGrafikVC.lineChartDataArray[indexPath.row]
    cell?.barChartView.data = MainGrafikVC.barChartDataArray[indexPath.row]        
    cell?.barChartView.isHidden = false
    cell?.lineChartView.isHidden = false

    if MainGrafikVC.barChartDataArray[indexPath.row].dataSetCount != 0 {
cell?.configureBarChart(xTitle: MainGrafikVC.xTitleArray[indexPath.row], index: MainGrafikVC.barChartDataArray[indexPath.row].getDataSetByIndex(0).entryCount, chartData: MainGrafikVC.barChartDataArray[indexPath.row], chartType: Servisler.servisListesi[MainGrafikVC.indexler[indexPath.row]].chartType)
cell?.lineChartView.isHidden = true
    }
    if MainGrafikVC.lineChartDataArray[indexPath.row].dataSetCount != 0 {
    cell?.configureLineChart(xTitle:MainGrafikVC.xTitleArray[indexPath.row] , index: MainGrafikVC.lineChartDataArray[indexPath.row].getDataSetByIndex(0).entryCount)
    cell?.barChartView.isHidden = true
    }

当用户想要在代码工作后将图表添加到我的主表视图中时。

if (Servisler.servisListesi[MainGrafikVC.indexler[MainGrafikVC.listIndex]].chartType == "line") {
    self.createLineChart()
}

if (Servisler.servisListesi[MainGrafikVC.indexler[MainGrafikVC.listIndex]].chartType == "bar" || Servisler.servisListesi[MainGrafikVC.indexler[MainGrafikVC.listIndex]].chartType == "clustered") {
    self.createBarChart()
}

在我的createLineChart方法

func createLineChart() {
    let data = LineChartData()        
    var lineChartEntry1 = [ChartDataEntry]()
    for i in 0..<x1.count {
        lineChartEntry1.append(ChartDataEntry(x: Double(i), y: Double(x1[i]) ?? 0.0))
    }
    let line1 = LineChartDataSet(values: lineChartEntry1, label: "1")
    data.addDataSet(line1)        
    if (x2.count > 0) {
        var lineChartEntry2 = [ChartDataEntry]()
        for i in 0..<x2.count {
            lineChartEntry2.append(ChartDataEntry(x: Double(i), y: Double(x2[i]) ?? 0.0))
        }
    let line2 = LineChartDataSet(values: lineChartEntry2, label: "2")
    data.addDataSet(line2)
    }

    if (x3.count > 0) {
        var lineChartEntry3 = [ChartDataEntry]()
        for i in 0..<x3.count {
            lineChartEntry3.append(ChartDataEntry(x: Double(i), y: Double(x3[i]) ?? 0.0))
        }
        let line3 = LineChartDataSet(values: lineChartEntry3, label: "3")
        data.addDataSet(line3)
    }

        MainGrafikVC.lineChartDataArray.append(data)
        MainGrafikVC.barChartDataArray.append(BarChartData())
        MainGrafikVC.xTitleArray.append(IndexAxisValueFormatter(values: xTitle))
}

4 个答案:

答案 0 :(得分:1)

您的interval值为NaN(不是数字)。这就是错误的原因。

您需要追踪它的来源。您可以使用Double测试Nan以查看它是.isNaN

例如:

if interval.isNaN {
    interval = 0
}

如果interval变为否定,则log10将返回Nan。取log10 0也不好。 0附近的值将产生较大的负值。你应该考虑所有这些因素。

您似乎也在使用Int将值截断为整数。使用floor功能执行此操作:

替换:

Double(Int(log10(interval)))

使用:

floor(log10(interval))

答案 1 :(得分:0)

即使我尝试过这些解决方案,但它们都没有适合我。所以,我在Charts库的AxisRendererBase.swift类中添加了isNaN控件。现在,AxisRendererBase类的第98行应该如下所示,

if labelCount == 0 || range <= 0 || range.isInfinite || range.isNaN

答案 2 :(得分:0)

刚刚遇到了同样的问题,没有必要摆弄库中的类,但是如果没有数据可以计算它们,请强制设置您的最小值和最大值。

如果没有数据来计算它们,那么它们将是负无穷大和正无穷大,从而导致崩溃发生。

对于我的代码,修复如下:

//If less than two items in line
//Force min and max to avoid range crash in library
if doubleValueArray.compactMap({ $0 }).count <= 2 {
    chartView.leftAxis.axisMinimum = 0
    chartView.leftAxis.axisMaximum = 100
} else {
    chartView.leftAxis.axisMinimum = lineChartData.yMin
    chartView.leftAxis.axisMaximum = lineChartData.yMax
}

答案 3 :(得分:0)

我刚刚通过编辑 AxisRendererBase 类解决了这个问题。 我的错误和你的一样。 它在第 119 行遇到该错误

将您的 Double(Int(log10(interval))) 替换为 floor(log10(fabs(interval)))

错误

AxisRendererBase.swift
    let intervalMagnitude = pow(10.0, Double(Int(log10(interval)))).roundedToNextSignficant() //error line 

已解决

AxisRendererBase.swift
      let intervalMagnitude = pow(10.0, floor(log10(fabs(interval)))).roundedToNextSignficant()

++ 如果它不起作用, 当records.isEmpty时请不要设置图表。

喜欢

if(!records.isEmpty){
   showChart()
}