【问题标题】:How to create a BarChart with grouped bars with MPAndroidChart?如何使用 MPAndroidChart 创建带有分组条形的条形图?
【发布时间】:2016-05-16 09:11:22
【问题描述】:

我如何使用MPAndroidChartBarChart 比较两组数据。

它应该如下图所示:

我编辑了一个代码,我从 github 的一个示例项目中获得。 我怎样才能将100f and 110f 值放在一个Xaxis 标签Whole Number

        Score score1 = new Score(100f, 0, "Whole Number");
        mRealm.copyToRealm(score1);
        Score score2 = new Score(110f, 0, "Whole Number");
        mRealm.copyToRealm(score2);

【问题讨论】:

    标签: android graph mpandroidchart


    【解决方案1】:

    由于 BarData 构造函数有更新,您需要使用以下代码:

    BarChart barChart = (BarChart) view.findViewById(R.id.chart);
    barChart.setDrawBarShadow(false);
    barChart.setDrawValueAboveBar(true);
    barChart.setDescription("");
    barChart.setMaxVisibleValueCount(50);
    barChart.setPinchZoom(false);
    barChart.setDrawGridBackground(false);
    
    XAxis xl = barChart.getXAxis();
    xl.setGranularity(1f);
    xl.setCenterAxisLabels(true);
    xl.setValueFormatter(new AxisValueFormatter() {
        @Override
        public String getFormattedValue(float value, AxisBase axis) {
            return String.valueOf((int) value);
        }
    
        @Override
        public int getDecimalDigits() {
            return 0;
        }
    });
    
    YAxis leftAxis = barChart.getAxisLeft();
    leftAxis.setValueFormatter(new AxisValueFormatter() {
        @Override
        public String getFormattedValue(float value, AxisBase axis) {
            return String.valueOf((int) value);
        }
    
        @Override
        public int getDecimalDigits() {
            return 0;
        }
    });
    leftAxis.setDrawGridLines(false);
    leftAxis.setSpaceTop(30f);
    leftAxis.setAxisMinValue(0f); // this replaces setStartAtZero(true
    barChart.getAxisRight().setEnabled(false);
    
    //data
    float groupSpace = 0.04f;
    float barSpace = 0.02f; // x2 dataset
    float barWidth = 0.46f; // x2 dataset
    // (0.46 + 0.02) * 2 + 0.04 = 1.00 -> interval per "group"
    
    int startYear = 1980;
    int endYear = 1985;
    List<BarEntry> yVals1 = new ArrayList<BarEntry>(); 
    List<BarEntry> yVals2 = new ArrayList<BarEntry>();
    
    for (int i = startYear; i < endYear; i++) {
        yVals1.add(new BarEntry(i, 0.4f));
        yVals2.add(new BarEntry(i, 0.7f));
    }
    
    BarDataSet set1, set2;
    if (barChart.getData() != null && barChart.getData().getDataSetCount() > 0) {
        set1 = (BarDataSet)barChart.getData().getDataSetByIndex(0);
        set2 = (BarDataSet)barChart.getData().getDataSetByIndex(1);
        set1.setValues(yVals1);
        set2.setValues(yVals2);
        barChart.getData().notifyDataChanged();
        barChart.notifyDataSetChanged();
    } else {
        // create 2 datasets with different types
        set1 = new BarDataSet(yVals1, "Company A");
        set1.setColor(Color.rgb(104, 241, 175));
        set2 = new BarDataSet(yVals2, "Company B");
        set2.setColor(Color.rgb(164, 228, 251));
        ArrayList<IBarDataSet> dataSets = new ArrayList<IBarDataSet>();
        dataSets.add(set1);
        dataSets.add(set2);
        BarData data = new BarData(dataSets);
        barChart.setData(data);
    }
    
    barChart.getBarData().setBarWidth(barWidth);
    barChart.getXAxis().setAxisMinValue(startYear);
    barChart.groupBars(startYear, groupSpace, barSpace);
    barChart.invalidate();
    

    这就是它的样子:

    【讨论】:

    • 您好,lidox,感谢您的回答。你救了我很多天。你能帮我贴标签吗?如何将标签设置在中心,就像它出现在您的图形图像中一样。我的标签从 0 索引开始,而不是在中间。提前致谢。
    • “每组间隔”的解释让我节省了很多时间。谢谢。
    • 我的列表有 21 个,但只显示 7 个数据,您能帮帮我吗
    【解决方案2】:

    是的,这很容易做到。

    您需要的是带有多个 BarDataSetsBarChart,其中每个集合(在您的情况下)代表一种性别(男性或女性)。

    示例代码(不含 realm.io)

        List<String> xValues = ...; // "Denmark", "Finland", ...
    
        XAxis xAxis = chart.getXAxis();
        xAxis.setValueFormatter(new MyValueFormatter(xValues));
    
        // create 2 datasets 
        BarDataSet set1 = new BarDataSet(valuesMen, "Men");
        set1.setColor(Color.BLUE);
        BarDataSet set2 = new BarDataSet(valuesWomen, "Women");
        set2.setColor(Color.RED);
    
        BarData data = new BarData(set1, set2);
        chart.setData(data);
        chart.groupBars(...); // available since release v3.0.0
        chart.invalidate(); // refresh
    

    如果您需要进一步的帮助,这里有一个 detailed tutorial 分组 BarChart 可在 wiki 上找到。

    如果您想将BarChart 中的值“堆叠”在彼此之上,您需要创建一个堆叠条形图:Android Stacked Bars Chart

    【讨论】:

    • Phillipp BarData 的构造函数变了!你需要更新你的代码!
    【解决方案3】:

    我尝试的大多数答案都存在诸如未对齐、未居中的标签或条形图被隐藏在屏幕空间之外的问题。所以经过一些尝试,我有一个正常工作的 poc。

    最后 4 行是最重要的。

        ArrayList<BarEntry> barEntries = new ArrayList<>();
        ArrayList<BarEntry> barEntries1 = new ArrayList<>();
        ArrayList<BarEntry> barEntries2 = new ArrayList<>();
        ArrayList<BarEntry> barEntries3 = new ArrayList<>();
    
        barEntries.add(new BarEntry(1,989.21f));
        barEntries.add(new BarEntry(2,420.22f));
        barEntries.add(new BarEntry(3,758));
        barEntries.add(new BarEntry(4,3078.97f));
        barEntries.add(new BarEntry(5,14586.96f));
        barEntries.add(new BarEntry(6,400.4f));
        barEntries.add(new BarEntry(7,5888.58f));
    
        barEntries1.add(new BarEntry(1,950));
        barEntries1.add(new BarEntry(2,791));
        barEntries1.add(new BarEntry(3,630));
        barEntries1.add(new BarEntry(4,782));
        barEntries1.add(new BarEntry(5,2714.54f));
        barEntries1.add(new BarEntry(6,500));
        barEntries1.add(new BarEntry(7,2173.36f));
    
        barEntries2.add(new BarEntry(1,900));
        barEntries2.add(new BarEntry(2,691));
        barEntries2.add(new BarEntry(3,1030));
        barEntries2.add(new BarEntry(4,382));
        barEntries2.add(new BarEntry(5,2714f));
        barEntries2.add(new BarEntry(6,5000));
        barEntries2.add(new BarEntry(7,1173f));
    
        barEntries3.add(new BarEntry(1,200));
        barEntries3.add(new BarEntry(2,991));
        barEntries3.add(new BarEntry(3,1830));
        barEntries3.add(new BarEntry(4,3082));
        barEntries3.add(new BarEntry(5,214));
        barEntries3.add(new BarEntry(6,5600));
        barEntries3.add(new BarEntry(7,9173));
    
        BarDataSet barDataSet = new BarDataSet(barEntries,"DATA SET 1");
        barDataSet.setColor(Color.parseColor("#F44336"));
        BarDataSet barDataSet1 = new BarDataSet(barEntries1,"DATA SET 2");
        barDataSet1.setColors(Color.parseColor("#9C27B0"));
        BarDataSet barDataSet2 = new BarDataSet(barEntries2,"DATA SET 3");
        barDataSet1.setColors(Color.parseColor("#e241f4"));
        BarDataSet barDataSet3 = new BarDataSet(barEntries3,"DATA SET 4");
        barDataSet1.setColors(Color.parseColor("#42f46e"));
    
        String[] months = new String[] {"TYPE 1", "TYPE 2", "TYPE 3", "TYPE 4"};
        BarData data = new BarData(barDataSet,barDataSet1,barDataSet2,barDataSet3);
        barChart.setData(data);
    
        XAxis xAxis = barChart.getXAxis();
        xAxis.setValueFormatter(new IndexAxisValueFormatter(months));
        barChart.getAxisLeft().setAxisMinimum(0);
        xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
        xAxis.setGranularity(1);
        xAxis.setCenterAxisLabels(true);
        xAxis.setGranularityEnabled(true);
    
        float barSpace = 0.02f;
        float groupSpace = 0.3f;
        int groupCount = 4;
    
        //IMPORTANT *****
        data.setBarWidth(0.15f);
        barChart.getXAxis().setAxisMinimum(0);
        barChart.getXAxis().setAxisMaximum(0 + barChart.getBarData().getGroupWidth(groupSpace, barSpace) * groupCount);
        barChart.groupBars(0, groupSpace, barSpace); // perform the "explicit" grouping
        //***** IMPORTANT
    

    我得到的最终结果是:

    【讨论】:

    • 嗨 Sudesh,你能用整个代码更新 ans 吗?
    • stackoverflow.com/a/55386818/7735032 。我做了一个POC并提供了源代码和apk文件,你可以查看github链接
    • 请详细说明新的 IndexAxisValueFormatter(months) 是如何工作的?这对我来说没有意义。 X 值如何与“月份”(Type1、type2 等)对应?
    • 嗨 Sidesh,当用户点击类型 1 部分的任何位置时,您知道如何在标记窗口中同时显示所有 4 个类型 1 值吗?
    • @sudesh 它显示警告BarData data = new BarData(barDataSet,barDataSet1,barDataSet2,barDataSet3); class not found exception
    【解决方案4】:
    • 步骤 1 在条形图中划分第一个组数。就像下面显示 5 组的示例代码一样。每组有 5 个小节。

                 xaxis0 = new ArrayList<>();
                 for (int i = 0; i < cData.size(); i++) {
      
                     String str = cData.get(i).get("count");
                     str = str.replaceAll("\\[", "").replaceAll("\\]", "");
                     String[] finalString = str.split(",");
                     if (i == 0) {
                         for (int k = 0; k < finalString.length; k++) {
      
                             int data22 = Integer.parseInt(finalString[k]);
                             BarEntry v1e1 = new BarEntry(data22, position);
                             valueSet1.add(v1e1);
                         }
                     }
                     if (i == 1) {
                         for (int k = 0; k < finalString.length; k++) {
                             int data22 = Integer.parseInt(finalString[k] + "");
                             BarEntry v1e1 = new BarEntry(data22, position);
                             valueSet2.add(v1e1);
                         }
                     }
                     if (i == 2) {
                         for (int k = 0; k < finalString.length; k++) {
                             int data22 = Integer.parseInt(finalString[k] + "");
                             BarEntry v1e1 = new BarEntry(data22, position);
                             valueSet3.add(v1e1);
                         }
                     }
                     if (i == 3) {
                         for (int k = 0; k < finalString.length; k++) {
                             int data22 = Integer.parseInt(finalString[k] + "");
                             BarEntry v1e1 = new BarEntry(data22, position);
                             valueSet4.add(v1e1);
                         }
                     }
                     if (i == 4) {
                         for (int k = 0; k < finalString.length; k++) {
                             int data22 = Integer.parseInt(finalString[k] + "");
                             BarEntry v1e1 = new BarEntry(data22, position);
                             valueSet5.add(v1e1);
                         }
                     }
                     xaxis0.add(i, xdata.get(i).get("date"));
      
    • Step2 在上面的代码中,您观察到 5 组柱形条目在每个值集的循环中加载数据 - ArrayList valueSet2 = new ArrayList(); 在此值集和

    • 之前初始化
    • Step3 并将这 5 个集合加载到 Bardataset,如下所示

      ` BarDataSet barDataSet1 = new BarDataSet(valueSet1, "Set1"); barDataSet1.setColors(whitecolors); barDataSet1.setValueTextColor(Color.WHITE);

      BarDataSet barDataSet2 = new BarDataSet(valueSet2, "Set2"); barDataSet2.setColors(whitecolors); barDataSet2.setValueTextColor(Color.WHITE);

      BarDataSet barDataSet3 = new BarDataSet(valueSet3, "Set3"); barDataSet3.setColors(whitecolors);

      barDataSet3.setValueTextColor(Color.WHITE); BarDataSet barDataSet4 = new BarDataSet(valueSet4, "Set4");

      barDataSet4.setColors(whitecolors); barDataSet4.setValueTextColor(Color.WHITE);

      BarDataSet barDataSet5 = new BarDataSet(valueSet5, "Set5"); barDataSet5.setColors(whitecolors);

      barDataSet5.setValueTextColor(Color.WHITE); 数据集 = 新的 ArrayList(); dataSets.add(barDataSet1); 数据集.add(barDataSet2); dataSets.add(barDataSet3); dataSets.add(barDataSet4); dataSets.add(barDataSet5); `

    • 最后一步需要将此数据附加到 Bardata,如下代码所示

    BarData data11 = new BarData(xaxis0, dataSets); data11.setGroupSpace(100f);

                   holder.chart.setData(data11);
    
                   XAxis xAxis = holder.chart.getXAxis();
    
                   xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
    
                   xAxis.setDrawGridLines(true);  
    

    xAxis.setGridColor(context.getResources().getColor(R.color.white));

                   xAxis.isDrawLabelsEnabled();    
    

    xAxis.setAxisLineColor(context.getResources().getColor(R.color.accentColor)); xAxis.setTextColor(context.getResources().getColor(R.color.white));

                   xAxis.isAdjustXLabelsEnabled();
    
                   xAxis.setAdjustXLabels(true);
    
                   holder.chart.setDescription("");
    
                   holder.chart.animateXY(2000, 2000);
     holder.chart.getAxisLeft().setTextColor(context.getResources().getColor(R.color.white));
                   holder.chart.getAxisRight().setTextColor(context.getResources().getColor(R.color.white));
                   holder.chart.setDrawGridBackground(false);
                   holder.chart.getAxisRight().setEnabled(false);
                   holder.chart.setDrawValueAboveBar(true);
                   holder.chart.getAxisLeft().setEnabled(false);
                   holder.chart.setSoundEffectsEnabled(true);
                   holder.chart.getXAxis().setDrawGridLines(false);
                   holder.chart.setTransitionGroup(true);
                   YAxis yAxis = holder.chart.getAxisLeft();
                   yAxis.setDrawGridLines(false);
                   yAxis.setLabelCount(5);
                   yAxis = holder.chart.getAxisRight();
                   yAxis.setDrawGridLines(false);
                   yAxis.setTextColor(context.getResources().getColor(R.color.white));
                   Legend l =  holder.chart.getLegend();
                   l.setEnabled(false);     
                   Paint p = holder.chart.getPaint(Chart.PAINT_INFO);
                   p.setTextSize(10);
                   p.setColor(context.getResources().getColor(R.color.white));
                   p.setTypeface(gotham);
                   holder.chart.invalidate();
                   l.setPosition(Legend.LegendPosition.BELOW_CHART_CENTER);
                   l.setTextSize(200);
                   yAxis.setValueFormatter(new LargeValueFormatter());
    
       # Thats it if you have doubt about this code ask me any time .......
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-08-08
      • 1970-01-01
      • 2018-05-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多