Android图表库(MPAndroidChart3.0.3)动态更新全解之一:多柱状动态更新(BarChart)

    xiaoxiao2025-06-12  21

    一:效果图

    先看图解:

    看图说话,多柱状图就是有多个DataSet,上面这个公式很重要,否则画出来的图简直是天马行空

    完整代码

    注释很详细,几乎每行代码都有注释

    public class BarChartFragmnet extends BaseChart<BarChart> { //DataSet 对应的Label String[] arr = new String[]{ "Java", "JavaWeb", "python", "php", "C++", }; //YAxis标签集 String[] leftXValue = new String[]{ "", "simple", "general", "difficult", "hell", "Purgatory" }; //XAxis数据 LinkedList<String> xValueList = new LinkedList<>(); @Override protected BarChart createChart() { return new BarChart(getContext()); } @Override protected void initData() { //DataSet集合,这里多柱状图绘制,所有用这个集合保存DataSet List<IBarDataSet> dataSets = new ArrayList<>(); for (int pos = 0; pos < 5; pos++) { BarDataSet barDataSet = new BarDataSet(new ArrayList<BarEntry>(), arr[pos]); //给柱子上色,ColorTemplate类是作者提供的颜色类,里面有一些长度为5的颜色数组,刚好我这是5个DataSet,一个DataSet对应一种颜色 barDataSet.setColor(ColorTemplate.JOYFUL_COLORS[pos]); dataSets.add(barDataSet); } BarData barData = new BarData(dataSets); //设置单挑柱状的在这个Group中的占比,也就是图解中的BarWidth barData.setBarWidth(0.1f); //获得左侧Y轴对象 YAxis axisLeft = mChart.getAxisLeft(); //设置y轴数据起始值为0 axisLeft.setAxisMinimum(0f); //设置y轴标签的个数 axisLeft.setLabelCount(6); //设置y轴粒度为1f,必须设置,意思就是y轴的Value一直累加1,由于在3.0.3版本中y轴Value值不是再是1,2,3,4这种一直累加,而是由框架自适应计算值 //便于后期自定义Y轴刻度数据 axisLeft.setGranularity(1f); //设置y轴最大刻度值 axisLeft.setAxisMaximum(6f); /** * 格式化y轴数据,这里有个坑,不能直接new IAxisValueFormatter(), * new IAxisValueFormatter() { * @Override * public String getFormattedValue(float value, AxisBase axis) { * return null; * } * } * * getFormattedValue中有两参数,我们主要看Value,一开始我天真的以为这个Value就是0,1,2,3,4这样的Y轴刻度值,一顿操作,把这个Value当下标设置自定义Y轴数据 * 把程序跑起来,直接抛java.lang.ArrayIndexOutOfBoundsException ε=ε=ε=(~ ̄▽ ̄)~ * 打印出来发现这个值还能出现负数 * 后来在stackoverflow上找到下面这种方法,IndexAxisValueFormatter也是实现了IAxisValueFormatter,不过它对Value做了一些处理,、 * 配合setGranularity()一起使用即可实现在2.0的效果 * */ axisLeft.setValueFormatter(new IndexAxisValueFormatter(leftXValue)); //设置是否绘制Y轴网格线, axisLeft.setDrawGridLines(false); //设置是否绘制左侧y轴的线 //axisLeft.setDrawAxisLine(false); //设置隐藏右侧轴线 mChart.getAxisRight().setEnabled(false); //获得X轴线对象 XAxis xAxis = mChart.getXAxis(); //设置X轴轴线位于下方 xAxis.setPosition(XAxis.XAxisPosition.BOTTOM); //设置x轴刻度起始值为0f xAxis.setAxisMinimum(0f); //设置X轴粒度,和y轴同理 xAxis.setGranularity(1f); //设置x轴刻度位于Group的中间 xAxis.setCenterAxisLabels(true); //设置X轴数据倾斜度,负数为逆时针,正数为顺时针 //xAxis.setLabelRotationAngle(-60); //获得图例说明对象 Legend legend = mChart.getLegend(); //设置图例说明位于柱状图下面的中间 legend.setPosition(Legend.LegendPosition.BELOW_CHART_CENTER); //绑定数据 mChart.setData(barData); //模拟数据更新,没3.4秒调用updateChart(int[] arr)方法 timer.schedule(new TimerTask() { @Override public void run() { //切换主线程便于更新图表 getActivity().runOnUiThread(() -> updateChart(new int[]{ (random.nextInt(5) + 1), (random.nextInt(5) + 1), (random.nextInt(5) + 1), (random.nextInt(5) + 1), (random.nextInt(5) + 1)})); } }, 0, 3400); } public void updateChart(int[] arr) { //循环给5个DataSet添加数据 for (int pos = 0, size = mChart.getBarData().getDataSetCount(); pos < size; pos++) { //这里当EntryCount小于7时直接添加数据 if (mChart.getBarData().getDataSetByIndex(pos).getEntryCount() < 7) { xValueList.add(mDateFormat.format(System.currentTimeMillis())); mChart.getBarData().getDataSetByIndex(pos).addEntry(new BarEntry(mChart.getBarData().getDataSetByIndex(pos).getEntryCount(), arr[pos])); } //当EntryCount>=7是做删除和更新操作 else { //删除x轴刻度数据第一个 xValueList.removeFirst(); //删除第一个Entry mChart.getBarData().getDataSetByIndex(pos).removeEntry(0); //删除后再做添加操作 xValueList.add(mDateFormat.format(System.currentTimeMillis())); mChart.getBarData().getDataSetByIndex(pos).addEntry(new BarEntry(mChart.getBarData().getDataSetByIndex(pos).getEntryCount(), arr[pos])); /** * 精髓所在 * 遍历DataSet中所有Entry,将所有的Entry的x轴数据-1,实现更新图表的效果 */ for (int index = 0, entrySize = mChart.getBarData().getDataSetByIndex(pos).getEntryCount(); index < entrySize; index++) { float newX = mChart.getBarData().getDataSetByIndex(pos).getEntryForIndex(index).getX() - 1; mChart.getBarData().getDataSetByIndex(pos).getEntryForIndex(index).setX(newX); } } } //动态更新x轴刻度自定义的数据 mChart.getXAxis().setValueFormatter(new IndexAxisValueFormatter(xValueList)); //以下两属性必须设置,而且必须每次更新都设置一遍 //设置图例上显示多少个柱子,这里是多柱状图,所以这里设置显示多少个组 mChart.setVisibleXRangeMinimum(7f); mChart.setVisibleXRangeMaximum(7f); //设置柱距和组距的占比,怎么算往上翻看图二图解 //更新一次设置一次 mChart.groupBars(0f, 0.2f, 0.06f); //通知BarData更新 mChart.getBarData().notifyDataChanged(); //通知BarChart更新 mChart.notifyDataSetChanged(); //使图表更新生效 mChart.invalidate(); } }

    有什么疑问可以直接在底下私信我

    最新回复(0)