Lorsqu'il travaille avec des applications gourmandes en données, un développeur doit souvent faire plus que simplement afficher des listes d'enregistrements de données dans une vue sous forme de tableau. La bibliothèque CorePlot vous permettra d’ajouter de superbes visualisations de données à vos applications. Découvrez comment dans cette série Tuts + Premium!
La dernière fois que nous avons présenté le cadre CorePlot, nous avons discuté de ce qu’il peut faire et de la façon dont nous pouvons l’utiliser pour améliorer la visualisation des données dans nos applications. Nous avons également exploré l'exemple d'application que nous allons créer dans la série et comment ajouter CorePlot à notre application. Pour obtenir un instantané du code de l'endroit où nous nous étions arrêtés la dernière fois, téléchargez le code source de ce tutoriel (sinon, n'hésitez pas à utiliser votre base de code existante et à économiser du temps de téléchargement!).
Avant de créer un graphique, nous avons besoin d'une vue pour le faire. Nous allons permettre à l'utilisateur de cliquer sur un UIBarButtonItem dans l'onglet "Etudiants" qui affichera une feuille d'action contenant une liste de graphiques pour le utilisateur à choisir. Une fois la sélection effectuée, une vue modale affiche un graphique avec les données pertinentes..
Nous allons créer un nouveau groupe appelé "Graphing" sous le groupe "StudentTracker". Créez un groupe "Vues" et "Contrôleurs" en dessous, comme dans "Liste des étudiants" et "Liste des sujets"..
Créez une nouvelle classe appelée 'STLineGraphViewController' (sous-classe UIViewController) dans le groupe 'View Controllers'. Lorsque vous choisissez où ajouter les fichiers, le meilleur endroit pour les placer est le dossier 'Classes / Graphing / View Controllers' (vous devrez créer le répertoire 'Graphing / View Controllers')..
Nous allons revenir et travailler sur la personnalisation plus tard. À l'heure actuelle, nous allons implémenter ce code qui permet à l'utilisateur de sélectionner un graphique à regarder.
Commencez par ouvrir STStudentListViewController.h et ajoutez les déclarations de protocole 'UIActionSheetDelegate' et 'STLineGraphViewControllerDelegate'. Ce protocole n'existe pas encore mais nous le créerons plus tard (Veillez également à importer le fichier 'STLineGraphViewController.h').
@interface STStudentListViewController: UIViewController
Ensuite, ouvrez le fichier .m et implémentez la méthode 'actionSheet: clickedButtonAtIndex:' avec le code suivant:
- (void) actionSheet: (UIActionSheet *) actionSheet a cliqué surButtonAtIndex: (NSInteger) buttonIndex if (buttonIndex == 0) STLineGraphViewController * lineGraphVC = [[STLineGraphViewController alloc] init]; [lineGraphVC setModalTransitionStyle: UIModalTransitionStyleFlipHorizontal]; [lineGraphVC setDelegate: self]; [lineGraphVC setManagedObjectContext: [auto managedObjectContext]]; [self presentModalViewController: lineGraphVC animated: YES]; [lineGraphVC release];
Ce code ne devrait pas nécessiter trop d'explications. Nous créons simplement un contrôleur de vue LineGraph et le présentons sous forme modale. Nous nous sommes fixés comme délégué pour savoir quand rejeter la vue modale. Nous donnons également au contrôleur de vue un contexte d'objet géré avec lequel il peut travailler en interface avec les données principales. Ces deux dernières méthodes créeront un avertissement (ou une erreur si vous utilisez ARC) car les propriétés n'existent pas encore, mais nous les créerons plus tard..
Nous allons ensuite créer une méthode pour appeler la feuille d’action et ajouter un UITabBarItem pour l’appeler. Ajoutez une déclaration de méthode dans l'interface .m appelée 'graphButtonWasSelected:':
@interface STStudentListViewController () @property (nonatomic, strong) NSArray * studentArray; - (void) addStudent: (id) expéditeur; - (void) graphButtonWasSelected: (id) sender; @fin
Ensuite, ajoutez l'implémentation de la méthode:
- (void) graphButtonWasSelected: (id) expéditeur UIActionSheet * graphSelectionActionSheet = [[[UIActionSheet alloc] initWithTitle: @ "Choisissez un graphique" délégué: self cancelButtonTitle: @ "Cancel" destructiveButtonTitle: nil otherButtonTitles: ] autorelease]; [graphSelectionActionSheet showInView: [[UIApplication sharedApplication] keyWindow]];
Ensuite, nous devons ajouter un UIBarButtonItem pour que l’utilisateur puisse sélectionner quand il veut voir le graphique. Nous ferons cela dans la méthode viewDidLoad ci-dessous, où nous créons l'élément de bouton de barre de droite:
[[auto navigationItem] setLeftBarButtonItem: [[[[UIBarButtonItem alloc]] initWithTitle: @ style "Graphs": UIBarButtonItemStylePlain cible: auto action: @selector (graphButtonWasSelected :)] autorelease: animated: NO;
Enfin, nous devons implémenter une méthode de protocole STLineGraphViewController qui indiquera au contrôleur de rejeter la vue modale lorsque l'utilisateur a terminé d'examiner le graphique:
- (void) doneButtonWasTapped: (id) expéditeur [auto-licenciementModalViewControllerAnimated: YES];
Maintenant, nous sommes prêts à commencer à créer le graphique!
Nous devons d’abord créer une classe de vue personnalisée pour notre LineGraphViewController. Dans le groupe Graphing> Views, créez une nouvelle classe qui étend UIView et s'appelle 'STLineGraphView' (assurez-vous de la placer dans le bon dossier lorsque vous choisissez l'emplacement où elle sera enregistrée sur le système de fichiers)..
Nous allons définir les aspects graphiques de la vue dans la classe de vue. Allez d'abord dans le fichier .h et (après avoir importé le fichier "CorePlot-CocoaTouch.h") et ajoutez la déclaration de propriété suivante:
@property (nonatomic, strong) CPTGraphHostingView * chartHostingView;
CPTGraphHostingView est simplement un UIView responsable de contenir le graphe et de permettre l’interaction de l’utilisateur (ce que nous verrons dans un prochain tutoriel)..
Synthétisez le chartHostingView et créez la vue d'hébergement du graphique dans la méthode initWithFrame:
[self setChartHostingView: [[[[[CPTGraphHostingView alloc]] initWithFrame: CGRectZero] autorelease]]; [auto addSubview: chartHostingView];
Ce qui précède devrait être assez explicite. Nous créons un CPTGraphHostingView et le définissons comme notre propriété chartHostingVIew. Nous l'ajoutons ensuite en tant que sous-vue.
Ensuite, nous devons définir les dimensions du cadre graphViews dans la méthode 'layout subviews':
[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: [centre auto]]];
Encore une fois, tout ce qui précède devrait être simple. Avant de commencer à travailler sur le contrôleur, assurez-vous de bien libérer la propriété 'chartHostingView' dans la méthode dealloc de vues si vous ne l'avez pas encore fait..
La majeure partie du travail que nous allons faire maintenant sera dans le contrôleur. Ouvrez STLineGraphViewController.h et ajoutez les déclarations de propriété suivantes:
@interface STLineGraphViewController: UIViewController@property (nonatomic, strong) graphique CPTGraph *; @property (nonatomic, assign) id déléguer; @property (nonatomic, strong) NSManagedObjectContext * managedObjectContext;
CPTGraph est une classe abstraite chargée de dessiner les éléments graphiques et de gérer les différents graphiques. Il est également responsable de l'application des thèmes, du rechargement des données du graphique, et bien plus encore! Nous indiquons également que nous nous conformerons aux protocoles CPTScatterPlotDataSource et CPTScatterPlotDelegate..
Nous devons également ajouter notre propre protocole afin que la vue modale puisse être rejetée. Placez le code suivant au-dessus de la déclaration d'interface:
@protocol STLineGraphViewControllerDelegate @required - (void) doneButtonWasTapped: (id) expéditeur; @fin
Basculez vers le fichier * .m, synthétisez le graphique et déléguez les propriétés. Ceci fait, ajoutez le code suivant avant la méthode 'viewDidLoad':
[self setView: [[[[STLineGraphView alloc]] initWithFrame: self.view.frame] autorelease]]; CPTTheme * defaultTheme = [CPTTheme themeNamed: kCPTPlainWhiteTheme]; [self setGraph: (CPTGraph *) [defaultTheme newGraph]]; [releaseTheme par défaut];
Il y a quelques choses qui se passent dans cette section. Tout d'abord, nous créons et définissons la vue du contrôleur en tant que notre STLineGraphView personnalisé. Ensuite, nous créons un objet 'CPTTheme'. L'objet CPTTheme gère le style d'un graphique avec les styles de ligne, de style de texte et les remplissages requis. Un moyen simple d'obtenir un CPTGraph préconfiguré avec un CPTTheme de base consiste à créer le CPTTheme avec l'un des noms de thème prédéfinis, puis à utiliser la méthode 'newGraph' pour nous donner un graphique stylé avec ce dernier..
Ensuite, nous allons mettre le code suivant dans la méthode 'viewDidLoad':
[super viewDidLoad]; STLineGraphView * graphView = (STLineGraphView *) [vue autonome]; [[self graphique] setDelegate: self]; [[graphView chartHostingView] setHostedGraph: [graphique auto]]; CPTScatterPlot * studentScatterPlot = [[CPTScatterPlot alloc] initWithFrame: [graph bounds]]; [studentScatterPlot setIdentifier: @ "studentEnrollment"]; [studentScatterPlot setDelegate: self]; [studentScatterPlot setDataSource: self]; [[auto graphique] 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]; [auto.view addSubview: navigationBar]; [navigationItem setRightBarButtonItem: [[[[UIBarButtonItem alloc]] initWithTitle: @ style "fait: UIBarButtonItemStyleDone target: action auto-déléguée: @secteur (doneButtonWasTapped :)] auto-animée: non];
Dans le code ci-dessus, nous obtenons notre vue et définissons le graphique hébergé pour la vue d'hébergement du graphique de vues dans notre objet graphique. Nous créons ensuite un «tracé» à mettre sur le graphique. Nous utilisons le 'CPTScatterPlot' lorsque nous voulons créer un graphique linéaire. L'identifiant est quelque chose que nous pouvons utiliser pour identifier l'intrigue plus tard. Nous définissons ensuite le délégué et la source de données sur la classe de contrôleur, car elle sera chargée de fournir les données pour le graphique. Enfin, nous ajoutons le graphique nouvellement créé du graphe.
Après avoir travaillé avec le graphique, nous créons un élément de navigation et une barre pour que le contrôleur de vue modale affiche un titre et un bouton Terminé qui les ramène à la vue d'origine..
Essayez d'exécuter le projet maintenant et d'aller au graphique linéaire. Vous devriez voir quelque chose comme ce qui suit:
Nous avons le début d'un graphique! Maintenant, ajoutez quelques données:
Les parcelles dans CorePlot utilisent deux méthodes principales de source de données pour obtenir des données, 'numberOfRecordsForPlot' et 'numberForPlot: field: recordIndex:'. Cela ressemble beaucoup au fonctionnement des vues de table. Tout d'abord, nous voulons spécifier le nombre d'enregistrements pour le tracé:
- (NSUInteger) numberOfRecordsForPlot: (CPTPlot *) plot return 8;
Nous montrons combien d'inscriptions ont eu lieu chaque jour de la semaine. Puisqu'il y a 7 jours possibles où l'élève aurait pu s'inscrire, nous avons 8 enregistrements au total (car nous commençons à 0).
Maintenant, nous voulons spécifier ce que devraient être les valeurs x et y pour chaque enregistrement:
- (NSNumber *) numberForPlot: (CPTPlot *) champ de tracé: (NSUInteger) fieldEnum recordIndex: (NSUInteger) index NSUInteger x = index; NSUInteger y = 0; NSError * error; NSFetchRequest * fetchRequest = [[NSFetchRequest alloc] init]; NSEntityDescription * entity = [NSEntityDescription entityForName: @ "STStudent" inManagedObjectContext: managedObjectContext]; NSPredicate * predicate = [NSPredicate predicateWithFormat: @ "dayEnrolled ==% d", index]; [fetchRequest setEntity: entité]; [fetchRequest setPredicate: predicate]; y = [managedObjectContext countForFetchRequest: erreur fetchRequest: & error]; [version fetchRequest]; switch (fieldEnum) case CPTScatterPlotFieldX: NSLog (@ "la valeur x pour% d est% d", index, x); return [NSNumber numberWithInt: x]; Pause; case CPTScatterPlotFieldY: NSLog (@ "la valeur de y pour% d est% d", index, y); return [NSNumber numberWithInt: y]; Pause; défaut: break; return nil;
Il y a pas mal de choses qui se passent ci-dessus. Cette méthode doit spécifier une valeur x et y pour un index donné et la valeur renvoyée est basée sur la valeur 'fieldEnum' (qui, dans notre cas, est CPTScatterPlotFieldX ou CPTScatterPlotFieldY). L'index indique l'enregistrement qu'il est sur le point de tracer sur le graphique et le tracé fait référence au tracé réel qui affiche les données. Lorsqu'un contrôleur gère plus d'un tracé, nous pouvons examiner l'identificateur de tracé pour déterminer le jeu de données à fournir (nous couvrirons ce processus dans un didacticiel ultérieur)..
Je trouve plus facile de spécifier une valeur 'x' et 'y' au début de la méthode, en travaillant sur les deux valeurs, puis en se basant sur le champ enum renvoyant la valeur correcte sous la forme d'un NSNumber (qui est le format corePlot en a besoin).
La valeur x est facile à comprendre. Comme il affiche les jours d'inscription, x est égal à l'index actuel. La valeur y sera le nombre total d'étudiants inscrits ce jour-là. Nous pouvons l'obtenir en appelant notre magasin de données principal et en recherchant tous les enregistrements STStudent avec une valeur "dayEnrolled" de l'index. Si vous ne connaissez pas les données de base et que vous ne comprenez pas tout ce qui se passe, ne vous inquiétez pas trop, pour l'instant, il est normal que cela fonctionne. Concentrez-vous sur l'apprentissage une chose à la fois!
Si vous enregistrez et exécutez votre application maintenant, rien ne s'affiche toujours sur le graphique, mais vous devriez voir le résultat suivant dans votre console:
Cela signifie que le graphique obtient les valeurs correctes pour x et y (assurez-vous qu'il est identique ou similaire à la sortie dans l'image. Il ne s'affiche toujours pas sur le graphique, car si vous regardez le graphique, La plage affichée est incorrecte. Nous examinons les valeurs de -1.0 à 0 sur les axes x et Y. Nous devons définir la plage à examiner avant de voir les points de données..
L'espace du tracé détermine en grande partie la manière dont le graphique est visualisé et mis en forme. Nous allons couvrir un peu ce tutoriel et entrer plus en détail dans le prochain.
Pour définir la plage x et y que l'utilisateur consulte, nous devons travailler avec l'objet 'CPTXYPlotSpace'. Cet objet nous permet de définir une plage visible pour le graphique..
Accédez à la méthode viewDidLoad et ajoutez le code suivant juste en dessous duquel nous ajoutons le tracé à notre graphique:
CPTXYPlotSpace * studentPlotSpace = (CPTXYPlotSpace *) [graph defaultPlotSpace]; [studentPlotSpace setXRange: [CPTPlotRange plotRangeWithLocation: CPTDecimalFromInt (0) longueur: CPTDecimalFromInt (7)]]; [studentPlotSpace setYRange: [CPTPlotRange plotRangeWithLocation: CPTDecimalFromInt (0) longueur: CPTDecimalFromInt (10)]];
Tout d'abord, nous obtenons un objet CPTXYPlotSpace à partir de l'espace de traçage par défaut des graphes (une conversion est nécessaire). Ensuite, nous définissons simplement la plage x et y. La plage est un objet 'CPTPlotRange' que nous créons statiquement à l'aide de la méthode 'plotRangeWithLocation: length:'. Cette méthode utilise NSDecimals mais corePlot nous fournit une fonction que nous pouvons utiliser pour obtenir une décimale à partir d’un int appelé "CPTDecimalFromInt" (il en existe aussi une pour float si nécessaire)..
Maintenant, enregistrez et exécutez l'application et vous devriez voir le début de votre premier graphique!
Nous avons le début d’un graphique mais il faut un peu plus de travail avant que cela puisse être très utile. La prochaine fois, nous verrons comment définir et mettre en forme les étiquettes d'axe, les lignes de graduation et les incréments. Nous allons également discuter de la personnalisation de l'apparence du graphique et, enfin, de l'ajout et de la gestion de plusieurs tracés sur un même graphique. À la prochaine!