Show only some values in MPAndroidChart - java

I have an array of y values that I am displaying over the dates of a month. To simplify, for the first week of April, I would have the values {0,200,0,0,500,0,100} over the x values {1,2,3,4,5,6,7}. I am able to display them as a bar chart using MPAndroidChart. I am also able to hide and display the values over each bar using
barChart.getData().setDrawValues(true); //or false when I want to hide
However, I want to display only the number that are non-zero, how would I be able to do so? Any pointers would be appreciated!
I tried creating my formatter the following way:
public class MyYAxisValueFormatter implements IAxisValueFormatter {
private DecimalFormat mFormat;
public MyYAxisValueFormatter() {
// format values to 1 decimal digit
mFormat = new DecimalFormat("###,###,##0.0");
}
#Override
public String getFormattedValue(float value, AxisBase axis) {
String val = "";
if(value != 0)
val = String.valueOf(value);
return mFormat.format(value) + " $";
}
}
and called it using this in my main function:
YAxis yAxis = barChart.getAxisLeft();
yAxis.setValueFormatter(new MyYAxisValueFormatter());
However the values of zero are still displayed.

Try making your own IValueFormatter Interface
public class MyYAxisValueFormatter implements IValueFormatter {
private DecimalFormat mFormat;
public MyYAxisValueFormatter() {
// format values to 1 decimal digit
mFormat = new DecimalFormat("###,###,##0.0");
}
#Override
public String getFormattedValue(float value, Entry entry, int dataSetIndex, ViewPortHandler viewPortHandler) {
// "value" represents the position of the label on the axis (x or y)
if(value > 0) {
return mFormat.format(value);
} else {
return "";
}
}
}
try setting value formatter to your barchart.
bar.setValueFormatter(new MyYAxisValueFormatter ());

try this:
private class MyValueFormatter implements ValueFormatter {
#Override
public String getFormattedValue(float value, Entry entry, int dataSetIndex, ViewPortHandler viewPortHandler) {
// write your logic here
if(value > 0)
return value+"";
else
return "";
}
}
OR
try this likn it helps you
https://github.com/PhilJay/MPAndroidChart/issues/2402

Related

How to remove decimal value from BarChart MPAndroid Chart? I tried several methods but didn't work

enter image description hereI tried all methods but I could not remove the decimal from bar label. How can I remove decimal part from the bar label
barData.setValueFormatter(new ValueFormatter() {
#Override
public String getFormattedValue(float value) {
if (value > 0){
return super.getFormattedValue((int)value);
}else{
return "";
}
}
});
This might be the answer:
#Override
public String getFormattedValue(float value, AxisBase axis) {
val df = DecimalFormat("#");
df.roundingMode = RoundingMode.CEILING;
return df.format(value);
}
Combining your code, it should look like this:
#Override
public String getFormattedValue(float value, AxisBase axis) {
if (value > 0) {
val df = DecimalFormat("#");
df.roundingMode = RoundingMode.CEILING;
return df.format(value);
} else {
return "";
}
}
I don't code in Java, so please, check for any syntax misspellings. :)
I reproduced it on my Line chart using Kotlin.
Read more about ValueFormatter in the docs of MPAndroidChart, please: https://weeklycoding.com/mpandroidchart-documentation/formatting-data-values/

Getting NullPointerException when dealing with passing String variables [duplicate]

