强制BarChart Y轴标签是整数?

时间:2015-02-26 21:57:01

标签: android bar-chart mpandroidchart

我使用MPAndroidChart创建了一个BarChart,并且我动态输入了数据。这意味着我还需要动态确定Y轴。我的所有数据都表示为整数,但Y轴有时会将图例显示为带小数点1的十进制值。

我尝试使用ValueFormatter来舍入值,但问题是有时Y值不在整数值位置(例如0.8,1.6,2.4等)。因此,如果我只是将它们编辑成整数,那么它们就不会在正确的位置。

无论如何,我是否可以强制BarChart仅在Integer位置显示值?如果它跳过一些就可以了,实际上我想在值变大时使用它。

编辑:当我说整数不在正确的位置时,我的意思是,一旦我修改了每个标签显示的内容,他们就不会纠正这些错误。在我的例子中,我有5个条显示值3,4,2,3,2。第一张图片是'默认',第二张图片是我使用以下内容编辑了值格式化程序后的图像:

myBarChart.getYLabels().setFormatter(new ValueFormatter()
{
    @Override
    public String getFormattedValue(float v)
    {
        return ((int) v)+"";
    }
});

enter image description here enter image description here

正如我们从这些图像中看到的那样,我的整数值不是它们应该存在的位置(并且有两个' 2s')。在这个例子中我除了显示值0,1,2,3,4之外。如果我有更多的数据,我希望它足够智能,只显示我有空间的值,所以例如,如果数据包含0-50的值,它将显示类似0,10,20 ,30,40,50或可能是0,15,30,45等。

9 个答案:

答案 0 :(得分:11)

好吧,好吧,现在我看到了你的问题。 问题是YAxis(YLabels)确定了位数,从而确定了每个标签之间的步骤自动

不幸的是,目前无法来自定义轴的计算方式或设置自定义标签。

我正在考虑将来添加这样一个功能,用户可以自定义哪些值作为轴标签绘制。

只是提示:

包含所有轴标签的mEntries数组是公共的。因此,一般情况下,您可以在创建后对其进行修改。 但是,如果您手动修改轴,我绝对不确定轴的行为。

但也许值得一试:-) https://github.com/PhilJay/MPAndroidChart/blob/master/MPChartLib/src/com/github/mikephil/charting/components/YAxis.java

答案 1 :(得分:6)

非常简单。所有你需要的是两件事:

  1. 轴值格式化程序

    mChart.getAxisLeft().setValueFormatter(new ValueFormatter() {
        @Override
        public String getFormattedValue(float value) {
            return String.valueOf((int) Math.floor(value));
        }
    });
    
  2. 轴标签计数

    int max = findMaxYValue(yourdata); // figure out the max value in your dataset
    mChart.getAxisLeft().setLabelCount(max);
    

答案 2 :(得分:6)

这就是我解决这个问题的方法。似乎y轴总是在最大值上绘制1(如果它不强制它)。因此,将标签计数2设置为最大值(包括零和一个超过最大值),然后您需要做的就是使用轴格式化程序删除小数。如果所有y值都是整数,则无法确定它如何与十进制值一起使用。

    barChart.getAxisLeft().setLabelCount(maxYvalue + 2, true);
    barChart.getAxisLeft().setAxisMinValue(0f);
    barChart.getAxisLeft().setAxisMaxValue(maxYvalue + 1);
    YAxisValueFormatter customYaxisFormatter = new YAxisValueFormatter() {
        @Override
        public String getFormattedValue(float value, YAxis yAxis) {
            return String.valueOf((int)value);
        }
    };
    barChart.getAxisLeft().setValueFormatter(customYaxisFormatter);

答案 3 :(得分:3)

我知道我的回答很晚,但我正在尝试更多地了解这个问题,以便未来的用户对此有更多的了解。

我也面临同样的问题。我使用MyYAxisValueFormatter仅显示Y-Axis中的整数值。下面是相同的代码。

public class MyYAxisValueFormatter implements YAxisValueFormatter {

    private DecimalFormat mFormat;

    public MyYAxisValueFormatter () {
        mFormat = new DecimalFormat("###,###,##0");
    }

    @Override
    public String getFormattedValue(float value, YAxis yAxis) {
        // write your logic here
        // access the YAxis object to get more information
        return mFormat.format(value);
    }
}

通过使用这个类,发生的事情肯定是以整数格式显示Y轴值,但也复制了一些值。那是因为浮点值转换为整数。

  

