Supongo que el título regala la mayoría de mis preguntas, pero vamos a detallar y dar un poco de antecedentes:Mi Android AChartEngine ya está funcionando, pero ¿cómo hacer que se vea bien?
Tengo una aplicación para Android enfocada principalmente a tabletas que mostrarán algunos datos diferentes en tiempo real en TimeCharts. Así que ya tengo un servicio para comunicarme con la fuente de datos que toma los datos, los analiza y agrega los valores a Singletons TimeSeries. Cuando el usuario navega dentro y fuera de fragmentos del fragmento simplemente añade las TimeSeries correctas y sigue llamando mChartView.repaint();
cada 500 ms
Todo lo que es operativa y trabajando muy bien por las fichas, rotación, notificación, etc.
Debido a que es una tableta aplicación Quiero lograr dos cosas: 1) maximizar el área de visualización; 2) hacer que se vea bien.
1) Ya retiré los botones del zoom (por alguna razón si trato de agregarlos, me da NullException) con mRenderer.setZoomButtonsVisible(false);
, pero todavía hay un gran margen inferior que ocupa mucho espacio en la pantalla. Intenté establecer un borde negativo, y funciona, pero las etiquetas no se mueven con este borde y termino con el eje X cruzando las etiquetas o incluso pasándolas. ¿Cómo puedo mover las etiquetas hacia abajo con el borde o ponerlas en la parte superior del gráfico?
2) a) la aplicación es configurable por el usuario para usar Holo_Dark o Holo_light. Así que estoy usando un fondo transparente en el renderizador (vea el fragmento a continuación) para mostrar ese lindo sombreado de fondo que holo hace. Cómo cambiar el color del texto del eje? Encontré el mRenderer.setAxesColor(color)
pero solo cambia la línea, no el texto.
int color = Color.argb(0, 255, 255, 255); // Transparent colour
mRenderer.setBackgroundColor(color);
mRenderer.setMarginsColor(color);
b) el eje Y está cruzando en la parte superior de la misma de las etiquetas, ¿cómo puedo compensar un poco hacia la izquierda para que el texto sea legible? (no es con setMargins()
)
c) cuando el usuario amplía y gira alrededor del gráfico, el gráfico deja de actualizar/volver a acercar los últimos valores en la pantalla y el usuario tiene que seguir desplazándose para ver los últimos valores. Agregué un botón "Restablecer zoom" en la Barra de acciones, pero no puedo hacerlo funcionar. ¿Cuál sería el código para hacer que los valores se actualicen nuevamente?
d) si mi TimeSeires tiene un rango de 10min (2 valores por segundo) ¿cómo puedo hacer que solo muestre los últimos 1min (por ejemplo) y si el usuario quiere valores previos puede retroceder? (Y el botón de su uso en c) volver a empezar)
en el momento en que mi rendido se configura como:
int color = Color.argb(0, 255, 255, 255); // Transparent colour
mRenderer.setBackgroundColor(color);
mRenderer.setMarginsColor(color);
mRenderer.setAxisTitleTextSize(16); // 16
mRenderer.setChartTitleTextSize(20); // 20
mRenderer.setLabelsTextSize(15); // 15
mRenderer.setLegendTextSize(15); // 15
mRenderer.setPointSize(0); // 10
mRenderer.setMargins(new int[] { 20, 30, 15, 0 });
mRenderer.setZoomButtonsVisible(false);
mRenderer.setShowAxes(true);
mRenderer.setShowLegend(true);
mRenderer.setShowGridX(true);
mRenderer.setShowLabels(true);
y cada prestados añade al procesador múltiple es como sigue:
renderer.setDisplayChartValues(false);
mRenderer.addSeriesRenderer(renderer);
muchas gracias por toda la ayuda!
edición acaba de incluir mi código final para que otros lo vean:
he terminado abandonando por completo la leyenda y la implementación de mi propia leyenda flotando por encima de la tabla, por lo que el diseño es una FrameLayout con un ChartView y un TableLayout.
Implementé una clase CurvesFragment abstracta que se extiende por unas pocas clases.
puedo configurar la tabla durante mi fragmento OnCreateView como:
mChartView = ChartFactory.getTimeChartView(getActivity().getApplicationContext(), mDataset, mRenderer, "HH:mm:ss"); // X axis in a time scale
// Setup chart renderer =============================
mRenderer.setLabelsTextSize(15); // Text size
mRenderer.setMargins(new int[] { 0, Utils.convertToPx(5, getActivity().getApplicationContext()), 0, 0 }); // 5dp on the left to show that little line
mRenderer.setZoomButtonsVisible(false); // bye bye zoom
mRenderer.setShowAxes(true); // show both axes
mRenderer.setShowLegend(false); // bye bye legend
mRenderer.setShowGridX(true); // X grid helps identify values
mRenderer.setShowLabels(true); // See the values
mRenderer.setYLabelsAlign(Align.LEFT); // put the Y labels on the left of the axis
if (Utils.getCurrentTheme(getActivity().getApplicationContext()) == android.R.style.Theme_Holo) {
mRenderer.setXLabelsColor(getResources().getColor(android.R.color.primary_text_dark));
mRenderer.setYLabelsColor(0, getResources().getColor(android.R.color.primary_text_dark));
mRenderer.setMarginsColor(getResources().getColor(android.R.color.background_dark));
legend.setBackgroundResource(R.drawable.border_dark);
} else {
// same as above but for Holo_light
}
// And from here proceed to add the TimeCharts with using
renderer.setDisplayChartValues(false);
En mi barra de acción Incluí botones para Pausa/Reanudar y ResetZoom. el Restaurar Zoom es simple:
mRenderer.setXAxisMax(-Double.MAX_VALUE);
mRenderer.setXAxisMin(Double.MAX_VALUE);
mRenderer.setYAxisMax(-Double.MAX_VALUE);
mRenderer.setYAxisMin(Double.MAX_VALUE);
mChartView.repaint();
Hay un servicio en segundo plano que contiene referencias a los TimeSeries que siempre está leyendo datos frescos de la conexión Wi-Fi y la adición a la serie. De esta manera, en el fragmento no es un ejecutable ejecutar cada 700ms que llama repinte() como:
// Chart rendering control ========================
private Runnable updateDataSet = new Runnable() {
public void run() {
if (!chartPaused) {
double max = mRenderer.getXAxisMax(); // get renderer maximum value
double min = mRenderer.getXAxisMin(); // get renderer minimum value
// Check if the user scrolled/zoomed/panned the graph or if it's on 'auto'
if (!((max == Double.MAX_VALUE || max == -Double.MAX_VALUE) && (min == Double.MAX_VALUE || min == -Double.MAX_VALUE))) {
double newMax = mDataset.getSeriesAt(0).getMaxX(); // new max is the latest value from our series
double newMin = newMax - Math.abs(max - min); // new min value is the X range the user zoomed into
mRenderer.setXAxisMax(newMax); // set the new values
mRenderer.setXAxisMin(newMin);
}
// Logic that updates the TableLayout with the legend is placed here
mChartView.repaint();
}
getView().postDelayed(updateDataSet, 700);
}
};
y hay una ZoomListener y una PanListener que detiene el gráfico cada vez que el usuario lo toca. De esta forma, el usuario puede hacer zoom y desplazarse, pero siempre que reanude la actualización del gráfico, solo avanzará a los datos más antiguos sin cambiar el nivel de zoom.
Supongo que el resultado final es bastante sólido y se ve bien en Holo_Light y Holo_Dark.
Gracias a LOTE por Dan para las respuestas y para todos los demás desarrolladores que crearon el motor.
happy coding!
hi Dan. Gracias por la info. Eso es parte de un proyecto de ingeniería y los gráficos son datos en tiempo real de la máquina que estamos desarrollando. Por el momento tuve que interrumpir la aplicación de Android para hacer frente a algunas cosas más urgentes, pero volveré sobre ello en un par de días y probaré todas sus sugerencias. PD.: 'Incluso el autor de esta biblioteca tiene que pensar en algunas respuestas:)' He revisado tu perfil, entonces eres el autor. Muchas gracias por la achartengine en sí y por las respuestas. – Budius
e) Para eliminar el desplazamiento de esa tabla: mRenderer.setZoomEnabled (false); mRenderer.setPanEnabled (falso); – ViJay