在xAxis MPChart上获取重复值

时间:2017-05-10 11:05:40

标签: android charts mpandroidchart

现在我正面临着这个问题。我在xAx中得到的重复值是第一个和最后一个。图形值不是根据各个x轴值的值。 第二个问题是,如果我想显示不在float中但在int Rounded中的值,并将它们的颜色更改为白色。

ArrayList<String> xlabels = new ArrayList<String>();
        xlabels.add("Jan");
        xlabels.add("Feb");
        xlabels.add("Mar");
        xlabels.add("Apr");
        xlabels.add("May");
        xlabels.add("Jun");

        ArrayList<String> values = new ArrayList<String>();
        values.add("1");
        values.add("20");
        values.add("10");
        values.add("80");
        values.add("90");
        values.add("24");

        showLineChart(clickChart,xlabels,values,mColors[3]);

showLineChart方法:

private void showLineChart(LineChart chart,final List<String> xLabels, List<String> values,int color){
        List<Entry> entries = new ArrayList<Entry>();
        for(int i=0;i<values.size();i++){
            entries.add(new Entry(i, Integer.parseInt(values.get(i))));
        }



        LineDataSet dataSet = new LineDataSet(entries, "Numbers");
        dataSet.setLineWidth(1.75f);
        dataSet.setCircleRadius(5f);
        dataSet.setCircleHoleRadius(2.5f);
        dataSet.setColor(Color.WHITE);
        dataSet.setCircleColor(Color.WHITE);
        dataSet.setHighLightColor(Color.WHITE);
        dataSet.setDrawValues(true);


        LineData data = new LineData(dataSet);
        ((LineDataSet) data.getDataSetByIndex(0)).setCircleColorHole(color);

        chart.getDescription().setEnabled(false);

        chart.setDrawGridBackground(false);

        chart.setTouchEnabled(true);

        chart.setBorderColor(Color.WHITE);

        chart.setDragEnabled(true);
        chart.setScaleEnabled(true);


        chart.setPinchZoom(false);

        chart.setBackgroundColor(color);

        YAxis yAxisLeft = chart.getAxisLeft();
        yAxisLeft.setTextColor(Color.WHITE);
        yAxisLeft.setAxisLineColor(Color.WHITE);


        YAxis yAxisRight = chart.getAxisRight();
        yAxisRight.setTextColor(Color.WHITE);
        yAxisRight.setAxisLineColor(Color.WHITE);

        XAxis xAxis = chart.getXAxis();
        xAxis.setTextColor(Color.WHITE);
        xAxis.setAxisLineColor(Color.WHITE);
        xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
        xAxis.setAvoidFirstLastClipping(false);
        xAxis.isDrawLabelsEnabled();
        xAxis.setDrawGridLines(false);
        xAxis.setValueFormatter(new IAxisValueFormatter() {

            @Override
            public String getFormattedValue(float value, AxisBase axis) {

                return xLabels.get((int)value);
            }


        });
        chart.animateX(2500);
        chart.setData(data);
        chart.invalidate();
    }

enter image description here

3 个答案:

答案 0 :(得分:13)

我遇到同样的问题要解决它添加以下行:

xAxis.setGranularityEnabled(true);

检查link以获取有关Axis的更多详细信息。

答案 1 :(得分:2)

仅设置粒度并不能解决我的问题。这是我必须要做的:

XAxis xAxis = chart.getXAxis();
xAxis.setGranularity(1f);
xAxis.setGranularityEnabled(true);
xAxis.setLabelCount(xLabels.size(),false); // yes, false. This is intentional
xAxis.setValueFormatter(new MyXAxisValueFormatter(xLabels));
xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);

而且,这是我对IAxisValueFormatter的简单实现。您可以根据需要进行更改:

public class MyXAxisValueFormatter implements IAxisValueFormatter {
        private ArrayList<String> mValues;

        MyXAxisValueFormatter(ArrayList<String> values) {
            this.mValues = values;
        }

        @Override
        public String getFormattedValue(float value, AxisBase axis) {
            int index = Math.round(value);

            if(index >= mValues.size()){
                index = mValues.size()-1;
            }
            return mValues.get(index);
        }
    }

了解每个问题为何会发生以及解决方案代码能够解决问题的原因非常重要。因此,这是分析部分:

为什么会这样?

即使您的数据位于x轴上的整数位置(0,1,2 ...),实际的标签也不一定位于这些特定位置。例如,在1.00f处数据的标签可能在0.92f处。 (这是库处理它的方式,不确定原因)。因此,当您尝试将浮点数value转换为int时,不会得到确切的位置。在前面的示例中,当转换为int时位于0.92f处的标签为0,而不是1。

此代码如何解决问题?

如果您了解以上部分,则不必这样做。无论如何,这就是理由。从测试结果中,我注意到标签位置始终位于实际x的附近。因此,Math.round()方法非常适合从浮点值中获取适当的索引。

另外,我在forced方法中将参数false设置为setLabelCount,因为我希望标签随着用户在x轴上的放大而隐藏。

答案 2 :(得分:1)

//set granularity to minimum value to ensure label does not give duplicate value
lineChart.getAxisLeft().setGranularity(1f);
lineChart.getXAxis().setGranularity(1f);
lineChart.getXAxis().setGranularityEnabled(true);
//also make sure you don't pass true as force parameter in below line please pass only false
bottomAxis.setLabelCount(dateLabels.size(),false);