假设例如0.4将被转换为0所以将有两个或   在Y轴中可能有0个值。

我认为这是@Fozefy发生的事情。

我实现了下面给出的代码来解决这个问题,它的工作就像一个魅力。我使用setAxisMaxValue函数为Y轴设置自定义最大值,使用setLabelCount设置Y轴的标签条目数。

    YAxis yAxis = chart.getAxis(YAxis.AxisDependency.LEFT);

    // Minimum section is 1.0f, could be 0.25f for float values
    float labelInterval = 1.0f / 2f;

    int sections; //No of sections in Y-Axis, Means your Highest Y-value.
    do {
        labelInterval *= 2; //Interval between labels in Y-Axis
        sections = ((int) Math.ceil(chart.getYMax() / labelInterval));
    } while (sections > 10);

    // If the ymax lies on one of the top interval, add another one for some spacing
    if (chart.getYMax() == sections * labelInterval) {
        sections++;
    }

    yAxis.setAxisMaximum(labelInterval * sections);
    yAxis.setLabelCount(sections + 1, true);
  

如果您的最大y值小于10,则标签间隔保持为1   否则两个。您可以根据需要自定义此行为   并通过修改do-while循环来增加标签间隔。

另请确保您使用setLabelCount(int count, boolean force)方法并将force值传递给true

答案 4 :(得分:3)

在没有可用解决方案的情况下环顾四周后,我决定查看javadoc并找到有关此方法的信息:setGranularity(float)。要强制YAxis始终显示整数(或任何你想要的间隔),你只需要调用它:

yAxisLeft.setGranularity(1.0f);
yAxisLeft.setGranularityEnabled(true); // Required to enable granularity

但是,如果图表的最小值和最大值太接近,那么图表将不会尊重setLabelCount(),除非强制使用(这将使标签再次成为十进制),因此您需要调用在设置数据之后:

private void calculateMinMax(BarLineChartBase chart, int labelCount) {
    float maxValue = chart.getData().getYMax();
    float minValue = chart.getData().getYMin();

    if ((maxValue - minValue) < labelCount) {
        float diff = labelCount - (maxValue - minValue);
        maxValue = maxValue + diff;
        chart.getAxisLeft().setAxisMaximum(maxValue);
        chart.getAxisLeft().setAxisMinimum(minValue);
    }
}

那就是它!

答案 5 :(得分:0)

我的解决方案:

mChart.getAxisLeft().setValueFormatter(new ValueFormatter() {
    @Override
    public String getFormattedValue(float value) {
        return String.valueOf((int) Math.floor(value));
    }
});

int max = (int) mChart.getData().getYMax(); 
mChart.getAxisLeft().setLabelCount(max);

答案 6 :(得分:0)

这是简单的解决方案,它将使正在寻找答案的人受益。

  1. Y轴标签数

    barChart.getAxisLeft().setLabelCount(7, true); //if you want 6 labels then value should be 7

  2. 计算maxValue

    • 从值中获取maxValue需要包含在图表中
    int maxValueMod = (maxValue + 2) % 6; //calc mod, here 2 is to display Legend and 6 is no of labels
    maxValue = maxValue + (6-maxValueMod); // calculate final maxValue to set in barchart
    barChart.getAxisLeft().setAxisMaximum(maxValue+2); ```
    

答案 7 :(得分:0)

要添加到解决方案中,如果有人只想删除小数和重复值,则可以执行以下操作:

IAxisValueFormatter yAxisValueFormatter = new IAxisValueFormatter() {
      @Override
      public String getFormattedValue(float v, AxisBase axisBase) {
//check for decimal value
        if (v - (int) v != 0) {
          return "";
        } else {
          return String.valueOf((int) v);
        }
      }
    }; 
    leftAxis.setValueFormatter(yAxisValueFormatter);
    rightAxis.setValueFormatter(yAxisValueFormatter);

答案 8 :(得分:0)

我遇到了同样的问题,我正在获取:

Chart without the fix

要仅显示“整数”(在本例中为“10”),请尝试以下操作:

chart.axisLeft.valueFormatter = object : ValueFormatter() {
    override fun getFormattedValue(value: Float): String {
        return if (value == value.toInt().toFloat()) {
            (floor(value.toDouble()).toInt()).toString()
        } else {
            ""
        }
    }
}

结果:

Chart with the fix