Cuando se trabaja con aplicaciones de uso intensivo de datos, un desarrollador a menudo debe hacer algo más que mostrar listas de registros de datos en una vista de tabla. La biblioteca CorePlot le permitirá agregar impresionantes visualizaciones de datos a sus aplicaciones. Descubre cómo en esta serie Tuts + Premium.!
La última vez que introdujimos el marco CorePlot y discutimos lo que puede hacer y cómo podemos usarlo para mejorar la visualización de datos en nuestras aplicaciones. También exploramos la aplicación de muestra que vamos a crear en la serie y cómo agregar CorePlot a nuestra aplicación. Para obtener una instantánea del código donde lo dejamos la última vez, descargue el código fuente de este tutorial (de lo contrario, ¡no dude en utilizar su base de código existente y ahorre tiempo de descarga!).
Antes de que podamos crear un gráfico, necesitaremos una vista para hacerlo. Vamos a permitir que el usuario haga clic en un UIBarButtonItem en la pestaña 'Estudiantes' que mostrará una hoja de acción que contiene una lista de gráficos para el usuario a elegir. Una vez que se realiza una selección, una vista modal mostrará un gráfico con los datos relevantes en él..
Vamos a crear un nuevo grupo llamado 'Graficar' debajo del grupo 'StudentTracker'. Cree un grupo de 'Vistas' y 'Controladores' debajo de este como en 'Lista de estudiantes' y 'Lista de sujetos'.
Cree una nueva clase llamada 'STLineGraphViewController' (subclasificando UIViewController) en el grupo 'Ver controladores'. Al elegir dónde agregar los archivos, el mejor lugar para colocarlos es la carpeta 'Clases / Gráficos / Controladores de vista' (tendrá que crear el directorio 'Gráficos / Controladores de vista').
Vamos a volver y trabajar en la personalización de esto más adelante. Ahora mismo vamos a implementar ese código que le permite al usuario seleccionar un gráfico para ver.
Primero abra STStudentListViewController.h y agregue las declaraciones de protocolo 'UIActionSheetDelegate' y 'STLineGraphViewControllerDelegate'. Este protocolo aún no existe, pero lo crearemos más tarde (también asegúrese de importar el archivo 'STLineGraphViewController.h').
@interface STStudentListViewController: UIViewController
A continuación, abra el archivo .m e implemente el método 'actionSheet: clickedButtonAtIndex:' con el siguiente código:
- (void) actionSheet: (UIActionSheet *) actionSheet clickedButtonAtIndex: (NSInteger) buttonIndex if (buttonIndex == 0) STLineGraphViewController * lineGraphVC = [[STLineGraphViewController alloc] init]; [lineGraphVC setModalTransitionStyle: UIModalTransitionStyleFlipHorizontal]; [lineGraphVC setDelegate: self]; [lineGraphVC setManagedObjectContext: [self managedObjectContext]]; [self presentModalViewController: lineGraphVC animated: YES]; [lineGraphVC release];
Este código no debería necesitar demasiadas explicaciones. Simplemente estamos creando un LineGraph View Controller y presentándolo de manera modesta. Nos establecemos como delegados para que sepamos cuándo desechar la vista modal. También le damos al controlador de la vista un contexto de objeto gestionado con el que trabajar para que pueda interactuar con los datos centrales. Estos dos últimos métodos crearán una advertencia (o error si se usa ARC) porque las propiedades aún no existen, pero las crearemos más adelante.
A continuación, crearemos un método para llamar a la hoja de acción y agregaremos un UITabBarItem para llamarla. Agregue una declaración de método en la interfaz .m llamada 'graphButtonWasSelected:':
@interface STStudentListViewController () @property (nonatomic, strong) NSArray * studentArray; - (void) addStudent: (id) sender; - (void) graphButtonWasSelected: (id) sender; @fin
A continuación, agregue la implementación del método:
- (void) graphButtonWasSelected: (id) sender UIActionSheet * graphSelectionActionSheet = [[[[UIActionSheet alloc] initWithTitle: @ Elija un gráfico "delegado". "" "" "" "" "" "" "" "" "" "" "" "" "" ] autorelease]; [graphSelectionActionSheet showInView: [[UIApplication sharedApplication] keyWindow]];
A continuación, debemos agregar un UIBarButtonItem para que el usuario lo seleccione cuando quiera ver el gráfico. Haremos esto en el método viewDidLoad debajo de donde creamos el elemento del botón de la barra derecha:
[[self navigationItem] setLeftBarButtonItem: [[[UIBarButtonItem alloc] initWithTitle: @ estilo de "Gráficos": UIBarButtonItemStylePlain target: auto action: @selector (graphButtonWasSelected :)] autorelease]
Finalmente, necesitamos implementar un método de protocolo STLineGraphViewController que le indique al controlador que descarte la vista modal cuando el usuario haya terminado de mirar el gráfico:
- (void) doneButtonWasTapped: (id) sender [self dismissModalViewControllerAnimated: YES];
Ahora estamos listos para empezar a crear la gráfica.!
Primero necesitamos crear una clase de vista personalizada para nuestro LineGraphViewController. En el grupo Gráficos> Vistas, cree una nueva clase que extienda UIView llamada 'STLineGraphView' (asegúrese de colocarla en la carpeta correcta cuando elija dónde se guardará en el sistema de archivos).
Vamos a configurar los aspectos gráficos de la vista en la clase de vista. Primero vaya al archivo .h y (después de importar el archivo "CorePlot-CocoaTouch.h") y agregue la siguiente declaración de propiedad:
@ propiedad (no atómica, fuerte) CPTGraphHostingView * chartHostingView;
El CPTGraphHostingView es simplemente un UIView que se encarga de contener el gráfico y de permitir la interacción del usuario (que veremos en un tutorial posterior).
Sintetice chartHostingView y cree la vista de alojamiento de gráficos en el método initWithFrame:
[self setChartHostingView: [[[CPTGraphHostingView alloc] initWithFrame: CGRectZero] autorelease]]; [auto addSubview: chartHostingView];
Lo anterior debe ser bastante autoexplicativo. Creamos un CPTGraphHostingView y lo configuramos como nuestra propiedad chartHostingVIew. Luego lo agregamos como una subvista.
A continuación, debemos configurar las dimensiones del cuadro graphViews en el método de 'subvistas de diseño':
[super layoutSubviews]; float chartHeight = self.frame.size.height - 40; float chartWidth = self.frame.size.width; [[self chartHostingView] setFrame: CGRectMake (0, 0, chartWidth, chartHeight)]; [[self chartHostingView] setCenter: [self center]];
Una vez más, todo lo anterior debe ser simple. Antes de comenzar a trabajar en el controlador, asegúrese de liberar la propiedad 'chartHostingView' en el método dealloc de vistas si aún no lo ha hecho..
La mayor parte del trabajo que vamos a hacer ahora estará en el controlador. Abra STLineGraphViewController.h y agregue las siguientes declaraciones de propiedades:
@interface STLineGraphViewController: UIViewController@property (nonatomic, strong) CPTGraph * graph; @ propiedad (no atómica, asignar) id delegar; @ propiedad (no atómica, fuerte) NSManagedObjectContext * managedObjectContext;
El CPTGraph es una clase abstracta que se encarga de dibujar los elementos del gráfico y administrar los diferentes gráficos. También es responsable de aplicar temas, recargar los datos del gráfico y mucho más. También estamos indicando que cumpliremos con los protocolos CPTScatterPlotDataSource y CPTScatterPlotDelegate.
También necesitamos agregar un protocolo propio para que la vista modal pueda ser descartada. Coloque el siguiente código sobre la declaración de interfaz:
@protocol STLineGraphViewControllerDelegate @required - (void) doneButtonWasTapped: (id) sender; @fin
Pase al archivo * .m y sintetice el gráfico y delegue las propiedades. Una vez hecho esto, agregue el siguiente código antes del método 'viewDidLoad':
[self setView: [[[STLineGraphView alloc] initWithFrame: self.view.frame] autorelease]]; CPTTheme * defaultTheme = [CPTTheme themeNamed: kCPTPlainWhiteTheme]; [auto setGraph: (CPTGraph *) [defaultTheme newGraph]]; [versión por defecto del tema];
Hay algunas cosas que suceden en esta sección. Primero, estamos creando y configurando la vista del controlador como nuestro STLineGraphView personalizado. A continuación, creamos un objeto 'CPTTheme'. El objeto CPTTheme administra el estilo de un gráfico con estilos de línea, estilo de texto y cualquier relleno que se requiera. Una forma fácil de obtener un CPTGraph preconfigurado con un CPTTheme base es crear el CPTTheme con uno de los nombres de tema predefinidos y luego usar el método 'newGraph' para darnos un gráfico con el estilo.
A continuación, vamos a colocar el siguiente código en el método 'viewDidLoad':
[super viewDidLoad]; STLineGraphView * graphView = (STLineGraphView *) [vista propia]; [[self graph] setDelegate: self]; [[graphView chartHostingView] setHostedGraph: [auto graph]]; CPTScatterPlot * studentScatterPlot = [[CPTScatterPlot alloc] initWithFrame: [gráfico de límites]]; [studentScatterPlot setIdentifier: @ "studentEnrollment"]; [studentScatterPlot setDelegate: self]; [studentScatterPlot setDataSource: self]; [[auto-gráfico] addPlot: studentScatterPlot]; UINavigationItem * navigationItem = [[UINavigationItem alloc] initWithTitle: self.title]; [navigationItem setHidesBackButton: YES]; UINavigationBar * navigationBar = [[[[UINavigationBar alloc] initWithFrame: CGRectMake (0, 0, self.view.frame.size.width, 44.0f)] autorelease]; [navigationBar pushNavigationItem: navigationItem animated: NO]; [self.view addSubview: navigationBar]; [navigationItem setRightBarButtonItem: [[[UIBarButtonItem alloc] initWithTitle: @ estilo "Listo": UIBarButtonItemStyleDone target: [self delegate] action: @selector (doneButtonWasTapped :)] autorelease]
En el código anterior, obtenemos nuestra vista y configuramos el gráfico alojado para la vista de alojamiento del gráfico de vistas para nuestro objeto gráfico. Luego creamos una 'parcela' para poner en el gráfico. Usamos el 'CPTScatterPlot' cuando queremos crear un gráfico de líneas. El identificador es algo que podemos usar para identificar la trama más adelante. Luego, configuramos el delegado y la fuente de datos a la clase del controlador, ya que será responsable de proporcionar los datos para el gráfico. Finalmente, añadimos la nueva trama creada de la gráfica..
Después de trabajar con el gráfico, creamos un elemento de navegación y una barra para que el controlador de vista modal muestre un título y un botón de finalización que los llevará de vuelta a la vista original.
Intente ejecutar el proyecto ahora y vaya al gráfico de líneas. Deberías ver algo como lo siguiente:
Tenemos el inicio de una gráfica! Ahora para agregar algunos datos:
Los gráficos en CorePlot utilizan dos métodos principales de fuente de datos para obtener datos, 'numberOfRecordsForPlot' y 'numberForPlot: field: recordIndex:'. Es muy similar a cómo funcionan las vistas de tabla. Primero, queremos especificar el número de registros para la parcela:
- (NSUInteger) numberOfRecordsForPlot: (CPTPlot *) plot return 8;
Estamos mostrando cuántas inscripciones se produjeron todos los días de la semana. Ya que hay 7 días posibles en los que el estudiante podría haberse inscrito, tenemos 8 registros totales (porque comenzamos en 0).
Ahora queremos especificar cuál debe ser el valor de x e y para cada registro:
- (NSNumber *) numberForPlot: (CPTPlot *) campo de trazado: (NSUInteger) fieldEnum recordIndex: (NSUInteger) index NSUInteger x = index; NSUInteger y = 0; Error NSError *; NSFetchRequest * fetchRequest = [[NSFetchRequest alloc] init]; NSEntityDescription * entidad = [NSEntityDescription entityForName: @ "STStudent" inManagedObjectContext: managedObjectContext]; NSPredicate * predicate = [NSPredicate predicateWithFormat: @ "dayEnrolled ==% d", índice]; [fetchRequest setEntity: entidad]; [fetchRequest setPredicate: predicate]; y = [managedObjectContext countForFetchRequest: fetchRequest error: & error]; [fetchRequest release]; switch (fieldEnum) case CPTScatterPlotFieldX: NSLog (@ "el valor de x para% d es% d", índice, x); return [NSNumber numberWithInt: x]; descanso; case CPTScatterPlotFieldY: NSLog (@ "el valor de y para% d es% d", índice, y); return [NSNumber numberWithInt: y]; descanso; por defecto: break; devuelve nil;
Hay un poco justo pasando arriba. Este método debe especificar un valor de x e y para un índice determinado y el valor que devuelve se basa en el valor 'fieldEnum' (que en nuestro caso es CPTScatterPlotFieldX o CPTScatterPlotFieldY). El índice indica el registro que está a punto de trazar en el gráfico y la gráfica se refiere a la gráfica real que muestra los datos. Cuando tenemos un controlador que administra más de 1 gráfico, podemos ver el identificador de gráfico para determinar qué conjunto de datos proporcionar (cubrimos este proceso en un tutorial posterior).
Encuentro que es más fácil especificar un valor de 'x' e 'y' al comienzo del método, calculando ambos valores, y luego en base a la enumeración del campo que devuelve el correcto en la forma de un Número de NS (que es el formato que corePlot lo requiere en).
El valor de x es fácil de averiguar. Como muestra los días de inscripción, x es igual al índice actual. El valor de y será un recuento de todos los estudiantes inscritos ese día. Podemos obtener esto haciendo una llamada a nuestro almacén de datos principal y buscando todos los registros de STStudent con un valor de "DayEnrolled" del índice. Si no está familiarizado con los datos básicos y no entiende todo lo que está sucediendo, no se preocupe demasiado, por ahora está bien que funcione. Enfócate en aprender una cosa a la vez!
Si guarda y ejecuta su aplicación ahora, aún no verá nada en el gráfico, pero debería ver el siguiente resultado en su consola:
Esto significa que la gráfica está obteniendo los valores correctos para x e y (asegúrese de que sea la misma o similar a la salida en la imagen. Sin embargo, todavía no se muestra en la gráfica. Eso se debe a que si observa la gráfica, el rango mostrado es incorrecto. Estamos viendo -1.0 a 0 tanto en el eje x como en el eje y. Necesitamos establecer el rango a mirar antes de poder ver los puntos de datos.
El espacio de trazado determina mucho sobre cómo se ve y se formatea el gráfico. Vamos a cubrir un poco en este tutorial y entraremos en mucho más detalle en el siguiente..
Para configurar el rango xey que el usuario mira, necesitamos trabajar con el objeto 'CPTXYPlotSpace'. Este objeto nos permite establecer un rango visible para el gráfico.
Vaya al método viewDidLoad y agregue el siguiente código justo debajo de donde agregamos el gráfico a nuestro gráfico:
CPTXYPlotSpace * studentPlotSpace = (CPTXYPlotSpace *) [graph defaultPlotSpace]; [studentPlotSpace setXRange: [CPTPlotRange plotRangeWithLocation: CPTDecimalFromInt (0) length: CPTDecimalFromInt (7)]]; [studentPlotSpace setYRange: [CPTPlotRange plotRangeWithLocation: CPTDecimalFromInt (0) length: CPTDecimalFromInt (10)]];
Primero, obtenemos un objeto CPTXYPlotSpace del espacio de trazado predeterminado de los gráficos (se requiere algo de conversión). Luego simplemente establecemos el rango xey. El rango es un objeto 'CPTPlotRange' que creamos estáticamente usando el método 'plotRangeWithLocation: length:'. Este método toma NSDecimals pero corePlot nos proporciona una función que podemos usar para obtener un decimal de un int llamado 'CPTDecimalFromInt' (También hay uno para flotar si es necesario).
Ahora guarde y ejecute la aplicación y debería ver el inicio de su primer gráfico!
Tenemos el inicio de un gráfico, pero necesita un poco más de trabajo antes de que pueda ser muy útil. La próxima vez vamos a discutir cómo configurar y formatear las etiquetas de los ejes, las líneas de graduación y los incrementos. También vamos a discutir cómo personalizar el aspecto del gráfico y, finalmente, cómo agregar y administrar varias parcelas en un solo gráfico. Nos vemos la proxima vez!