MPAndroidChart HorizontalBarChart X轴自定义
由于项目要有一个品种分析功能,显示推荐品种,因此选择使用MPAndroidChart,以图表形式表现比较直观。效果如图所示。
先上代码:
AnalysisActivity.java:
package com.XXX.Activity;
import android.os.Bundle;
import com.github.mikephil.charting.charts.BarChart;
import com.github.mikephil.charting.components.Legend;
import com.github.mikephil.charting.components.XAxis;
import com.github.mikephil.charting.components.YAxis;
import com.github.mikephil.charting.data.BarData;
import com.github.mikephil.charting.data.BarDataSet;
import com.github.mikephil.charting.data.BarEntry;
import com.github.mikephil.charting.interfaces.datasets.IBarDataSet;
import com.XXX.Activity.Util.BaseActivity;
import com.XXX.MyView.Chart.MyXFormatter;
import com.XXX.R;
import java.util.ArrayList;
public class AnalysisActivity extends BaseActivity
{
protected BarChart mChart; //图
private int sCount = 12; //X轴坐标数据数量
private ArrayList<String> data; //保存X轴坐标数据
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_analysis);
mActionBar.setTitle(getString(R.string.s_analysis));
mChart = findViewById(R.id.bc_re);
mChart.setDrawBarShadow(false);
mChart.setDrawValueAboveBar(true);
//mChart.setContentDescription("××表");
mChart.getDescription().setEnabled(false);
mChart.setNoDataText(getString(R.string.s_no_data));
mChart.setPinchZoom(false); //scaling can now only be done on x- and y-axis separately
mChart.setDrawGridBackground(false);
mChart.getAxisRight().setEnabled(false); //不绘制右侧轴线
data = new ArrayList<>();
for(int i = 0; i<sCount ; i++)
{
data.add("ca"+(i+1));
}
XAxis xl = mChart.getXAxis();
xl.setValueFormatter(new MyXFormatter(data));
xl.setPosition(XAxis.XAxisPosition.BOTTOM);
//xl.setLabelRotationAngle(45); //标签倾斜
xl.setDrawAxisLine(true);
xl.setDrawGridLines(false);
xl.setCenterAxisLabels(false); //可不加这句,默认为false
//xl.setGranularity(sCount); //x轴坐标占的宽度
xl.setGranularity(1f); //x轴坐标占的宽度
//xl.setCenterAxisLabels(true);
xl.setAxisMinimum(-0.5f); // 此轴显示的最小值
//xl.setAxisMaximum(sCount*sCount); // 此轴显示的最大值
xl.setLabelCount(sCount); //显示的坐标数量
YAxis yl = mChart.getAxisLeft();
yl.setDrawAxisLine(true);
yl.setDrawGridLines(true);
yl.setAxisMinimum(0f); //this replaces setStartAtZero(true)
float[] val = {24, 35 , 73.6f, 94.2f, 23, 6, 86, 55, 44.4f, 77.77f, 0, 33};
setData(sCount, val);
mChart.setFitBars(true);
mChart.animateXY(2000, 2000);
Legend legend = mChart.getLegend();
legend.setEnabled(false); //不显示图例
}
private void setData(int count, float[] val)
{
//float barWidth = count-1; //每个彩色数据条的宽度
//float spaceForBar = count; //每个数据条实际占的宽度
float barWidth = 0.8f; //每个彩色数据条的宽度
float spaceForBar = 1f; //每个数据条实际占的宽度
ArrayList<BarEntry> yVals1 = new ArrayList<BarEntry>();
for (int i = 0; i < count; i++)
{
//float val = (float) (Math.random() * range);
yVals1.add(new BarEntry(i * spaceForBar, val[i],
getResources().getDrawable(R.drawable.ic_add_a_photo)));
}
BarDataSet set1;
if (mChart.getData() != null && mChart.getData().getDataSetCount() > 0)
{
set1 = (BarDataSet)mChart.getData().getDataSetByIndex(0);
set1.setValues(yVals1);
mChart.getData().notifyDataChanged();
mChart.notifyDataSetChanged();
}
else
{
set1 = new BarDataSet(yVals1, "XXXX");
set1.setDrawIcons(false);
ArrayList<IBarDataSet> dataSets = new ArrayList<IBarDataSet>();
dataSets.add(set1);
BarData data = new BarData(dataSets);
data.setValueTextSize(10f);
data.setBarWidth(barWidth);
mChart.setData(data);
}
}
}
MyXFormatter.java:
package com.XXX.MyView.Chart;
import com.github.mikephil.charting.components.AxisBase;
import com.github.mikephil.charting.formatter.IAxisValueFormatter;
import java.util.List;
public class MyXFormatter implements IAxisValueFormatter
{
private List<String> mValues;
public MyXFormatter(List<String> values)
{
this.mValues = values;
}
@Override
public String getFormattedValue(float value, AxisBase axis)
{
if(((int)value >=0 && (int)value < mValues.size()))
return mValues.get((int) value);
else
return "";
}
}
activity_analysis.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/colorBcakground">
<com.github.mikephil.charting.charts.HorizontalBarChart
android:id="@+id/bc_re"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
分析:
按照示例代码来写,本来以为比较简单的功能,没想到卡在X轴自定义上。总是不能在正确的地方显示坐标。主要原因在于MyXFormatter 中 getFormattedValue() 方法中的参数value,到现在也没弄明白value的分段(增长)机制,github上的Issues
https://github.com/PhilJay/MPAndroidChart/issues/2693
https://github.com/PhilJay/MPAndroidChart/issues/3894
也无人回答。
当将代码中红色行改成注释掉的值时,发现当sCount<=10,value的增长幅度为10,当sCount>10,value的增长幅度为sCount。最后采取了
的答案,行了。