You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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();

二、图例无法正常显示的问题

你的自定义图例设置逻辑没问题,但可能是时机和属性设置不全导致的。可以调整以下几点:

  1. 设置图例的方向和对齐方式:默认的图例可能位置不对,加上这些属性让图例显示更合理:
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});
  1. 确保在设置数据之后更新图例:把图例的设置放在mBarChart.setData(data);之后,再调用mBarChart.invalidate();刷新图表。

  2. 统一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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:30:51