我在应用中使用BarChart
,但有时当我重新绘制它时,条形宽度不受尊重而且我得到的结果不一致(即使X轴中的值总是100)。
这就是我希望它总是看起来的样子:
但有时它看起来像这样:
有谁知道为什么会发生这种情况,我怎么能强迫它总是看起来一样?
我认为它与X轴的值范围有关,因为当范围从0到50或类似时,图表看起来很好,但是当范围较小时它看起来很糟糕。
我已经设置了这样的条形宽度值,但它没有帮助:
barChartView?.data?.barWidth = 0.3f
这是我使用的完整图表配置(此方法仅在创建Fragment
时运行一次):
private fun setUpChartView() {
barChartView?.setTouchEnabled(false)
val xAxis = barChartView?.xAxis
val yAxis = barChartView?.axisLeft
// Hide all parts of the chart that we don't want to show
barChartView?.legend?.isEnabled = false
barChartView?.description?.isEnabled = false
barChartView?.setDrawGridBackground(false)
xAxis?.setDrawGridLines(false)
xAxis?.setDrawAxisLine(false)
yAxis?.setDrawAxisLine(false)
barChartView?.axisRight?.isEnabled = false
// Show the Y axis grid lines as dashed
yAxis?.enableGridDashedLine(5f, 10f, 0f)
val barChartTextColor = getColor(R.color.chart_text)
val barChartTextSize = 12f
val barChartLabelsTypeface = Typeface.SANS_SERIF
// Show the X axis labels at the bottom and set the proper style
xAxis?.position = XAxis.XAxisPosition.BOTTOM
xAxis?.textColor = barChartTextColor
xAxis?.textSize = barChartTextSize
xAxis?.typeface = barChartLabelsTypeface
// Set the proper style for the Y axis labels
yAxis?.textSize = barChartTextSize
yAxis?.textColor = barChartTextColor
yAxis?.typeface = barChartLabelsTypeface
barChartView?.setNoDataText("")
val viewPortHandler = barChartView?.viewPortHandler
val axisTransformer = barChartView?.getTransformer(LEFT)
// Set a custom axises so that we can control the drawing of the labels and grid lines
barChartView?.setXAxisRenderer(CustomEntriesXAxisRenderer(viewPortHandler = viewPortHandler,
xAxis = xAxis,
transformer = axisTransformer))
barChartView?.rendererLeftYAxis = CustomEntriesYAxisRenderer(viewPortHandler = viewPortHandler,
yAxis = yAxis,
transformer = axisTransformer)
}
这是我在获取新数据时用于绘制图表的代码:
private fun drawBarChart() {
// The data list has always 100 items
val entries = data.map { BarEntry(it.x, it.y) }
// Prepare the chart data set by adding the entries and configuring its style (colors, etc.)
val dataSet = BarDataSet(entries, null)
dataSet.setDrawValues(false)
dataSet.colors = colorsList
// Load data to chart
if (barChartView?.data == null) {
// If there is no data set yet, create a new data object and add it to the chart (this happens the first
// time we draw the chart after the Fragment was created, or after an empty data list was returned)
barChartView?.data = BarData(dataSet)
} else {
// If there is already data in the chart, remove the existing data set and add the new one
barChartView.data?.removeDataSet(0)
barChartView.data?.addDataSet(dataSet)
barChartView.notifyDataSetChanged()
}
// Set a custom width for the bars or the chart will draw them too wide
barChartView?.data?.barWidth = 0.3f
val xAxis = barChartView?.xAxis
val yAxis = barChartView?.axisLeft
// Set the min and max values for the Y axis or the chart lib will calculate them and add more values than
// we need
yAxis?.axisMinimum = 0f
yAxis?.axisMaximum = entries.last().y
// Set the entries that need to be drawn in the X axis, so the chart doesn't calculate them automatically
(barChartView?.rendererXAxis as CustomEntriesXAxisRenderer).entries = xAxisEntries
// Set the entries that need to be drawn in the Y axis, so the chart doesn't calculate them automatically
(barChartView?.rendererLeftYAxis as CustomEntriesYAxisRenderer).entries = yAxisEntries
// Add the label count to avoid the chart from automatically setting a range of labels instead of the ones we need,
// which prevents the axis value formatter below to set the correct labels
xAxis?.setLabelCount(xAxisEntries.size, true)
yAxis?.setLabelCount(yAxisEntries.size, true)
// Use a custom value formatter that sets only the needed labels on the axises
xAxis?.setValueFormatter { value, _ ->
// TODO
}
yAxis?.setValueFormatter { value, _ ->
// TODO
}
// Draw chart
barChartView?.invalidate()
}
这是我创建的自定义轴渲染器的实现:
class CustomEntriesXAxisRenderer(viewPortHandler: ViewPortHandler?, xAxis: XAxis?, transformer: Transformer?)
: XAxisRenderer(viewPortHandler, xAxis, transformer) {
/**
* Entries used to draw the grid lines and labels on the X axis.
*/
var entries: List<Float>? = null
override fun computeSize() {
entries?.forEachIndexed { i, value ->
mAxis.mEntries[i] = value
}
super.computeSize()
}
}
class CustomEntriesYAxisRenderer(viewPortHandler: ViewPortHandler?, yAxis: YAxis?, transformer: Transformer?)
: YAxisRenderer(viewPortHandler, yAxis, transformer) {
/**
* Entries used to draw the grid lines and labels on the Y axis.
*/
var entries: List<Float>? = null
override fun computeAxisValues(min: Float, max: Float) {
super.computeAxisValues(min, max)
entries?.forEachIndexed { i, value ->
mAxis.mEntries[i] = value
}
}
}
答案 0 :(得分:0)
其中一个MPAndroidChart开发人员说这确实是库中的一个错误,它现在已经在他们的待办事项列表中了。如果有人遇到此问题,您可以按照进度here进行操作。
与此同时,在玩了一段时间之后,我发现了一个(相当丑陋)的黑客行为,阻止了图表看起来太糟糕:
barChartView?.data?.barWidth = when (entries.last().x) {
in 0..30 -> 0.1f
in 30..60 -> 0.2f
else -> 0.3f
}
您可以将值调整为适合您的数据条目的值,但基本上通过根据数据集中X值的范围设置不同的条宽,您至少可以使其更好一点,直到修复错误为止