Quando si lavora con applicazioni ad uso intensivo di dati, uno sviluppatore deve spesso fare molto di più che mostrare solo elenchi di record di dati in una vista tabella. La libreria CorePlot ti consentirà di aggiungere incredibili visualizzazioni di dati alle tue applicazioni. Scopri come in questa serie di Tuts + Premium!
L'ultima volta abbiamo introdotto il framework CorePlot e discusso di cosa può fare e come possiamo utilizzarlo per migliorare la visualizzazione dei dati nelle nostre applicazioni. Abbiamo anche esplorato l'applicazione di esempio che creeremo nella serie e come aggiungere CorePlot alla nostra applicazione. Per un'anteprima di codice di dove abbiamo lasciato l'ultima volta, scarica il codice sorgente per questo tutorial (altrimenti sentiti libero di usare il tuo codice base esistente e risparmia il tempo di download!).
Prima di poter creare un grafico, abbiamo bisogno di una vista per farlo. Permetteremo all'utente di fare clic su un UIBarButtonItem nella scheda "Studenti" che farà apparire un foglio di azione contenente un elenco di grafici per utente da scegliere. Una volta effettuata una selezione, una vista modale mostrerà un grafico con i relativi dati.
Creeremo un nuovo gruppo chiamato "Graphing" sotto il gruppo "StudentTracker". Crea un gruppo "Visualizzazioni" e "Controllori" sotto questo come in "Elenco studenti" e "Elenco oggetto".
Crea una nuova classe chiamata 'STLineGraphViewController' (sottoclasse UIViewController) nel gruppo 'Visualizza controller'. Quando si sceglie dove aggiungere i file, il posto migliore per metterli è la cartella "Classi / Grafici / Controller di visualizzazione" (Dovrai creare la directory "Controller grafici / Visualizza").
Torneremo e lavoreremo per personalizzarlo più tardi. In questo momento implementeremo quel codice che consente all'utente di selezionare un grafico da guardare.
Innanzitutto aprire STStudentListViewController.h e aggiungere le dichiarazioni di protocollo 'UIActionSheetDelegate' e 'STLineGraphViewControllerDelegate'. Questo protocollo non esiste ancora ma lo creeremo in seguito (assicurati anche di importare il file 'STLineGraphViewController.h').
@interface STStudentListViewController: UIViewController
Quindi, apri il file .m e implementa il metodo "actionSheet: clickkedButtonAtIndex:" con il seguente codice:
- (void) actionSheet: (UIActionSheet *) actionSheet clickkedButtonAtIndex: (NSInteger) buttonIndex if (buttonIndex == 0) STLineGraphViewController * lineGraphVC = [[STLineGraphViewController alloc] init]; [lineGraphVC setModalTransitionStyle: UIModalTransitionStyleFlipHorizontal]; [lineGraphVC setDelegate: self]; [lineGraphVC setManagedObjectContext: [self managedObjectContext]]; [AutoModalViewController: lineGraphVC animated: YES]; [versione lineGraphVC];
Questo codice non dovrebbe richiedere troppe spiegazioni. Stiamo semplicemente creando un controller di visualizzazione LineGraph e presentandolo in modo modale. Ci poniamo come delegati in modo da sapere quando chiudere la vista modale. Diamo anche al controller della vista un contesto oggetto gestito con cui lavorare in modo che possa interfacciarsi con i dati principali. Questi ultimi due metodi creeranno un avvertimento (o errore se si usa ARC) perché le proprietà non esistono ancora, ma le creeremo in seguito.
Successivamente creeremo un metodo per chiamare il foglio azioni e aggiungere un UITabBarItem per chiamarlo. Aggiungi una dichiarazione di metodo nell'interfaccia .m chiamata 'graphButtonWasSelected:':
@interface STStudentListViewController () @property (nonatomic, strong) NSArray * studentArray; - (void) addStudent: (id) mittente; - (void) graphButtonWasSelected: (id) sender; @fine
Successivamente, aggiungi l'implementazione del metodo:
- (void) graphButtonWasSelected: (id) sender UIActionSheet * graphSelectionActionSheet = [[[UIActionSheet alloc] initWithTitle: @ "Scegli un grafico" delegato: self cancelButtonTitle: @ "Annulla" distructiveButtonTitle: nil otherButtonTitles: @ "Iscrizione nel tempo", nil ] autorelease]; [graphSelectionActionSheet showInView: [[UIApplication sharedApplication] keyWindow]];
Successivamente, è necessario aggiungere un UIBarButtonItem affinché l'utente possa selezionare quando desidera visualizzare il grafico. Lo faremo nel metodo viewDidLoad al di sotto del quale creiamo la voce del pulsante della barra destra:
[[self navigationItem] setLeftBarButtonItem: [[[UIBarButtonItem alloc] initWithTitle: @ Stile "Grafici": UIBarButtonItemStylePlain target: self action: @selector (graphButtonWasSelected :)] autorelease] animato: NO];
Infine, dobbiamo implementare un metodo di protocollo STLineGraphViewController che dirà al controller di ignorare la vista modale quando l'utente ha terminato di guardare il grafico:
- (void) doneButtonWasTapped: (id) sender [self dismissModalViewControllerAnimated: YES];
Ora siamo pronti per iniziare a creare il grafico!
Per prima cosa dobbiamo creare una classe di visualizzazione personalizzata per il nostro LineGraphViewController. Nel gruppo Grafica> Viste crea una nuova classe che estende UIView chiamata 'STLineGraphView' (assicurati di metterlo nella cartella corretta quando si sceglie dove è salvato sul file system).
Imposteremo gli aspetti grafici della vista nella classe vista. Prima vai sul file .h e (dopo aver importato il file "CorePlot-CocoaTouch.h") e aggiungi la seguente dichiarazione di proprietà:
@property (nonatomic, strong) CPTGraphHostingView * chartHostingView;
Il CPTGraphHostingView è semplicemente un UIView che è responsabile per contenere il grafico e consentire l'interazione dell'utente (che tratteremo in un tutorial successivo).
Sintetizzare il graficoHostingView e creare la vista di hosting del grafico nel metodo initWithFrame:
[self setChartHostingView: [[[CPTGraphHostingView alloc] initWithFrame: CGRectZero] autorelease]]; [self addSubview: chartHostingView];
Quanto sopra dovrebbe essere abbastanza auto esplicativo. Creiamo un CPTGraphHostingView e lo impostiamo come proprietà chartHostingVIew. Quindi lo aggiungiamo come sottoview.
Successivamente, è necessario impostare le dimensioni del frame graphView nel metodo "subviews layout":
[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: [centro auto]];
Di nuovo, tutto quanto sopra dovrebbe essere roba semplice. Prima di iniziare a lavorare sul controller, assicurati di rilasciare la proprietà 'chartHostingView' nel metodo dealloc viste se non lo hai già fatto.
La maggior parte del lavoro che faremo ora sarà nel controller. Aprire STLineGraphViewController.h e aggiungere le seguenti dichiarazioni di proprietà:
@interface STLineGraphViewController: UIViewController@property (nonatomic, strong) grafico CPTGraph *; @property (nonatomic, assegna) id delegare; @property (nonatomic, strong) NSManagedObjectContext * managedObjectContext;
Il CPTGraph è una classe astratta che è responsabile del disegno degli elementi del grafico e della gestione dei diversi grafici. È anche responsabile dell'applicazione dei temi, del ricaricamento dei dati del grafico e molto altro! Stiamo anche indicando che ci conformeremo ai protocolli CPTScatterPlotDataSource e CPTScatterPlotDelegate.
Abbiamo anche bisogno di aggiungere un nostro protocollo in modo che la vista modale possa essere ignorata. Inserisci il seguente codice sopra la dichiarazione dell'interfaccia:
@protocol STLineGraphViewControllerDelegate @required - (void) doneButtonWasTapped: (id) sender; @fine
Passare al file * .m e sintetizzare il grafico e delegare le proprietà. Una volta fatto, aggiungi il seguente codice prima del metodo 'viewDidLoad':
[self setView: [[[STLineGraphView alloc] initWithFrame: self.view.frame] autorelease]]; CPTTheme * defaultTheme = [CPTTheme themeNamed: kCPTPlainWhiteTheme]; [self setGraph: (CPTGraph *) [defaultTheme newGraph]]; [defaultTheme release];
Ci sono alcune cose in questa sezione. Innanzitutto, stiamo creando e impostando la vista del controller come nostro STLineGraphView personalizzato. Successivamente, creiamo un oggetto 'CPTTheme'. L'oggetto CPTTheme gestisce lo stile di un grafico con stili di linea, stile del testo e eventuali riempimenti richiesti. Un modo semplice per ottenere un CPTGraph preconfigurato con un CPTTheme di base è creare il CPTTheme con uno dei nomi di temi predefiniti e quindi utilizzare il metodo "newGraph" per darci un grafico con esso.
Successivamente, inseriremo il codice seguente nel metodo "viewDidLoad":
[super viewDidLoad]; STLineGraphView * graphView = (STLineGraphView *) [visualizzazione automatica]; [[auto grafico] setDelegate: self]; [[graphView chartHostingView] setHostedGraph: [grafico autonomo]]; CPTScatterPlot * studentScatterPlot = [[CPTScatterPlot alloc] initWithFrame: [limiti del grafico]]; [studentScatterPlot setIdentifier: @ "studentEnrollment"]; [studentScatterPlot setDelegate: self]; [studentScatterPlot setDataSource: self]; [[auto grafico] 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 animato: NO]; [self.view addSubview: navigationBar]; [navigationItem setRightBarButtonItem: [[[UIBarButtonItem alloc] initWithTitle: @ Stile "Done": UIBarButtonItemStyleDone target: [self delegate] action: @selector (doneButtonWasTapped :)] autorelease] animato: NO];
Nel codice precedente stiamo ottenendo il nostro punto di vista e impostando il grafico ospitato per la vista di visualizzazione del grafico delle visualizzazioni sul nostro oggetto grafico. Quindi creiamo una "trama" da inserire nel grafico. Usiamo il 'CPTScatterPlot' quando vogliamo creare un grafico a linee. L'identificatore è qualcosa che possiamo usare per identificare la trama in seguito. Quindi impostiamo il delegato e l'origine dati nella classe controller in quanto sarà responsabile della fornitura dei dati per il grafico. Infine, aggiungiamo la trama appena creata del grafico.
Dopo aver lavorato con il grafico, creiamo un elemento di navigazione e una barra per il controller della vista modale per visualizzare un titolo e un pulsante eseguito che li riporterà alla vista originale.
Prova a eseguire il progetto ora e vai al grafico a linee. Dovresti vedere qualcosa di simile al seguente:
Abbiamo l'inizio di un grafico! Ora per aggiungere alcuni dati:
I grafici in CorePlot utilizzano due metodi di origine dati principali per ottenere dati, 'numberOfRecordsForPlot' e 'numberForPlot: campo: recordIndex:'. È molto simile a come funzionano le visualizzazioni delle tabelle. Per prima cosa, vogliamo specificare il numero di record per la trama:
- (NSUInteger) numberOfRecordsForPlot: (CPTPlot *) plot return 8;
Stiamo mostrando quante iscrizioni si sono verificate ogni giorno della settimana. Poiché ci sono 7 giorni possibili in cui lo studente potrebbe iscriversi, abbiamo 8 record totali (perché iniziamo da 0).
Ora vogliamo specificare quale dovrebbe essere il valore xey per ogni record:
- (NSNumber *) numberForPlot: (CPTPlot *) campo di trama: (NSUInteger) fieldEnum recordIndex: (NSUInteger) index NSUInteger x = index; NSU intero y = 0; Errore NSError *; NSFetchRequest * fetchRequest = [[NSFetchRequest alloc] init]; NSEntityDescription * entity = [NSEntityDescription entityForName: @ "STStudent" inManagedObjectContext: managedObjectContext]; NSPredicate * predicate = [NSPredicate predicateWithFormat: @ "dayEnrolled ==% d", index]; [fetchRequest setEntity: entity]; [fetchRequest setPredicate: predicate]; y = [managedObjectContext countForFetchRequest: fetchRequest error: & error]; [versione fetchRequest]; switch (fieldEnum) case CPTScatterPlotFieldX: NSLog (@ "valore x per% d è% d", indice, x); return [NSNumber numberWithInt: x]; rompere; case CPTScatterPlotFieldY: NSLog (@ "valore y per% d è% d", index, y); return [NSNumber numberWithInt: y]; rompere; default: break; return nil;
C'è un bel po 'succedendo sopra. Questo metodo deve specificare un valore xey per un determinato indice e quale valore viene restituito basato sul valore "fieldEnum" (che nel nostro caso è CPTScatterPlotFieldX o CPTScatterPlotFieldY). L'indice indica il record che sta per tracciare sul grafico e la trama si riferisce al grafico reale che sta visualizzando i dati. Quando abbiamo un controller che gestisce più di un grafico, possiamo esaminare l'identificatore di trama per determinare quale set di dati fornire (copriamo questo processo in un tutorial successivo).
Trovo più facile specificare un valore "x" e "y" all'inizio del metodo, elaborando entrambi i valori e quindi basato sull'enumerazione del campo che restituisce quella corretta sotto forma di un NSNumber (che è il formato che corePlot lo richiede in).
Il valore x è facile da capire. Mentre visualizza i giorni di iscrizione, x è uguale all'indice corrente. Il valore y sarà il conteggio di tutti gli studenti iscritti in quel giorno. Possiamo ottenere questo facendo una chiamata al nostro archivio dati principale e cercando tutti i record STStudent con un valore "dayEnrolled" dell'indice. Se non hai familiarità con i dati di base e non capisci tutto quello che sta succedendo non essere troppo preoccupato, per ora va bene che funzioni. Concentrati sull'apprendimento di una cosa alla volta!
Se salvi ed esegui l'applicazione ora, non visualizzerai nulla sul grafico, ma dovresti vedere il seguente output nella tua console:
Ciò significa che il grafico sta ottenendo i valori corretti per x e y (assicurati che sia uguale o simile all'output nell'immagine.) Tuttavia non viene ancora visualizzato sul grafico, perché se si guarda il grafico, l'intervallo visualizzato non è corretto. Stiamo osservando da -1,0 a 0 su entrambi gli assi xe y. Dobbiamo impostare l'intervallo da esaminare prima di poter vedere i punti dati.
Lo spazio trama determina molto su come il grafico viene visualizzato e formattato. Esamineremo un po 'questo tutorial e andremo molto più dettagliatamente nel prossimo.
Per impostare l'intervallo xey che l'utente guarda, è necessario lavorare con l'oggetto 'CPTXYPlotSpace'. Questo oggetto ci consente di impostare un intervallo visualizzabile per il grafico.
Vai al metodo viewDidLoad e aggiungi il seguente codice subito sotto dove aggiungiamo la trama al nostro grafico:
CPTXYPlotSpace * studentPlotSpace = (CPTXYPlotSpace *) [grafico defaultPlotSpace]; [studentPlotSpace setXRange: [CPTPlotRange plotRangeWithLocation: CPTDecimalFromInt (0) length: CPTDecimalFromInt (7)]]; [studentPlotSpace setYRange: [CPTPlotRange plotRangeWithLocation: CPTDecimalFromInt (0) length: CPTDecimalFromInt (10)]];
Per prima cosa, otteniamo un oggetto CPTXYPlotSpace dallo spazio di trama predefinito dei grafici (è richiesta una certa fusione). Quindi impostiamo semplicemente l'intervallo xey. L'intervallo è un oggetto 'CPTPlotRange' che creiamo staticamente utilizzando il metodo 'plotRangeWithLocation: length:'. Questo metodo accetta NSDecimals ma corePlot ci fornisce una funzione che possiamo usare per ottenere un decimale da un int chiamato 'CPTDecimalFromInt' (Ce n'è anche uno per float se necessario).
Ora salva ed esegui l'applicazione e dovresti vedere l'inizio del tuo primo grafico!
Abbiamo l'avvio di un grafico, ma ha bisogno di un po 'più di lavoro prima che possa essere molto utile. La prossima volta discuteremo come impostare e formattare le etichette degli assi, le linee di spunta e gli incrementi. Discuteremo anche come personalizzare l'aspetto del grafico e, infine, come aggiungere e gestire più grafici su un singolo grafico. Arrivederci alla prossima!