android - una - evitar duplicados con validación de datos en excel
mpandroidchart-¿Cómo puedo evitar los valores repetidos en el eje Y? (6)
Aunque esta es una pregunta más antigua, me gustaría agregarla para futuras referencias. Las versiones más recientes de la biblioteca tienen una característica poco conocida que resuelve las etiquetas duplicadas, llamada granularidad. Esto es mucho más fácil de usar que las soluciones anteriores (aunque para ser justos, no estaba disponible en el momento en que se publicaron).
Siempre puede consultar los últimos AxisBase
Javadocs (3.0.0-beta1) para obtener una explicación más detallada. Aquí están los métodos relevantes:
setGranularity(float granularity)
: establece un intervalo mínimo para el eje cuando se acerca. El eje no puede ir por debajo de ese límite. Esto se puede usar para evitar la duplicación de etiquetas al acercarse.setGranularityEnabled(boolean enabled)
: habilitó / deshabilitó el control de granularidad en los intervalos de valores del eje. Si está habilitado, el intervalo del eje no puede ir por debajo de una cierta granularidad.
Entonces, en su caso, tendría que establecer la granularidad en 0.1f
ya que tiene un punto decimal. El siguiente fragmento de código debe evitar los valores repetidos en el eje:
YAxis yAxis = mChart.getAxisLeft();
yAxis.setGranularityEnabled(true);
yAxis.setGranularity(0.1f);
Quiero evitar los valores repetidos y los valores -0 en el eje Y, evitando la situación de la imagen.
Tengo estas ideas para resolver esto, pero cualquier solución:
- Limite el zoom antes de repetir los valores en YAxis, por lo tanto, detenga el zoom infinito en la tabla
- Obtener los valores de YAxis y eliminar los valores duplicados.
Nunca he usado MPAndroidCharts antes, pero solo una pequeña búsqueda aquí y allá me dio este método que creo que sería útil.
public void setLabelCount(int count, boolean force) {
if (count > 25)
count = 25;
if (count < 2)
count = 2;
mLabelCount = count;
mForceLabels = force;
}
La descripción dice que "el conteo exacto especificado de etiquetas se dibujará y se distribuirá uniformemente a lo largo del eje". Si puede hacerlo funcionar a su favor, puede limitar el zoom.
Además, hay otro método
public int getLabelCount() {
return mLabelCount;
}
Esto devuelve el número de etiquetas en el eje. Espero que esto ayude.
Puede establecer la granularidad en el valor requerido para evitar la repetición cuando se amplía.
mBarChart.getAxisLeft().setGranularity(1f); // y-axis scale will be 0,1,2,3,4....
mBarChart.getAxisLeft().setGranularityEnabled(true);
Si desea establecer la granularidad dinámicamente, implemente IAxisValueFormatter y compare el valor de retorno para obtener la diferencia y establezca la granularidad en esa diferencia.
private float yAxisScaleDifference = -1;
private boolean granularitySet = false;
//say the values returned by IAxisFormatter is in hundreds: 100, 200, 300...
mBarChart.getAxisLeft.setValueFormatter(new IAxisValueFormatter() {
@Override
public String getFormattedValue(float v, AxisBase axisBase) {
if(!granularitySet) {
if(yAxisScaleDifference == -1) {
yAxisScaleDifference = v; //10
}
else {
float diff = v - yAxisScaleDifference; //200 - 100 = 100
if(diff >= 1000) {
yAxisLeft.setGranularity(1000f);
}
else if(diff >= 100) {
yAxisLeft.setGranularity(100f); //set to 100
}
else if(diff >= 1f) {
yAxisLeft.setGranularity(1f);
}
granularitySet =true;
}
}
return val;
}
});
Otro ejemplo:
say Y-Axis returns [1200,3400,8000,9000....]
first time: 1200
second time: 3400 - 1200 = 2200
granularity set to 1000
Si la diferencia no es uniforme, tiene que usar array para almacenar las diferencias y tomar el promedio para obtener la granularidad correcta.
Si está utilizando IAxisValueFormatter, el problema podría estar en la conversión de float a Int cuando intente acceder a la matriz de valores.
Para mí la solución fue
IAxisValueFormatter numAppointmentsXAxisFormatter = new IAxisValueFormatter() {
@Override
public String getFormattedValue(float value, AxisBase axis) {
int index = (int)Math.ceil(value);
if(index < 0){
index = 0;
}else if(index >= numAppointmentsLabels.size()){
index = numAppointmentsLabels.size()-1;
}
return numAppointmentsLabels.get(index);
}
};
También agregué +1 al recuento de etiquetas
chart.getXAxis().setLabelCount(numValue+1, true);
Espero eso ayude
código como este:
mchart.setAutoScaleMinMaxEnabled(false);
mchart.getAxisLeft().setAxisMaxValue(10);
mchart.getAxisLeft().setAxisMinValue(5);
mchart.getAxisRight().setAxisMaxValue(10);
mchart.getAxisRight().setAxisMinValue(5);
o:
boolean a = isReady;
mchart.getAxisLeft().setFormater(new format(float b){ return "" ;})
Cuando obtienes datos:
mchart.setAutoScaleMinMaxEnabled(true);
mchart.getAxisLeft().resetAxisMaxValue();
mchart.getAxisLeft().resetAxisMinValue();
mchart.getAxisRight().resetAxisMaxValue();
mchart.getAxisRight().resetAxisMinValue(5);
No tengo código a mi mano.
tl; dr Puede hacer esto cambiando el recuento de etiquetas en onChartScale
.
Primero, quieres que tu oyente esté configurado:
chart.setOnChartGestureListener(this); // set a listener ;)
Intenta obtener los valores dibujados arriba / abajo y verifique qué se dibuja en la pantalla. Aplica algunos cálculos básicos, y listo.
El siguiente código dibujará 2 etiquetas si el nivel de zoom se eleva (demasiado) y hasta 9 de lo contrario:
@Override
public void onChartScale(MotionEvent me, float scaleX, float scaleY) {
final YAxis yAxis = mChart.getAxisLeft();
final Transformer transformer = mChart.getTransformer(YAxis.AxisDependency.LEFT);
// ...minor dirty hack
final PointD top = transformer.getValuesByTouchPoint(0, 0);
final PointD bottom = transformer.getValuesByTouchPoint(0, mChart.getHeight());
final int diff = (int)(top.y - bottom.y);
// draw 2-9 axis labels
final int count = Math.min(9, Math.max(diff, 2));
Log.d("scale", String.format("scale %f: diff %d and count %d", scaleY, diff, count));
// "force" the count, for there are drawing issues where none get drawn on high zoom levels (just try it out)
yAxis.setLabelCount(count, true);
}
// todo implement other interface methods
El formateador de valores y todo lo demás permanece igual.
Y algunas capturas de pantalla feas para mostrar que funciona: D