valueformatter/getFormattedValue IndexOutOfBoundsException:索引:7,大小:7 MpAndroidChart in Barchart
valueformatter/getFormattedValue IndexOutOfBoundsException: Index: 7, Size: 7 MpAndroidChart in Barchart
尝试在 valueformatter 中创建水平条形图时出现以下错误,但 xAxis 和 mydatasets 的大小相同。
这里的奇怪行为是,如果数据集的大小和 xAxis 是 8:8,那么没有任何问题,但超出 7:7 之类的,它会给我例外。我已经打印了数据集和 xAxis 数组列表,这是 7:7 ratio:
的输出
E/Data: [DataSet, label: NADEC, entries: 1
Entry, x: 0.0 y: -99.8 , DataSet, label: ALMARAI, entries: 1
Entry, x: 1.0 y: -3.7 , DataSet, label: CREME CARAMEL, entries: 1
Entry, x: 2.0 y: -3.7 , DataSet, label: DANETTE, entries: 1
Entry, x: 3.0 y: -2.9 , DataSet, label: AL MAZRAH, entries: 1
Entry, x: 4.0 y: 0.0 , DataSet, label: PRIVATE LABEL, entries: 1
Entry, x: 5.0 y: 7.8 , DataSet, label: RAWABEH, entries: 1
Entry, x: 6.0 y: 61.5 ]
E/Brands: [NADEC, ALMARAI, CREME CARAMEL, DANETTE, AL MAZRAH, PRIVATE LABEL, RAWABEH]
这里一切似乎都很好?
这是水平条形图的设置代码:
private fun filterHorizontalBarData(myList: List<ResponseBrandValueGrowthChart>?) {
try {
val brand = ArrayList<String>()
var index = 0f
var color_index = 0
val data = BarData()
for (item in myList!!) {
if (item.kPI.equals("Value % Growth") || item.kPI.equals("Volume % growth")) {
val kpiValue = ArrayList<BarEntry>()
kpiValue.add(BarEntry(index,item.kPIvalue.toFloat()))
brand.add(item.brand)
val barDataSet = BarDataSet(kpiValue, item.brand)
if(color_index<7)
barDataSet.setColor(getColor(horizonatal_chart.context, getColorID(color_index)))
else
barDataSet.setColor(getColorID(color_index))
data.addDataSet(barDataSet)
index++
color_index++
}
}
setHorizontalChart(data, brand)
}catch (e: Exception){
e.printStackTrace()
}
}
private fun setHorizontalChart(data : BarData, brand: ArrayList<String>){
Log.e("Data ",data.dataSets.toString())
Log.e("Brands ",brand.toString())
horizonatal_chart.setDrawBarShadow(false)
val description = Description()
description.text = ""
horizonatal_chart.description = description
horizonatal_chart.legend.setEnabled(false)
horizonatal_chart.setPinchZoom(false)
horizonatal_chart.setDrawValueAboveBar(false)
horizonatal_chart.setScaleEnabled(false)
horizonatal_chart.setDrawValueAboveBar(true)
//Display the axis on the left (contains the labels 1*, 2* and so on)
val xAxis = horizonatal_chart.getXAxis()
xAxis.setDrawGridLines(false)
xAxis.setPosition(XAxis.XAxisPosition.BOTTOM)
xAxis.setEnabled(true)
xAxis.setDrawAxisLine(false)
xAxis.textColor = Color.parseColor("#a1a1a1")
val yLeft = horizonatal_chart.axisLeft
//Set the minimum and maximum bar lengths as per the values that they represent
yLeft.axisMaximum = 100f
yLeft.axisMinimum = 0f
yLeft.isEnabled = false
//Now add the labels to be added on the vertical axis
xAxis.valueFormatter = IAxisValueFormatter { value, axis -> brand[value.toInt()] }
val yRight = horizonatal_chart.axisRight
yRight.setDrawAxisLine(true)
yRight.setDrawGridLines(false)
yRight.isEnabled = false
//Set bar entries and add necessary formatting
horizonatal_chart.axisLeft.setAxisMinimum(data.yMin)
data.barWidth = 0.9f
// val myCustomChartRender = MyCustomChartRender(horizonatal_chart, horizonatal_chart.animator, horizonatal_chart.viewPortHandler)
// //Add animation to the graph
// horizonatal_chart.renderer = myCustomChartRender
horizonatal_chart.animateY(2000)
horizonatal_chart.data = data
horizonatal_chart.setTouchEnabled(false)
horizonatal_chart.invalidate()
}
这段代码有什么问题吗?以及为什么它使用大小为 8 的 mydata 和标签?
请帮帮我!!!
更新:
异常堆栈跟踪:
java.lang.IndexOutOfBoundsException: Index: 7, Size: 7
at java.util.ArrayList.get(ArrayList.java:411)
at com.almaraiquest.almarai.GrowthStoryFragment$setHorizontalChart.getFormattedValue(GrowthStoryFragment.kt:321)
at com.github.mikephil.charting.components.AxisBase.getFormattedLabel(AxisBase.java:489)
at com.github.mikephil.charting.components.AxisBase.getLongestLabel(AxisBase.java:475)
at com.github.mikephil.charting.renderer.XAxisRendererHorizontalBarChart.computeSize(XAxisRendererHorizontalBarChart.java:67)
at com.github.mikephil.charting.renderer.XAxisRenderer.computeAxisValues(XAxisRenderer.java:74)
at com.github.mikephil.charting.renderer.XAxisRendererHorizontalBarChart.computeAxis(XAxisRendererHorizontalBarChart.java:58)
at com.github.mikephil.charting.charts.BarLineChartBase.onDraw(BarLineChartBase.java:209)
at android.view.View.draw(View.java:17071)
at android.view.View.updateDisplayListIfDirty(View.java:16053)
at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3754)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3734)
at android.view.View.updateDisplayListIfDirty(View.java:16016)
at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3754)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3734)
at android.view.View.updateDisplayListIfDirty(View.java:16016)
at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3754)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3734)
at android.view.View.updateDisplayListIfDirty(View.java:16016)
at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3754)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3734)
at android.view.View.updateDisplayListIfDirty(View.java:16016)
at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3754)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3734)
at android.view.View.updateDisplayListIfDirty(View.java:16016)
at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3754)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3734)
at android.view.View.updateDisplayListIfDirty(View.java:16016)
at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3754)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3734)
at android.view.View.updateDisplayListIfDirty(View.java:16016)
at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3754)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3734)
at android.view.View.updateDisplayListIfDirty(View.java:16016)
at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3754)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3734)
at android.view.View.updateDisplayListIfDirty(View.java:16016)
at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3754)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3734)
at android.view.View.updateDisplayListIfDirty(View.java:16016)
at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3754)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3734)
at android.view.View.updateDisplayListIfDirty(View.java:16016)
at android.view.ThreadedRenderer.updateViewTreeDisplayList(ThreadedRenderer.java:656)
at android.view.ThreadedRenderer.updateRootDisplayList(ThreadedRenderer.java:662)
at android.view.ThreadedRenderer.draw(ThreadedRenderer.java:770)
at android.view.ViewRootImpl.draw(ViewRootImpl.java:2828)
at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:2636)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2243)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1278)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6357)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:871)
at android.view.Choreographer.doCallbacks(Choreographer.java:683)
2019-12-24 07:46:31.169 26673-26673/com.almaraiquest E/AndroidRuntime: at android.view.Choreographer.doFrame(Choreographer.java:619)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:857)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6077)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
终于得到我的解决方案:
xAxis.valueFormatter = IAxisValueFormatter { value, axis ->
if (value.toInt() < brand.size) {
brand.get(value.toInt())
} else {
"0"
}
}
IAxisValueFormatter 已弃用,现在您可以使用 ValueFormatter。
inner class MyXAxisValueFormatter(private val values : ArrayList<String>) : ValueFormatter() {
override fun getFormattedValue(value : Float) : String {
return if (value.toInt() < values.size && value.toInt() >= 0) values[value.toInt()] else "0"
}
}
这是我根据之前的回答得出的解决方案。
JAVA 代码:
private void initSecGraph() {
// .....Other stuff.....
final ArrayList<String> x = measurements.getLastMeasurementsDurationsDates_ByLastDays(7);
ValueFormatter formatter = new ValueFormatter() {
@Override
public String getFormattedValue(float value) {
if(((int)value) < x.size())
return x.get((int) value) ;
else
return "0";
}
};
xAxis.setValueFormatter(formatter);
// .....Other stuff.....
}
尝试在 valueformatter 中创建水平条形图时出现以下错误,但 xAxis 和 mydatasets 的大小相同。
这里的奇怪行为是,如果数据集的大小和 xAxis 是 8:8,那么没有任何问题,但超出 7:7 之类的,它会给我例外。我已经打印了数据集和 xAxis 数组列表,这是 7:7 ratio:
的输出E/Data: [DataSet, label: NADEC, entries: 1
Entry, x: 0.0 y: -99.8 , DataSet, label: ALMARAI, entries: 1
Entry, x: 1.0 y: -3.7 , DataSet, label: CREME CARAMEL, entries: 1
Entry, x: 2.0 y: -3.7 , DataSet, label: DANETTE, entries: 1
Entry, x: 3.0 y: -2.9 , DataSet, label: AL MAZRAH, entries: 1
Entry, x: 4.0 y: 0.0 , DataSet, label: PRIVATE LABEL, entries: 1
Entry, x: 5.0 y: 7.8 , DataSet, label: RAWABEH, entries: 1
Entry, x: 6.0 y: 61.5 ]
E/Brands: [NADEC, ALMARAI, CREME CARAMEL, DANETTE, AL MAZRAH, PRIVATE LABEL, RAWABEH]
这里一切似乎都很好? 这是水平条形图的设置代码:
private fun filterHorizontalBarData(myList: List<ResponseBrandValueGrowthChart>?) {
try {
val brand = ArrayList<String>()
var index = 0f
var color_index = 0
val data = BarData()
for (item in myList!!) {
if (item.kPI.equals("Value % Growth") || item.kPI.equals("Volume % growth")) {
val kpiValue = ArrayList<BarEntry>()
kpiValue.add(BarEntry(index,item.kPIvalue.toFloat()))
brand.add(item.brand)
val barDataSet = BarDataSet(kpiValue, item.brand)
if(color_index<7)
barDataSet.setColor(getColor(horizonatal_chart.context, getColorID(color_index)))
else
barDataSet.setColor(getColorID(color_index))
data.addDataSet(barDataSet)
index++
color_index++
}
}
setHorizontalChart(data, brand)
}catch (e: Exception){
e.printStackTrace()
}
}
private fun setHorizontalChart(data : BarData, brand: ArrayList<String>){
Log.e("Data ",data.dataSets.toString())
Log.e("Brands ",brand.toString())
horizonatal_chart.setDrawBarShadow(false)
val description = Description()
description.text = ""
horizonatal_chart.description = description
horizonatal_chart.legend.setEnabled(false)
horizonatal_chart.setPinchZoom(false)
horizonatal_chart.setDrawValueAboveBar(false)
horizonatal_chart.setScaleEnabled(false)
horizonatal_chart.setDrawValueAboveBar(true)
//Display the axis on the left (contains the labels 1*, 2* and so on)
val xAxis = horizonatal_chart.getXAxis()
xAxis.setDrawGridLines(false)
xAxis.setPosition(XAxis.XAxisPosition.BOTTOM)
xAxis.setEnabled(true)
xAxis.setDrawAxisLine(false)
xAxis.textColor = Color.parseColor("#a1a1a1")
val yLeft = horizonatal_chart.axisLeft
//Set the minimum and maximum bar lengths as per the values that they represent
yLeft.axisMaximum = 100f
yLeft.axisMinimum = 0f
yLeft.isEnabled = false
//Now add the labels to be added on the vertical axis
xAxis.valueFormatter = IAxisValueFormatter { value, axis -> brand[value.toInt()] }
val yRight = horizonatal_chart.axisRight
yRight.setDrawAxisLine(true)
yRight.setDrawGridLines(false)
yRight.isEnabled = false
//Set bar entries and add necessary formatting
horizonatal_chart.axisLeft.setAxisMinimum(data.yMin)
data.barWidth = 0.9f
// val myCustomChartRender = MyCustomChartRender(horizonatal_chart, horizonatal_chart.animator, horizonatal_chart.viewPortHandler)
// //Add animation to the graph
// horizonatal_chart.renderer = myCustomChartRender
horizonatal_chart.animateY(2000)
horizonatal_chart.data = data
horizonatal_chart.setTouchEnabled(false)
horizonatal_chart.invalidate()
}
这段代码有什么问题吗?以及为什么它使用大小为 8 的 mydata 和标签? 请帮帮我!!!
更新: 异常堆栈跟踪:
java.lang.IndexOutOfBoundsException: Index: 7, Size: 7
at java.util.ArrayList.get(ArrayList.java:411)
at com.almaraiquest.almarai.GrowthStoryFragment$setHorizontalChart.getFormattedValue(GrowthStoryFragment.kt:321)
at com.github.mikephil.charting.components.AxisBase.getFormattedLabel(AxisBase.java:489)
at com.github.mikephil.charting.components.AxisBase.getLongestLabel(AxisBase.java:475)
at com.github.mikephil.charting.renderer.XAxisRendererHorizontalBarChart.computeSize(XAxisRendererHorizontalBarChart.java:67)
at com.github.mikephil.charting.renderer.XAxisRenderer.computeAxisValues(XAxisRenderer.java:74)
at com.github.mikephil.charting.renderer.XAxisRendererHorizontalBarChart.computeAxis(XAxisRendererHorizontalBarChart.java:58)
at com.github.mikephil.charting.charts.BarLineChartBase.onDraw(BarLineChartBase.java:209)
at android.view.View.draw(View.java:17071)
at android.view.View.updateDisplayListIfDirty(View.java:16053)
at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3754)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3734)
at android.view.View.updateDisplayListIfDirty(View.java:16016)
at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3754)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3734)
at android.view.View.updateDisplayListIfDirty(View.java:16016)
at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3754)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3734)
at android.view.View.updateDisplayListIfDirty(View.java:16016)
at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3754)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3734)
at android.view.View.updateDisplayListIfDirty(View.java:16016)
at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3754)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3734)
at android.view.View.updateDisplayListIfDirty(View.java:16016)
at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3754)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3734)
at android.view.View.updateDisplayListIfDirty(View.java:16016)
at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3754)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3734)
at android.view.View.updateDisplayListIfDirty(View.java:16016)
at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3754)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3734)
at android.view.View.updateDisplayListIfDirty(View.java:16016)
at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3754)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3734)
at android.view.View.updateDisplayListIfDirty(View.java:16016)
at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3754)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3734)
at android.view.View.updateDisplayListIfDirty(View.java:16016)
at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3754)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3734)
at android.view.View.updateDisplayListIfDirty(View.java:16016)
at android.view.ThreadedRenderer.updateViewTreeDisplayList(ThreadedRenderer.java:656)
at android.view.ThreadedRenderer.updateRootDisplayList(ThreadedRenderer.java:662)
at android.view.ThreadedRenderer.draw(ThreadedRenderer.java:770)
at android.view.ViewRootImpl.draw(ViewRootImpl.java:2828)
at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:2636)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2243)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1278)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6357)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:871)
at android.view.Choreographer.doCallbacks(Choreographer.java:683)
2019-12-24 07:46:31.169 26673-26673/com.almaraiquest E/AndroidRuntime: at android.view.Choreographer.doFrame(Choreographer.java:619)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:857)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6077)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
终于得到我的解决方案:
xAxis.valueFormatter = IAxisValueFormatter { value, axis ->
if (value.toInt() < brand.size) {
brand.get(value.toInt())
} else {
"0"
}
}
IAxisValueFormatter 已弃用,现在您可以使用 ValueFormatter。
inner class MyXAxisValueFormatter(private val values : ArrayList<String>) : ValueFormatter() {
override fun getFormattedValue(value : Float) : String {
return if (value.toInt() < values.size && value.toInt() >= 0) values[value.toInt()] else "0"
}
}
这是我根据之前的回答得出的解决方案。
JAVA 代码:
private void initSecGraph() {
// .....Other stuff.....
final ArrayList<String> x = measurements.getLastMeasurementsDurationsDates_ByLastDays(7);
ValueFormatter formatter = new ValueFormatter() {
@Override
public String getFormattedValue(float value) {
if(((int)value) < x.size())
return x.get((int) value) ;
else
return "0";
}
};
xAxis.setValueFormatter(formatter);
// .....Other stuff.....
}