关于MPAndroidChart BarChart 柱状图组遇到的一些问题记录。
关于MPAndroidChart BarChart 柱状图组遇到的一些问题记录。
先上效果图
我用的版本是3.0.2
compile 'com.github.PhilJay:MPAndroidChart:v3.0.2'
主要问题
1:数据显示不全,看其他的帖子都是正好一屏的数据量,比如我这个有八组数据,加载完只能显示六组半
2:X轴命名问题
3:X轴标签不在柱状图组的中心。
解决办法:先说第一个问题,这个默认是支持缩放的,可以把柱状图组的宽度变小 ,直到能放下为止。不过这不符合UI的逻辑,如果数据量特别多怎么办,我的解决办法是默认把柱状图的x轴放大
barChart.setScaleMinima(1.2f, 1.0f); //x轴默认放大1.2倍 要不然x轴数据展示不全
barChart.setScaleXEnabled(true); //支持x轴缩放
barChart.setScaleYEnabled(false); //禁止y轴缩放
第二个问题跟第三个一块讲,本来是打算循环给X轴赋值,能省点事就省点事。
xAxis.setValueFormatter(new IAxisValueFormatter() {
@Override
public String getFormattedValue(float v, AxisBase axisBase) {
Log.e(TAG_LOG, "barChartValue: " + v);
//会出现-1 导致循环取值时崩溃
if (v < avgAnswerCount.size()) {
return avgAnswerCount.get((int) v).getLawName();
}
}
结果,横向坐标轴的value值竟然会出现-1,要知道我已经设置了X轴从0开始,最小是是0为什么会出现-1?到现在我都没弄明白
xAxis.setAxisMinimum(0f); //最小值 从0开始
xAxis.setAxisMaximum(avgAnswerCount.size()); //最大值
xAxis.setGranularity(1f); //设置最小间隔
后来我发现如果把自动居中这个属性关掉的话,就不会出现-1这种情况了,但是如果关掉,就会影响X轴标签的居中显示
//设置柱子(组)居中对齐x轴上的点 如果改正true X轴不能正常循环赋值 value值会出现-1
xAxis.setCenterAxisLabels(true);
后来暂时先改成这样的了 因为我很确定我的数据量只有八条。
xAxis.setValueFormatter(new IAxisValueFormatter() {
@Override
public String getFormattedValue(float v, AxisBase axisBase) {
Log.e(TAG_LOG, "barChartValue: " + v);
if (v == 0) {
return avgAnswerCount.get(0).getLawName();
}
if (v == 1) {
return avgAnswerCount.get(1).getLawName();
}
if (v == 2) {
return avgAnswerCount.get(2).getLawName();
}
if (v == 3) {
return avgAnswerCount.get(3).getLawName();
}
if (v == 4) {
return avgAnswerCount.get(4).getLawName();
}
if (v == 5) {
return avgAnswerCount.get(5).getLawName();
}
if (v == 6) {
return avgAnswerCount.get(6).getLawName();
}
if (v == 7) {
return avgAnswerCount.get(7).getLawName();
}
return "";
}
});
然后再说居中显示的问题 有几个关键点需要说一下
1:打开标签居中属性
2:柱子图组的设置公式 (barSpace + barWidth) * 柱形图数量(比如我的是每组两个) + groupSpace = 1
3:X轴最大值与最小值的差值为x轴数据个数,也是y轴数据的组数
4:记得调用 barChart.groupBars(0f, groupSpace, barSpace);这个函数
xAxis.setCenterAxisLabels(true);
xAxis.setAxisMinimum(0f); //最小值 从0开始
xAxis.setAxisMaximum(avgAnswerCount.size()); //最大值
float groupSpace = 0.2f;
float barSpace = 0f;
float barWidth = 0.4f;
//设置柱子宽度
//关键的地方在于 需要满足该等式,标签才能居中:
//(barSpace + barWidth) * 柱形图数量(比如我的是每组两个) + groupSpace = 1
barData.setBarWidth(barWidth);
//三个参数分别代表 X轴起点 组与组之间的间隔 组内柱子的间隔
barChart.groupBars(0f, groupSpace, barSpace);
下面给大家附上完整代码 传的参数是我的
/**
* 设置柱状图数据
*
* @param avgAnswerCount
*/
private void initBarChart(final List<TopicAnalysisEntity.AvgAnswerCountBean> avgAnswerCount) {
if (avgAnswerCount != null && avgAnswerCount.size() > 0) {
List<BarEntry> yValues1 = new ArrayList<>();
List<BarEntry> yValues2 = new ArrayList<>();
//循环创建数据
for (int i = 0; i < avgAnswerCount.size(); i++) {
yValues1.add(new BarEntry(i, avgAnswerCount.get(i).getAvgAnswerNum()));
yValues2.add(new BarEntry(i, avgAnswerCount.get(i).getUserNum()));
}
XAxis xAxis = barChart.getXAxis();
xAxis.setGranularity(1f); //设置最小间隔
xAxis.setCenterAxisLabels(true); //设置柱子(组)居中对齐x轴上的点 如果改正true X轴不能正常循环赋值 value值会出现-1
xAxis.setAxisMinimum(0f); //最小值 从0开始
xAxis.setAxisMaximum(avgAnswerCount.size()); //最大值
xAxis.setLabelCount(avgAnswerCount.size(), false); //x轴坐标数
xAxis.setPosition(XAxis.XAxisPosition.BOTTOM); //X轴的位置设置为下 默认为上
xAxis.setDrawGridLines(false); //不要竖线网格
xAxis.setValueFormatter(new IAxisValueFormatter() {
@Override
public String getFormattedValue(float v, AxisBase axisBase) {
Log.e(TAG_LOG, "barChartValue: " + v);
// if (v < avgAnswerCount.size()) {
// return avgAnswerCount.get((int) v).getLawName();
// }
if (v == 0) {
return avgAnswerCount.get(0).getLawName();
}
if (v == 1) {
return avgAnswerCount.get(1).getLawName();
}
if (v == 2) {
return avgAnswerCount.get(2).getLawName();
}
if (v == 3) {
return avgAnswerCount.get(3).getLawName();
}
if (v == 4) {
return avgAnswerCount.get(4).getLawName();
}
if (v == 5) {
return avgAnswerCount.get(5).getLawName();
}
if (v == 6) {
return avgAnswerCount.get(6).getLawName();
}
if (v == 7) {
return avgAnswerCount.get(7).getLawName();
}
return "";
}
});
// 获取 左边 Y轴
YAxis mLAxis = barChart.getAxisLeft();
mLAxis.setDrawGridLines(false); // 取消 横向 网格线
mLAxis.setAxisMinimum(0f); //设置Y轴显示最小值,不然0下面会有空隙
// mLAxis.setEnabled(false); //左侧Y轴不显示
barChart.setScaleMinima(1.2f, 1.0f); //x轴默认放大1.2倍 要不然x轴数据展示不全
barChart.setScaleXEnabled(true); //支持x轴缩放
barChart.setScaleYEnabled(false); //禁止y轴缩放
barChart.getDescription().setEnabled(false); //右下角一串英文字母不显示
barChart.getAxisRight().setEnabled(false); //右侧Y轴不显示 默认为显示
BarDataSet barDataSet = new BarDataSet(yValues1, "平均");
barDataSet.setColor(Color.parseColor("#0188fb")); //为第一组柱子设置颜色
BarDataSet barDataSet2 = new BarDataSet(yValues2, "个人");
barDataSet2.setColor(Color.parseColor("#fe5e4e")); //为第二组柱子设置颜色
BarData barData = new BarData(barDataSet); //加上第一组
barData.addDataSet(barDataSet2); //加上第二组(多组也可以用同样的方法)
barChart.setData(barData);
float groupSpace = 0.2f;
float barSpace = 0f;
float barWidth = 0.4f;
//设置柱子宽度
//关键的地方在于 需要满足该等式,标签才能居中:(barSpace + barWidth) * 柱形图数量(比如我的是每组两个) + groupSpace = 1
barData.setBarWidth(barWidth);
//三个参数分别代表 X轴起点 组与组之间的间隔 组内柱子的间隔
barChart.groupBars(0f, groupSpace, barSpace);
}
}
xml文件很简单
<FrameLayout
android:layout_marginTop="@dimen/twenty"
android:layout_width="match_parent"
android:layout_height="300dp">
<com.github.mikephil.charting.charts.BarChart
android:id="@+id/bar_chart"
android:layout_width="match_parent"
android:layout_height="match_parent">
</com.github.mikephil.charting.charts.BarChart>
</FrameLayout>
参考文章
https://blog.csdn.net/qq_44720366/article/details/104597917
https://blog.csdn.net/zhuawalibai/article/details/78034069?utm_source=blogxgwz0