簡體   English   中英

IOS Charts 折線圖視圖 Double 值無法轉換為 Int 因為它是無限的

[英]IOS Charts line chart view Double value cannot be converted to Int because it is either infinite

我一直在為我的應用程序使用 IOS 圖表庫。 我有包含折線圖、餅圖和條形圖的表格視圖單元格。 我第一次進入應用程序時,顯示圖表沒有問題,但是,當我捏​​放大折線圖視圖時,在 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 圖表致命錯誤圖像

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

您的interval值為NaN (不是數字)。 這就是錯誤的原因。

你需要追蹤它的來源。 您可以測試一個Double ,看它是否是Nan.isNaN

例如:

if interval.isNaN {
    interval = 0
}

如果interval變為負數,則log10將返回Nan 0log10也不好。 接近0值將產生較大的負值。 您應該考慮所有這些。


您似乎還使用Int將值截斷為整數。 使用floor函數來做到這一點:

替換:

Double(Int(log10(interval)))

與:

floor(log10(interval))

即使我嘗試了這些解決方案,也沒有一個適合我。 因此,我在 Charts 庫的 AxisRendererBase.swift 類中添加了 isNaN 控件。 現在,AxisRendererBase 類的第 98 行應如下所示,

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

剛剛遇到了同樣的問題,不需要擺弄庫中的類,但是如果沒有數據可以計算它們,請強制設置您的最小值和最大值。

如果沒有數據可以計算它們,那么它們將是負無窮大和正無窮大,這會導致崩潰發生。

對於我的代碼,修復如下:

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

我剛剛通過編輯 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()
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM