【问题标题】:mp android (line chart) Iaxisvalue formatter causes ArrayIndexOutOfBoundsException: length=10; index=-1mp android(折线图)Iaxisvalue 格式化程序导致 ArrayIndexOutOfBoundsException: length=10;指数=-1
【发布时间】:2020-10-14 06:43:15
【问题描述】:

我的应用程序运行良好,但只要我添加 iaxisvalue 格式化程序,应用程序就会崩溃并返回 ArrayIndexOutOfBoundsException: length=10; index=-1 并且我迷路了,无法找到如何使用 kotlin 解决它的正确解决方案

这是我的活动片段,当涉及到图表时,我试图将 x 轴值格式化为字符串值:

    chart.xAxis.valueFormatter =
                IAxisValueFormatter { value, axis ->
                    if (xAxis[value.toInt()] == 0) "12 AM" 
                    else if (xAxis[value.toInt()] < 12) "${xAxis[value.toInt()]} AM" 
                    else if (xAxis[value.toInt()] == 12) "12 PM" 
                    else "${xAxis[value.toInt()] - 12} PM"
                }

与上述类似,但在超过 12AM 后返回上述错误

这是使用图表的活动片段,以下函数获取图表数据以获取每日数据,以及 xaxis 值,这里我试图在 xaxis 上显示时间。

 private fun fillTodayData() {
        chart.invalidate()
        try {
            if (todayData.size < 1) {
                chart.visibility = View.GONE
                xAxisLabel.visibility = View.GONE
                return
            } else {
                chart.visibility = View.VISIBLE
                xAxisLabel.visibility = View.GONE
            }

            val LineEntries = ArrayList<Entry>()
            //val LineEntries: MutableList<Entry> = ArrayList()
            val dataObjects = todayData
            val xAxis = mutableListOf<Int>()
            var i = 0
            for (step in dataObjects) {
                // turn your data into Entry objects
                if (step.value > 0) {
                    LineEntries.add(Entry(i.toFloat(), step.value.toFloat()))
                    Log.d(
                        LOG_TAG,
                        "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxgraph entries $LineEntries \n$step"
                    )
                    xAxis.add(step.key)
                    i++
                }
            }
            val vl = LineDataSet(LineEntries, "My Type")
            //Part4
            //setting color for the line graph and the gradient
            val color = ContextCompat.getColor(context!!, R.color.yellowBar)
            vl.setColor(color)
            vl.setDrawFilled(true)
            if (Utils.getSDKInt() >= 18) {
                // fill drawable only supported on api level 18 and above
                val drawable: Drawable? =
                    ContextCompat.getDrawable(context!!, R.drawable.gradient_background)
                vl.setFillDrawable(drawable)
            } else {
                vl.setFillColor(Color.BLACK)
            }
            vl.setDrawValues(true)
            vl.lineWidth = 1f
            chart.xAxis.labelRotationAngle = 0f
            val lineData = LineData(vl)
            lineData.isHighlightEnabled = true //marker for each point
            lineData.setValueFormatter { value, _, _, _ ->
                if (value > 0) {
                    "$value"
                } else {
                    ""
                }
            }
            chart.data = lineData
            val graphSize: Int = if (LineEntries.size > 8) 8 else LineEntries.size
//
            chart.setVisibleXRangeMaximum(graphSize.toFloat())
            chart.moveViewToX(0F)
////
            chart.xAxis.labelCount = graphSize
            Log.d(LOG_TAG, "today $dataObjects \n$xAxis")

            println("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + xAxis)
            println("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + graphSize)
            chart.xAxis.valueFormatter =
                IAxisValueFormatter { value, axis ->
                    if (xAxis[value.toInt()] == 0) "12 AM" else if (xAxis[value.toInt()]
                        < 12
                    ) "${xAxis[value.toInt()]} AM" else if (xAxis[value.toInt()] == 12) "12 PM" else
                        "${xAxis[value.toInt()] - 12} PM"
                }

            chart.getXAxis().setDrawLabels(true);
            chart.invalidate()
//Part8
            chart.setTouchEnabled(true)
            chart.setPinchZoom(true)
            chart.getAxisLeft().setDrawGridLines(false);
//Part9
            chart.description.text = ""

//Part10
            chart.animateX(1800, Easing.EaseInExpo)

//Part11
            val markerView = CustomMarker(context!!, R.layout.marker_view)
            chart.marker = markerView
            chart.isScaleXEnabled = false
            chart.isDoubleTapToZoomEnabled = false
            chart.setScaleEnabled(false)
            dataLayout.visibility = View.VISIBLE
            progressBar.visibility = View.GONE


        } catch (e: Exception) {
            Log.d(LOG_TAG, "fillTodayData() Exception $e")
        }
    }

【问题讨论】:

    标签: android kotlin mpandroidchart linechart


    【解决方案1】:

    不能保证在有实际数据点的位置准确绘制标签。例如。可以在最低 x 值的左侧进一步绘制标签。这很可能是您的示例中发生的情况,因为异常表示它希望获取索引 -1 处的值,因此最低 x 值 0 左侧的 1。

    但是您的方法不支持这一点。我认为您可以通过以下方式解决此问题:

    1. 插值/外推值。
      • 例如对于 x 值 -1,您可能希望显示“晚上 11 点”(最后一天)。
      • 例如,MpAndroidChart 也可能希望在 5.5 处显示标签(如果您放大图表)。在这种情况下,您可以显示 5:30 AM。
      • 通过设置chart.xAxis.granularity = 1f,您可以防止 MpAndroidChart 标记 x 值,例如 5.5。
    2. 根本不显示与实际数据点不对应的标签。在您的 ValueFormatter 中,您可以只为这些情况返回一个空字符串。我建议仅将其与 chart.xAxis.granularity = 1f 结合使用。

    【讨论】:

      猜你喜欢
      • 2016-01-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多