Заставить метки оси Y BarChart быть целыми числами?

Я создал BarChart с помощью MPAndroidChart, и я ввожу данные динамически. Это означает, что мне нужно, чтобы моя ось Y также определялась динамически. Все мои данные представлены в виде целых чисел, однако ось Y иногда отображает легенду в виде десятичных значений с 1 десятичной запятой.

Я попытался использовать ValueFormatter для округления значений, но проблема в том, что иногда значения Y не находятся в целочисленных местоположениях (например . 0.8,1.6,2.4 и т. д.). Поэтому, если я просто отредактируйте их как целые числа, они не будут в правильном месте.

есть ли в любом случае, что я могу заставить BarChart отображать только значения в целочисленных местоположениях? Его хорошо, если он пропускает некоторые, на самом деле я хочу, чтобы он, когда значения становятся большими.

Edit: когда я сказал, что целые числа не находятся в правильных местах, я имел в виду, что как только я изменяю то, что отображает каждая метка, они не "правильные". В моем примере у меня есть 5 баров, отображающих значения 3,4,2,3,2. Первый образ - "по умолчанию", второй-это изображение, как только я отредактировал форматер значений, используя:

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

enter image description hereenter image description here

Как мы можем видеть из этих изображений, мои целочисленные значения не там, где они должны быть (и есть два "2s"). В этом примере я бы, кроме него, отображал значения 0,1,2,3,4. Если у меня есть намного больше данных, я надеюсь, что это будет достаточно умно, чтобы показать только те значения, для которых у меня есть место, поэтому для примеров, если данные содержат значения 0-50, это покажет что-то вроде 0,10,20,30,40,50 или, возможно, 0,15,30,45 и т. д.

6 ответов


ладно, теперь я вижу вашу проблему. Проблема в том, что YAxis (YLabels) определяет количество цифр и, следовательно, шаги между каждой меткой автоматически.

к сожалению, это В настоящее время не представляется возможным настройка способа вычисления оси или установки пользовательских меток.

Я рассматриваю возможность добавить такую функцию в будущем, где пользователь может самостоятельно определить, какие значения рисуются как ось ценник.

просто намек:

на mEntries массив, содержащий все метки оси, является общедоступным. Таким образом, в целом, вы можете изменить его после его создания. Однако я абсолютно не уверен, как поведет себя ось, если вы вручную измените ее.

но, возможно, стоит попробовать :-) https://github.com/PhilJay/MPAndroidChart/blob/master/MPChartLib/src/com/github/mikephil/charting/components/YAxis.java


вот как я решил эту проблему. Похоже, что ось 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);

довольно простой. Все, что вам нужно, это две вещи:

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

осмотревшись без доступного решения, я решил заглянуть в 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);
    }
}

и это все!


Я знаю, что отвечаю очень поздно, но я пытаюсь пролить свет на эту проблему, чтобы будущие пользователи имели немного больше знаний об этом.

я также столкнулся с той же проблемой. Я использовал 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 в целочисленном формате, но также дублирует некоторые значения. Это из-за преобразования значение float в целое число.

допустим, например, 0.4 будет преобразован в 0, поэтому будет два или может быть больше 0 значений по оси Y.

Я думаю, это то, что происходит в случае @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 или два. Вы можете настроить это поведение в соответствии с вашими требованиями а также увеличьте интервал метки, изменив цикл do-while.

также убедитесь, что вы используете setLabelCount(int count, boolean force) способ и передает force значение true.


Я тоже столкнулся с той же проблемой.. Просто используйте ниже код, чтобы избавиться от него!!!

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

Удачи В Кодировании..