MPAndroidChart加载数据后柱宽缩小及图例失效问题求助
解决MPAndroidChart的柱宽缩小和图例不显示问题
先看你代码里的两个核心问题,我一步步帮你修正:
一、柱宽随数据量增大缩小的问题
你的代码里存在一个逻辑错误:在for (int i = 0; i < jsonarray.length(); i++)循环中,每次遍历一个jsonobject就往yEntrys里添加7个BarEntry,这会导致柱子数量随着jsonarray的长度成倍增加(比如jsonarray有10个元素,就会生成70个柱子),图表为了容纳所有柱子,自然会缩小每个柱子的宽度。
修正方案:
你应该是想统计所有数据中7个类别(messageSent、failed等)的总和,然后每个类别对应一个柱子对吧?那需要先初始化7个累加变量,循环中累加每个类别的数值,最后再生成7个BarEntry:
// 初始化累加变量 float totalMessageSent = 0f; float totalFailed = 0f; float totalRejected = 0f; float totalExpired = 0f; float totalUnDelivered = 0f; float totalDelivered = 0f; float totalNdnc = 0f; try { JSONArray jsonarray = (JSONArray) response.get("piechartlist"); for (int i = 0; i < jsonarray.length(); i++) { JSONObject jsonobject = jsonarray.getJSONObject(i); // 累加每个类别的数值 totalMessageSent += Float.parseFloat(jsonobject.getString("messageSent").trim()); totalFailed += Float.parseFloat(jsonobject.getString("failed").trim()); totalRejected += Float.parseFloat(jsonobject.getString("rejected").trim()); totalExpired += Float.parseFloat(jsonobject.getString("expired").trim()); totalUnDelivered += Float.parseFloat(jsonobject.getString("unDelivered")); totalDelivered += Float.parseFloat(jsonobject.getString("delivered")); totalNdnc += Float.parseFloat(jsonobject.getString("ndnc")); } // 循环结束后,生成7个BarEntry(每个类别一个柱子) yEntrys.add(new BarEntry(0, totalMessageSent)); // 第一个参数是X轴位置,从0开始 yEntrys.add(new BarEntry(1, totalFailed)); yEntrys.add(new BarEntry(2, totalRejected)); yEntrys.add(new BarEntry(3, totalExpired)); yEntrys.add(new BarEntry(4, totalUnDelivered)); yEntrys.add(new BarEntry(5, totalDelivered)); yEntrys.add(new BarEntry(6, totalNdnc)); } catch (JSONException e) { e.printStackTrace(); }
另外,柱宽的调整可以结合以下设置,确保柱子宽度稳定:
- 把
data.setBarWidth(0.9f);改成更合适的数值,比如0.6f,避免柱子太挤 - 确保
mBarChart.setFitBars(true);在mBarChart.setData(data);之后调用,这样图表会自动调整边距适配柱子:
mBarChart.setData(data); mBarChart.setFitBars(true); // 移到setData之后 mBarChart.invalidate();
二、图例无法正常显示的问题
你的自定义图例设置逻辑没问题,但可能是时机和属性设置不全导致的。可以调整以下几点:
- 设置图例的方向和对齐方式:默认的图例可能位置不对,加上这些属性让图例显示更合理:
Legend l = mBarChart.getLegend(); l.setEnabled(true); l.setOrientation(Legend.LegendOrientation.HORIZONTAL); // 水平排列 l.setHorizontalAlignment(Legend.LegendHorizontalAlignment.CENTER); // 居中 l.setVerticalAlignment(Legend.LegendVerticalAlignment.BOTTOM); // 放在底部 l.setWordWrapEnabled(true); l.setCustom(new LegendEntry[]{l1,l2,l3,l4,l5,l6,l7});
确保在设置数据之后更新图例:把图例的设置放在
mBarChart.setData(data);之后,再调用mBarChart.invalidate();刷新图表。统一LegendEntry的参数:你部分LegendEntry的线宽设置不一致(比如l3的线宽是1f,其他是2f),可以统一成相同数值,避免显示异常:
LegendEntry l1 = new LegendEntry("messageSent", Legend.LegendForm.DEFAULT, 10f, 2f, null, ContextCompat.getColor(getContext(), R.color.massage_Sent)); LegendEntry l2 = new LegendEntry("Failed", Legend.LegendForm.DEFAULT, 10f, 2f, null, ContextCompat.getColor(getContext(), R.color.failed)); LegendEntry l3 = new LegendEntry("Rejected", Legend.LegendForm.DEFAULT, 10f, 2f, null, ContextCompat.getColor(getContext(), R.color.rejected)); // 其他LegendEntry也统一线宽为2f
完整修正后的核心代码片段
RequestQueue requestQueue = Volley.newRequestQueue(getContext()); JsonObjectRequest jsOnbjRequest = new JsonObjectRequest(Request.Method.POST, Constants.GETPICCHART, pieObject, new Response.Listener<JSONObject>() { @Override public void onResponse(JSONObject response) { final ArrayList<BarEntry> yEntrys = new ArrayList<>(); Log.d("pieData",response.toString()); // 初始化累加变量 float totalMessageSent = 0f; float totalFailed = 0f; float totalRejected = 0f; float totalExpired = 0f; float totalUnDelivered = 0f; float totalDelivered = 0f; float totalNdnc = 0f; try { JSONArray jsonarray = (JSONArray) response.get("piechartlist"); for (int i = 0; i < jsonarray.length(); i++) { JSONObject jsonobject = jsonarray.getJSONObject(i); // 累加每个类别的数值 totalMessageSent += Float.parseFloat(jsonobject.getString("messageSent").trim()); totalFailed += Float.parseFloat(jsonobject.getString("failed").trim()); totalRejected += Float.parseFloat(jsonobject.getString("rejected").trim()); totalExpired += Float.parseFloat(jsonobject.getString("expired").trim()); totalUnDelivered += Float.parseFloat(jsonobject.getString("unDelivered")); totalDelivered += Float.parseFloat(jsonobject.getString("delivered")); totalNdnc += Float.parseFloat(jsonobject.getString("ndnc")); } // 生成每个类别对应的BarEntry yEntrys.add(new BarEntry(0, totalMessageSent)); yEntrys.add(new BarEntry(1, totalFailed)); yEntrys.add(new BarEntry(2, totalRejected)); yEntrys.add(new BarEntry(3, totalExpired)); yEntrys.add(new BarEntry(4, totalUnDelivered)); yEntrys.add(new BarEntry(5, totalDelivered)); yEntrys.add(new BarEntry(6, totalNdnc)); } catch (JSONException e) { e.printStackTrace(); } BarDataSet set1; set1 = new BarDataSet(yEntrys,""); set1.setBarBorderWidth(1f); set1.setDrawIcons(false); ArrayList<IBarDataSet> dataSets = new ArrayList<IBarDataSet>(); dataSets.add(set1); ArrayList<Integer> colors = new ArrayList<Integer>(); colors.add(ContextCompat.getColor(getContext(),R.color.massage_Sent)); colors.add(ContextCompat.getColor(getContext(),R.color.failed)); colors.add(ContextCompat.getColor(getContext(),R.color.rejected)); colors.add(ContextCompat.getColor(getContext(),R.color.expiered)); colors.add(ContextCompat.getColor(getContext(),R.color.undelivred)); colors.add(ContextCompat.getColor(getContext(),R.color.delivered)); colors.add(ContextCompat.getColor(getContext(),R.color.ndnc)); set1.setColors(colors); BarData data = new BarData(dataSets); data.setBarWidth(0.6f); // 调整合适的柱宽 data.setValueFormatter(new MyValueFormatter()); XAxis xAxis = mBarChart.getXAxis(); xAxis.setPosition(XAxis.XAxisPosition.BOTTOM); xAxis.setLabelRotationAngle(30); xAxis.setSpaceMax(5f); xAxis.setGranularity(1f); xAxis.setDrawGridLines(false); xAxis.setGranularityEnabled(true); // 设置X轴标签 xAxis.setValueFormatter(new ValueFormatter() { @Override public String getFormattedValue(float value) { switch ((int)value) { case 0: return "messageSent"; case 1: return "Failed"; case 2: return "Rejected"; case 3: return "Expired"; case 4: return "Undelivred"; case 5: return "Delivered"; case 6: return "NNDNC"; default: return ""; } } }); // 设置自定义图例 Legend l = mBarChart.getLegend(); LegendEntry l1 = new LegendEntry("messageSent", Legend.LegendForm.DEFAULT, 10f, 2f, null, ContextCompat.getColor(getContext(),R.color.massage_Sent)); LegendEntry l2 = new LegendEntry("Failed", Legend.LegendForm.DEFAULT, 10f, 2f, null, ContextCompat.getColor(getContext(),R.color.failed)); LegendEntry l3 = new LegendEntry("Rejected", Legend.LegendForm.DEFAULT, 10f, 2f, null, ContextCompat.getColor(getContext(),R.color.rejected)); LegendEntry l4 = new LegendEntry("Expired", Legend.LegendForm.DEFAULT, 10f, 2f, null, ContextCompat.getColor(getContext(),R.color.expiered)); LegendEntry l5 = new LegendEntry("Undelivred", Legend.LegendForm.DEFAULT, 10f, 2f, null, ContextCompat.getColor(getContext(),R.color.undelivred)); LegendEntry l6 = new LegendEntry("Delivered", Legend.LegendForm.DEFAULT, 10f, 2f, null, ContextCompat.getColor(getContext(),R.color.delivered)); LegendEntry l7 = new LegendEntry("NNDNC", Legend.LegendForm.DEFAULT, 10f, 2f, null, ContextCompat.getColor(getContext(),R.color.ndnc)); l.setOrientation(Legend.LegendOrientation.HORIZONTAL); l.setHorizontalAlignment(Legend.LegendHorizontalAlignment.CENTER); l.setVerticalAlignment(Legend.LegendVerticalAlignment.BOTTOM); l.setWordWrapEnabled(true); l.setCustom(new LegendEntry[]{l1,l2,l3,l4,l5,l6,l7}); l.setEnabled(true); // 设置数据并刷新图表 mBarChart.setData(data); mBarChart.setFitBars(true); mBarChart.invalidate(); } }); requestQueue.add(jsOnbjRequest);
另外,我还给你加上了X轴的标签格式化,这样X轴会显示对应的类别名称,更直观。
内容的提问来源于stack exchange,提问作者ashish
相关产品推荐
相关产品推荐

