Заставить метки оси 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)+"";
}
});
Как мы можем видеть из этих изображений, мои целочисленные значения не там, где они должны быть (и есть два "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);
довольно простой. Все, что вам нужно, это две вещи:
-
форматер значений оси
mChart.getAxisLeft().setValueFormatter(new ValueFormatter() { @Override public String getFormattedValue(float value) { return String.valueOf((int) Math.floor(value)); } });
-
метки оси графа
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));
}
});
Удачи В Кодировании..