Я пытаюсь нарисовать многоугольник с помощью MPAndroidChart в AndroidStudio в Котлине для разработки Android. Я столкнулся с проблемой визуального рендеринга.
Я рисую 2 разных полигона на 2 разных графиках. Первый работает отлично, но второй создает проблему визуального рендеринга и приводит к сбою моего приложения, когда я пытаюсь увеличить масштаб или сделать что-либо на своей диаграмме.
Координата для второго полигона должна быть следующей:
polygonTopView = Polygon(
Pair(92.0, 3.0),
Pair(100.0, 3.0),
Pair(102.5, 1.5),
Pair(102.5, -1.5),
Pair(100.0, -3.0),
Pair(92.0, -3.0),
Pair(92.0, 3.0)
)
Результатом является следующая картинка ниже со вторым полигоном, для которого у меня есть только одна линия, и он вылетает всякий раз, когда я его касаюсь.
Если я просто прокомментирую координату Pair(100.0, -3.0), У меня нет этой проблемы, но, конечно, я хочу нарисовать свой полный полигон. Ниже показан полигон без координаты, вызвавшей ошибку:
Наконец, если координата Pair(100.0, -3.0) находится где-то выше или равна последней по оси X, это работает. Например, если я поставлю Pair(103.0, -3.0),, это сработает.
Кто-нибудь может помочь мне с этой проблемой?
Я пробовал много вещей, но я действительно не понимаю проблемы
О коде сказать особо нечего, потому что проблема связана с координатами, но вот моя функция для рисования моего многоугольника:
private fun drawPolygon(view: View, polygonSideView: Polygon, polygonTopView: Polygon){
chartSideView = view.findViewById(R.id.chartSideView)
chartSideView.setTouchEnabled(true)
chartSideView.setPinchZoom(true)
val entriesSideView = mutableListOf<Entry>()
for (point in polygonSideView.vertices) {
entriesSideView.add(Entry(point.first.toFloat(), point.second.toFloat()))
}
val dataSetSideView = LineDataSet(entriesSideView, "CG limit Side view")
dataSetSideView.color = ColorTemplate.COLORFUL_COLORS[0]
dataSetSideView.lineWidth = 1f // set the line width to 2 pixels
dataSetSideView.fillColor = ColorTemplate.COLORFUL_COLORS[0]
dataSetSideView.setDrawFilled(true)
val lineDataSetsSideView = mutableListOf<ILineDataSet>()
lineDataSetsSideView.add(dataSetSideView)
val lineDataSideView = LineData(lineDataSetsSideView)
chartSideView.data = lineDataSideView
chartSideView.description.isEnabled = false
chartSideView.legend.isEnabled = true
chartSideView.axisRight.isEnabled = false
chartSideView.axisLeft.axisMinimum = 1500f
chartSideView.axisLeft.axisMaximum = 2600f
//chartSideView.xAxis.labelRotationAngle = -45f
chartSideView.xAxis.granularity = 1f
chartSideView.xAxis.isGranularityEnabled = true
chartSideView.xAxis.axisMinimum = 91f
chartSideView.xAxis.axisMaximum = 103f
chartSideView.invalidate()
// end of sideview
// chartview 2
//chartTopView = view?.findViewById(R.id.chartTopView) ?: throw IllegalStateException("View is null")
chartTopView = view.findViewById(R.id.chartTopView)
chartTopView.setTouchEnabled(true)
chartTopView.setPinchZoom(true)
val entriesTopView = mutableListOf<Entry>()
for (point in polygonTopView.vertices) {
entriesTopView.add(Entry(point.first.toFloat(), point.second.toFloat()))
}
//entriesTopView.add(Entry(polygonTopView.vertices[0].first.toFloat(), polygonTopView.vertices[0].second.toFloat()))
val dataSetTopView = LineDataSet(entriesTopView, "CG limit Top view")
dataSetTopView.color = ColorTemplate.COLORFUL_COLORS[0]
dataSetTopView.lineWidth = 2f // set the line width to 2 pixels
dataSetTopView.fillColor = ColorTemplate.COLORFUL_COLORS[0]
dataSetTopView.setDrawFilled(true)
val lineDataSetsTopView = mutableListOf<ILineDataSet>()
lineDataSetsTopView.add(dataSetTopView)
val lineDataTopView = LineData(lineDataSetsTopView)
chartTopView.data = lineDataTopView
chartTopView.description.isEnabled = false
chartTopView.legend.isEnabled = true
chartTopView.axisRight.isEnabled = false
chartTopView.axisLeft.axisMinimum = -4f
chartTopView.axisLeft.axisMaximum = 4f
//chartTopView.xAxis.labelRotationAngle = -45f
chartTopView.xAxis.granularity = 1f
chartTopView.xAxis.isGranularityEnabled = true
chartTopView.xAxis.axisMinimum = 91f
chartTopView.xAxis.axisMaximum = 103f
chartTopView.invalidate()
}
@TylerV Мне нечего сказать о моем коде, потому что проблема связана с координатами, но я отредактировал свой пост, добавив свою функцию, которая рисует многоугольник, и у меня нет ничего в виде сообщения о сбое, приложение просто закрывается
В случае сбоя всегда появляется сообщение о сбое, посмотрите на вкладку Logcat в Android Studio (нижняя часть экрана). Я посмотрю, смогу ли я воспроизвести это из того, что вы разместили
Проблема в том, что линейная диаграмма предполагает, что предоставленные точки будут отсортированы по координате x (возрастанию). Если их нет, может возникнуть ряд ошибок. Некоторая предыстория этого требования есть в этом выпуске Github и в документации.
Имейте в виду, что эта библиотека официально не поддерживает рисование данных LineChart из списка записей, не отсортированных по x-позиции записей в порядке возрастания. Добавление записей несортированным образом может привести к правильному рисованию, но также может привести к непредвиденному поведению.
Даже в случае "работы", когда вы отбрасывали точку (100,-3), если вы увеличили масштаб диаграммы и прокрутили ее, заливка будет отображаться неправильно. В этом случае, когда вы пытаетесь панорамировать или масштабировать, включая точку (100,-3), возникает следующая ошибка:
Process: com.example.chartdemo, PID: 31183
java.lang.NegativeArraySizeException: -6
at com.github.mikephil.charting.utils.Transformer.generateTransformedValuesLine(Transformer.java:178)
at com.github.mikephil.charting.renderer.LineChartRenderer.drawValues(LineChartRenderer.java:549)
at com.github.mikephil.charting.charts.BarLineChartBase.onDraw(BarLineChartBase.java:278)
at android.view.View.draw(View.java:22644)
Одним из решений является разделение ребер многоугольника на несколько отдельных линий, одна из которых проходит «поверх» многоугольника, а другая образует основание. Оба они должны быть неубывающими по X.
val polyUpper = listOf(
Pair(92.0, -3.0),
Pair(92.0, 3.0),
Pair(100.0, 3.0),
Pair(102.5, 1.5),
Pair(102.5, -1.5)
)
val polyLower = listOf(
Pair(92.0, -3.0),
Pair(100.0, -3.0),
Pair(102.5, -1.5)
)
val entriesUpper = polyUpper.map { Entry(it.first.toFloat(), it.second.toFloat()) }
val entriesLower = polyLower.map { Entry(it.first.toFloat(), it.second.toFloat()) }
val dataSetUpper = LineDataSet(entriesUpper, "CG limit Side view")
dataSetUpper.color = ColorTemplate.COLORFUL_COLORS[0]
dataSetUpper.lineWidth = 1f // set the line width to 2 pixels
dataSetUpper.fillColor = ColorTemplate.COLORFUL_COLORS[0]
dataSetUpper.setDrawFilled(true)
val dataSetLower = LineDataSet(entriesLower, "")
dataSetLower.color = ColorTemplate.COLORFUL_COLORS[0]
dataSetLower.lineWidth = 1f // set the line width to 2 pixels
dataSetLower.fillColor = ColorTemplate.COLORFUL_COLORS[0]
dataSetLower.setDrawFilled(true)
val lineDataSideView = LineData(listOf(dataSetUpper, dataSetLower))
Результат:
Примечания
Color.WHITE вместо альфа-канала 255. Это описано ️ 🔁 здесь LineDataSet, что будет работать с полигоном любой сложности.Большое спасибо ! Это объясняет проблему и почему она связана с моими данными. Я попробую некоторые из предложенных вами решений, но, с моей точки зрения, вопрос можно считать закрытым.
Если приложение дает сбой, включите в свой вопрос полную трассировку стека из Logcat. Вы также должны включить достаточно кода, чтобы кто-то другой мог воспроизвести вашу проблему — очень мало кто может сделать с объемом информации, которую вы здесь включили.