This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 2 years ago.
I'm trying to code a project that deals with a dumb downed version of an excel sheet. One of the commands I am allowing from the user is assigning a value into specific cells in the format of = . i.e A3 = 72.3%. Once it assigns the value to the cell, it then prints out the entire spreadsheet with the updated changes.
I created different classes to represent different types of cells.
Value Cell is a cell that will contain any double value, Percent Cell is a cell that will contain any percentage value, Text Cell is a cell that will contain text.
While I was trying to run my program, I tried assigning a percentage value to a cell. (A2 = 7.25%)
When the program prints out the entire spreadsheet with the newly assigned A2 percentage cell, it's supposed to truncate the decimal from the percentage and just display 7%.
However, I keep getting this error message
Exception in thread "main" java.lang.NullPointerException
at PercentCell.abbreviatedCellText(PercentCell.java:18)
at Spreadsheet.getGridText(Spreadsheet.java:127)
at Spreadsheet.processCommand(Spreadsheet.java:73)
at TextExcel.main(TextExcel.java:20)
This is part of my code that assigns specific cell types depending on what the user inputs:
//assignment command
} else if (command.contains("=")) {
int eqIndex = command.indexOf("=");
if (!command.substring(eqIndex - 1, eqIndex).equals(" ") || !command.substring(eqIndex + 1, eqIndex + 2).equals(" ")) {
return "Formatting Error: please include a space before and after the ="; //error message
} else {
String[] input = command.split(" ", 3);
SpreadsheetLocation cell = new SpreadsheetLocation(input[0]);
int col = cell.getCol();
int row = cell.getRow();
if (col > COLUMNS || row > ROWS) {
return "Error: cell outside of spreadsheet"; //error message
}
//assigning a textcell
if (input[2].contains("\"")) {
String inputValue = input[2].substring(1, input[2].length() - 1);
TextCell textCell = new TextCell(inputValue);
spreadsheet[row][col] = textCell;
//assigning a percent cell
} else if (input[2].contains("%")) {
PercentCell percentCell = new PercentCell(input[2]);
spreadsheet[row][col] = percentCell;
The percent cell extends super class, Real Cell:
public class RealCell implements Cell {
private String fullText;
public RealCell(String input) {
this.fullText = input;
}
//method that returns the display of the abbreviated cell
public String abbreviatedCellText() {
if (fullText.length() > 10) {
return fullText.substring(0, CELLWIDTH);
} else {
String output = fullText;
while(output.length() < CELLWIDTH) {
output += " ";
}
return output;
}
}
//method that returns the actual value in a real cell
public String fullCellText() {
return fullText;
}
//method that parses the user input into a double
public double getDoubleValue() {
return Double.parseDouble(fullText);
}
}
Here is now the problem part of my code, the Percent Cell class:
public class PercentCell extends RealCell {
private String fullText;
public PercentCell(String input) {
super(input);
}
//method that returns the display of the abbreviated cell, truncating the decimal
public String abbreviatedCellText() {
String value = fullText;
if (value.contains(".")) {
int decIndex = fullText.indexOf(".");
value = value.substring(0, decIndex) + "%";
}
if (value.length() > 10) {
return value.substring(0, CELLWIDTH);
} else {
String output = value;
while(output.length() < CELLWIDTH) {
output += " ";
}
return output;
}
}
//method that parses the user input into a double and returns the percent value into a decimal
public double getDoubleValue() {
double decimal = Double.parseDouble(fullText.substring(0, fullText.length() - 1));
return decimal/100;
}
}
How could I fix this error?
If any clarifications regarding my code are needed (because this is not my entire project) please let me know!
public class PercentCell extends RealCell {
public PercentCell(String input) {
super(input);
}
//method that returns the display of the abbreviated cell, truncating the decimal
public String abbreviatedCellText() {
String value = super.fullCellText();
if (value.contains(".")) {
int decIndex = value.indexOf(".");
value = value.substring(0, decIndex) + "%";
}
if (value.length() > 10) {
return value.substring(0, CELLWIDTH);
} else {
String output = value;
while(output.length() < CELLWIDTH) {
output += " ";
}
return output;
}
}
You used fullText field without giving value and fullText value was always null
I think that was the problem, but let me know please if it helps!

MP Android Chart

Hi I am using MPAndroid chart as charting library in my android app. I am trying to highlight some out of the range values on line dataset with different color (Picture 1)and if the value is beyond range then I want to also change marker-view drawable image also.
I have achieved this (Picture 2 ) for now I have managed to change color to red of out of the range values. How can I achieve Picture 1 in chart?
private void populateChart() {
chart = binding.lcCharts;
chart.setBackgroundColor(Color.WHITE);
chart.getDescription().setEnabled(false);
chart.setDoubleTapToZoomEnabled(false);
chart.setPinchZoom(false);
chart.setScaleEnabled(false);
getXAxisData()
LineData lineData = new LineData(setLineDataSet());
lineData.setDrawValues(false);
chart.setData(lineData);
chart.setTouchEnabled(true);
chart.setDrawMarkers(false);
chart.setHighlightPerTapEnabled(true);
chart.setMarker(new YourMarkerView(fragment.requireContext(), R.layout.layout_pop_up));
chart.setClipChildren(false);
chart.setClipToPadding(false);
chart.invalidate();
chart.notifyDataSetChanged();
}
private ArrayList<ILineDataSet> setLineDataSet() {
ArrayList<ILineDataSet> dataSet = new ArrayList<>();
for (int i = 0; i < response.size(); i++) {
LineDataSet lineDataSet = new LineDataSet(setData(i),
response.get(i).getName());
lineDataSet.setLineWidth(3);
lineDataSet.setColor(this.getResources().getColor(colorArray[i]));
lineDataSet.setDrawCircleHole(false);
lineDataSet.setCircleRadius(4);
lineDataSet.setCircleColors(setColorOfLineDataSet(i));
dataSet.add(lineDataSet);
}
return dataSet;
}
private ArrayList<Integer> setColorOfLineDataSet(int i) {
ArrayList<Integer> color = new ArrayList<Integer>();
for (int j = 0; j < response.get(i).size(); j++) {
if (!response.get(i).isNormal()) {
color.add(R.color.Red);
} else {
color.add(colorArray[i]);
}
}
return color;
} private void getXAxisData() {
XAxis xAxis = chart.getXAxis();
xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
xAxis.setDrawAxisLine(false);
xAxis.setDrawGridLines(false);
// xAxis.setGranularity(1f);
xAxis.setValueFormatter(new MyXAxisValueFormatter(getDateArrayForXAxis()));//getDateArrayForXAxis function returns a String array of size 14 with values of dates of past two weeks.
xAxis.setLabelCount(14, true);
}
public class MyXAxisValueFormatter extends ValueFormatter {
private String[] mValues;
public MyXAxisValueFormatter(String[] values) {
this.mValues = values;
}
public String getFormattedValue(float value) {
String val = null;
try {
val = String.valueOf(mValues[(int) value]);
} catch (IndexOutOfBoundsException e) {
}
return val;
}
/**
* Used to draw axis labels, calls {#link #getFormattedValue(float)} by default.
*
* #param value float to be formatted
* #param axis axis being labeled
* #return formatted string label
*/
public String getAxisLabel(float value, AxisBase axis) {
return getFormattedValue(value);
}
}
This code is crashing with arrayIndexOutOfBoundException.
enter code here
For customizing the Circle shape you can use following methods of the LineDataSet:
setCircleColor(/some Color value/)
setCircleRadius(/* some float value */)
setDrawCircleHole(/* boolean value */)
setDrawFilled(/* boolean value*/)
try these out, maybe you'll find something which you want. But I don't think it will allow you to change the shape completely.
I have referred to this article for an example:https://www.studytutorial.in/android-line-chart-or-line-graph-using-mpandroid-library-tutorial

JavaFX IllegalArgumentException: The start must be <= the end

I am trying to format string in TextField which includes: remove all characters that are not numbers, format numbers using DecimalFormatter and limit number of character in the TextField:
private void IntegerInputChecker() {
ChangeListener<String> integerChecker = new ChangeListener<String>() {
#Override
public void changed(ObservableValue<? extends String> observable, String oldValue,
String newValue) {
String pureValue = newValue;
String formatedText = newValue;
if (pureValue.length() <= 15) {
// Limit the characters in TextField
if (!newValue.matches("\\d*")) {
// Replace everything excepts number
pureValue = newValue.replaceAll("[^\\d]", "");
formatedText = pureValue;
}
if (pureValue.length() > 3) {
// Format number
DecimalFormat formatter = new DecimalFormat( "#,###" );
formatedText = formatter.format(Double.parseDouble(pureValue));
}
else if(pureValue.length() == 3) {
formatedText = pureValue.replaceAll(",", "");
}
}
else {
// Limit the characters in TextField
formatedText = formatedText.substring(0, formatedText.length() - 1);
}
fieldPrice.setText(formatedText);
}
};
fieldPrice.textProperty().addListener(integerChecker);
}
Everything works fine when I type in number but when I try to delete them in order, JavaFX throws an exception (the program still works fine):
java.lang.IllegalArgumentException: The start must be <= the end
For example, If I have 123,456,789 when I delete the number to 123,456 then it throws the above exception.
Thanks in advance.

How can I format a String number to have commas in android Edit Field

For what function I can use in android to display the number into different formats.
For eg:
If I enter 1000 then it should display like this 1,000.
If I enter 10000 then it should display like this 10,000.
If I enter 1000000 then it should display like this 1,000,000.
Please guide me.
You could use DecimalFormat and just format the number
DecimalFormat formatter = new DecimalFormat("#,###,###");
String yourFormattedString = formatter.format(100000);
The result will be
1,000,000 for 1000000
10,000 for 10000
1,000 for 1000
Update 12/02/2019
This String.format("%,d", number) would be a better(less hardcoded) solution as indicated in the comments below by #DreaminginCode so I thought I would add it here as an alternative
try this one hope it will help.
System.out.println(NumberFormat.getNumberInstance(Locale.US).format(1000));
private String getFormatedAmount(int amount){
return NumberFormat.getNumberInstance(Locale.US).format(amount);
}
int[] numbersToFormat = new int[]
{ 1, 10, 100, 10000, 100000, 1000000, 10000000, 100000000, 1000000000 };
for (int number : numbersToFormat) {
System.out.println(
NumberFormat.getNumberInstance(Locale.getDefault()).format(number));
}
OUTPUT
1
10
100
10,000
100,000
1,000,000
10,000,000
100,000,000
1,000,000,000
Add this function in common class
public static String getFormatedNumber(String number){
if(!number.isEmpty()) {
double val = Double.parseDouble(number);
return NumberFormat.getNumberInstance(Locale.US).format(val);
}else{
return "0";
}
}
And use that function every where like this:
String newNumber = Utils.getFormatedNumber("10000000");
You can use Numberformat
public static double getNumberByString(String s) throws ParseException {
return NumberFormat.getInstance(Locale.getDefault()).parse(s).doubleValue();
}
Add a text change listener as below (Also make sure that the input type selected for Edittext is Number) :
etTest.addTextChangedListener(new TextWatcher() {
boolean isManualChange = false;
#Override
public void onTextChanged(CharSequence s, int start, int before,
int count) {
if (isManualChange) {
isManualChange = false;
return;
}
try {
String value = s.toString().replace(",", "");
String reverseValue = new StringBuilder(value).reverse()
.toString();
StringBuilder finalValue = new StringBuilder();
for (int i = 1; i <= reverseValue.length(); i++) {
char val = reverseValue.charAt(i - 1);
finalValue.append(val);
if (i % 3 == 0 && i != reverseValue.length() && i > 0) {
finalValue.append(",");
}
}
isManualChange = true;
etTest.setText(finalValue.reverse());
etTest.setSelection(finalValue.length());
} catch (Exception e) {
// Do nothing since not a number
}
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
// TODO Auto-generated method stub
}
#Override
public void afterTextChanged(Editable s) {
// TODO Auto-generated method stub
}
});
public static String formatNumber(int number){
return NumberFormat.getNumberInstance(Locale.getDefault()).format(number);
}
public static String formatNumber(String number){
return NumberFormat.getNumberInstance(Locale.getDefault()).format(Integer.parseInt(number));
}
I wrote this Kotlin extension function may can help.
fun String.formatPoint(): String {
val sb = StringBuilder()
this.reversed().forEachIndexed { index, c ->
// 123,123,123
if ((index + 1) % 3 == 0) {
if (index != this.length - 1) {
sb.append("$c,")
} else {
sb.append(c)
}
} else {
sb.append(c)
}
}
return sb.toString().reversed()
}
Recommended and preferred way is to do it with the strings.xml file
<string name="format_denominated">%,d</string>
from your Kotlin/Java code
getResources().getString(R.string.format_denominated, value)
Even better with databinding
<TextView
android:text="#{#string/format_denominated(value)}"
............/>

Categories

Resources