Travailler avec CorePlot Créer un graphique à secteurs

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!


Aussi disponible dans cette série:

  1. Travailler avec CorePlot: Configuration du projet
  2. Travailler avec CorePlot: Principes de base des parcelles
  3. Utilisation de CorePlot: Style et ajout de graphes
  4. Utilisation de CorePlot: Création d’un graphique à barres
  5. Travailler avec CorePlot: Créer un graphique à secteurs

Où nous nous sommes laissés

La dernière fois, nous avons découvert comment créer un graphique à barres, comment personnaliser les couleurs des barres et comment ajouter des étiquettes personnalisées à notre axe si nous voulons afficher du texte personnalisé au lieu de simples chiffres..


Ce que nous couvrirons aujourd'hui

Cette fois, nous verrons comment résumer la logique de notre contrôleur dans un objet source de données plus réutilisable. Une fois que nous aurons maîtrisé cela, nous verrons comment afficher les mêmes données que l'histogramme, sauf que cette fois-ci, elles seront affichées sous forme de camembert!


Étape 1: Mise en place

Avant de commencer à résumer la logique des données, nous allons créer nos classes de base pour le graphique à secteurs. Comme la dernière fois, nous devrons créer un nouveau contrôleur de vue pour le graphique. Appelons-le 'STPieGraphViewController'.


Notez que nous n'avons pas besoin de créer une vue cette fois car nous pourrons utiliser 'STGraphView'. Avant de commencer à configurer, sautons dans STStudentListViewController.h et importons STPieGraphViewController.h. Nous devons également nous conformer au protocole STPieGraphViewControllerDelegate (que nous créerons plus tard):

 @interface STStudentListViewController: UIViewController 

Basculez vers le fichier .m. Nous devons ajouter un bouton à la fiche d'action. Localisez la méthode graphButtonWasSelected:. Nous allons éditer le texte du deuxième bouton et en ajouter un troisième:

 - (void) graphButtonWasSelected: (id) expéditeur UIActionSheet * graphSelectionActionSheet = [[[UIActionSheet alloc] initWithTitle: @ "Choisissez un graphique" délégué: auto cancelButtonTitle: @ "Cancel" destructiveButtonTitle: nil otherButtonTitles: "Total des objets - Bar", @ "Total des objets - Pie", nil] autorelease]; [graphSelectionActionSheet showInView: [[UIApplication sharedApplication] keyWindow]]; 

Maintenant, sautez dans la méthode actionSheet: clickedButtonAtIndex: et ajoutez une clause pour buttonIndex == 2:

 else if (buttonIndex == 2) STPieGraphViewController * graphVC = [[STPieGraphViewController alloc] init]; [graphVC setModalTransitionStyle: UIModalTransitionStyleFlipHorizontal]; [graphVC setModalPresentationStyle: UIModalPresentationFullScreen]; [graphVC setDelegate: self]; [graphVC setManagedObjectContext: [auto managedObjectContext]]; [self presentModalViewController: graphVC animated: YES]; [version graphVC]; 

Comme la dernière fois, il affichera des avertissements, car STPieGraphViewController ne possède pas de propriété delegate ou managedObjectContext..

Alors sautez dans STPieGraphViewController.h. Importez 'CorePlot-CocoaTouch.h' et ajoutez les propriétés et déclarations de protocole suivantes:

 @protocol STPieGraphViewControllerDelegate @required - (void) doneButtonWasTapped: (id) expéditeur; @end @interface STPieGraphViewController: UIViewController  @property (nonatomic, strong) graphique CPTGraph *; @property (nonatomic, assign) id déléguer; @property (nonatomic, strong) NSManagedObjectContext * managedObjectContext; @fin

Il est important de souligner que nous ne nous conformons pas à CPTPieChartDataSource pour le moment. En effet, nous allons résumer la logique des données graphiques de STBarGraphViewController dans une classe distincte DataSource. Avant de faire cela, finissons de tout configurer. Dans le fichier .m, importez 'STGraphView.h', synthétisez les propriétés et implémentez la méthode dealloc.

Enfin, configurez les méthodes loadView et viewDidLoad comme ci-dessous:

 - (void) loadView [super loadView]; [self setTitle: @ "Inscription par sujet"]; [auto setView: [[[[STGraphView alloc]] initWithFrame: self.view.frame] autorelease]]; CPTTheme * defaultTheme = [CPTTheme themeNamed: kCPTPlainWhiteTheme]; [self setGraph: (CPTGraph *) [defaultTheme newGraph]];  - (void) viewDidLoad [super viewDidLoad]; STGraphView * graphView = (STGraphView *) [vue autonome]; [[graphView chartHostingView] setHostedGraph: [graphique auto]]; // Permettre à l'utilisateur de revenir en arrière UINavigationItem * navigationItem = [[[UINavigationItem alloc]] initWithTitle: self.title] autorelease]; [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]; 

Ce qui précède devrait être familier maintenant. Voyons donc comment résumer la logique des graphes en une classe séparée.


Étape 2: séparation de la logique graphique

Nous avons déjà écrit la logique pour obtenir des données sur le nombre total d'étudiants dans toutes les matières; nous ne voulons pas avoir à l'écrire à nouveau, heureusement, nous n'avons pas à le faire. Tous les protocoles de source de données pour les tracés hérités de 'CPTPlotDataSource', et c'est ce protocole qui contient les méthodes numberOfRecordsForPlot: et numberForPlot: fieldEnum: recordIndex.

Créez une classe appelée 'STAbstractSubjectDataSource.h' (héritant de NSObject) dans un nouveau groupe appelé 'DataSource' dans le groupe graphique. Pour le fichier d'en-tête, importez 'CorePlot-CocoaTouch.h' et insérez les propriétés et déclarations de méthode suivantes:

 @interface STAbstractSubjectEnrollementDataSource: NSObject  @property (nonatomic, strong) NSManagedObjectContext * managedObjectContext; - (id) initWithManagedObjectContext: (NSManagedObjectContext *) aManagedObjectContext; - (float) getTotalSubjects; - (float) getMaxEnrolled; - (NSArray *) getSubjectTitlesAsArray; @fin

Nous sommes abonnés au protocole 'CPTPlotDataSource'. Nous créons une méthode d'init personnalisée qui passe par un managedObjectContext afin que l'objet puisse accéder au magasin de données. Enfin, trois méthodes auxiliaires peuvent vous aider à obtenir des informations sur les sujets et les inscriptions. Ce sont les mêmes méthodes qui existent actuellement dans STBarGraphViewController. Nous allons déplacer ceux-ci dans la méthode de source de données.

À part la méthode init, le fichier .m ne contient aucun nouveau code que vous n'avez pas vu auparavant. Il suffit de déplacer tout le code existant de STBarGraphViewController dans l'objet dataSource. Les méthodes que vous devez déplacer sont les suivantes:

  • (float) getTotalSubjects
  • (float) getMaxEnrolled
  • (NSArray *) getSubjectTitlesAsArray
  • (NSUInteger) numberOfRecordsForPlot: tracé (CPTPlot *)
  • (NSNumber *) numberForPlot: (CPTPlot *) champ de tracé: (NSUInteger) fieldEnum recordIndex: (NSUInteger) index

Assurez-vous également que vous ajoutez la méthode init personnalisée:

 - (id) initWithManagedObjectContext: (NSManagedObjectContext *) aManagedObjectContext self = [super init]; if (self) [self setManagedObjectContext: aManagedObjectContext];  retourner soi-même; 

Nous avons maintenant un objet de source de données qui peut fournir les données de base à la fois pour le graphique en secteurs et le graphique à barres. La source de données abstraite ne nous donne pas tout ce dont nous avons besoin, cependant, barFillForBarPlot: recordIndex ne peut pas être implémenté car il fait partie de CPTBarPlotDataSource. Nous allons devoir étendre notre classe abstraite à quelque chose de spécifique pour les parcelles à barres.

Créez un nouvel objet dans le groupe de sources de données appelé 'STBarGraphSubjectEnrollementDataSource' qui étend notre classe abstraite. Dans l'en-tête, abonnez-vous à 'CPTBarPlotDataSource:

 - (id) initWithManagedObjectContext: (NSManagedObjectContext *) aManagedObjectContext @interface STBarGraphSubjectEnrollementDataSource: STAbstractSubjectEnrollementDataSource 

Et dans le fichier .m, implémentez la méthode barFillForBarPlot:

 #pragma mark - Méthodes CPTBarPlotDataSource - (CPTFill *) barFillForBarPlot: (CPTBarPlot *) barPlot recordIndex: (NSUInteger) index CPTColor * areaColor = nil; commutateur (index) cas 0: areaColor = [CPTColor redColor]; Pause; cas 1: areaColor = [CPTColor blueColor]; Pause; cas 2: areaColor = [CPTColor orangeColor]; Pause; cas 3: areaColor = [CPTColor greenColor]; Pause; default: areaColor = [CPTColor purpleColor]; Pause;  CPTFill * barFill = [CPTFill fillWithColor: areaColor]; retour barFill; 

Retournez maintenant dans votre fichier d'en-tête STBarGraphViewControllers et importez la nouvelle source de données de graphique à barres. Vous pouvez maintenant supprimer l'abonnement 'CPTBarPlotDataSource'. Accédez au fichier .m et supprimez toutes les méthodes sauf loadView, viewDidLoad et dealloc. Nous n'en avons plus besoin.

Nous devons maintenir un pointeur sur la source de données, puis le relâcher lorsque la vue est terminée. Dans l'interface privée, déclarez la propriété, puis synthétisez:

 @interface STBarGraphViewController () @property (nonatomic, keep) STBarGraphSubjectEnrollementDataSource * barGraphDataSource; @end @implementation STBarGraphViewController @synthesize delegate; @synthesize managedObjectContext; @synthèse graphique; @synthesize barGraphDataSource;

Assurez-vous de le libérer également dans la méthode dealloc. Créez une nouvelle instance et définissez-la comme notre propriété dans la méthode loadView:

 [self setBarGraphDataSource: [[[[STBarGraphSubjectEnrollementDataSource alloc] all]] initWithManagedObjectContext: [auto managedObjectContext]] autorelease]];

Maintenant, dans la méthode viewDidLoad, nous devons utiliser les méthodes d'assistance de notre source de données pour calculer l'espace de traçage et les étiquettes personnalisées:

 CPTXYPlotSpace * studentPlotSpace = (CPTXYPlotSpace *) [graph defaultPlotSpace]; [studentPlotSpace setXRange: [CPTPlotRange plotRangeWithLocation: CPTDecimalFromInt (0) longueur: CPTDecimalFromInt ([[auto barGraphDataSource] getTotalSubjects]] + 1)]; [studentPlotSpace setYRange: [CPTPlotRange plotRangeWithLocation: CPTDecimalFromInt (0) longueur: CPTDecimalFromInt ([[auto barGraphDataSource] getMaxEnrolled] + 1)]];
 NSArray * subjectArray = [[self barGraphDataSource] getSubjectTitlesAsArray];

Enregistrez, construisez et exécutez. Tout devrait fonctionner comme avant. Si c'est le cas, nous pouvons commencer à créer notre graphique à secteurs.!


Étape 3: Création du graphique à secteurs

Nous voudrons créer une source de données spécifique pour le graphique à secteurs exactement comme nous l'avons fait pour le graphique à barres au cas où nous aurions besoin d'implémenter des méthodes de source de données spécifiques aux graphiques à secteurs. Créez une classe appelée 'STPieGraphSubjectEnrollementDataSource' qui hérite de 'STAbstractSubjectEnrollementDataSource'. Dans le fichier d'en-tête, abonnez-vous au protocole 'CPTPieChartDataSource'. Nous n'implémenterons pas encore de méthodes de source de données à secteurs spécifiques, nous y reviendrons plus tard..

Maintenant que nous avons des sources de données, la création du graphique à secteurs est simple! Accédez à STBPieGraphViewController.m et importez l'objet de source de données de graphique à secteurs. Déclarez-le comme une propriété du fichier .m, comme nous l'avions fait la dernière fois:

 @interface STPieGraphViewController () @property (nonatomic, strong) STPieGraphSubjectEnrollementDataSource * pieChartDataSource; @end @implementation STPieGraphViewController @synthesize managedObjectContext; @synthesize delegate; @synthèse graphique; @synthesize pieChartDataSource;

Maintenant, créez et configurez-le dans le loadView:

 [self setPieChartDataSource: [[[[STPieGraphSubjectEnrollementDataSource alloc] all]] initWithManagedObjectContext: [auto managedObjectContext]] autorelease]];

Enfin, dans la méthode viewDidLoad, nous devons créer notre graphique à secteurs, l'ajouter à notre GraphView et supprimer l'axe standard:

 STGraphView * graphView = (STGraphView *) [vue autonome]; [[graphView chartHostingView] setHostedGraph: [graphique auto]]; CPTPieChart * pieChart = [[CPTPieChart alloc]] initWithFrame: [graph bounds]]; [pieChart setPieRadius: 100,00]; [pieChart setIdentifier: @ "Subject"]; [pieChart setStartAngle: M_PI_4]; [pieChart setSliceDirection: CPTPieDirectionCounterClockwise]; [pieChart setDataSource: pieChartDataSource]; [graph addPlot: pieChart]; [graph setAxisSet: nil]; [graph setBorderLineStyle: nil];

La plupart de ce qui précède devrait sembler familier. Notez que ce n’est pas explicitement appelé un "tracé" car il ne repose pas sur un axe des x ou des y, mais nous le traitons toujours de la même manière. Nous faisons également certaines choses spécifiques aux graphiques à secteurs. Nous créons un rayon et un angle de départ. Nous définissons également une direction de tranche. Enfin, nous définissons le 'axisSet' du graphique sur nil pour ne pas obtenir les lignes x et y.

Et cela devrait être tout. Construire et exécuter pour voir votre graphique à secteurs.


C'est bien, mais cela pourrait donner une sorte d'indication quant à ce que chaque couleur représente. Une bonne façon de faire est d'utiliser des légendes. Pour ce faire, nous créons un objet 'CPTLegend' que nous ajoutons à notre graphique et implémentons une méthode déléguée qui renvoie le titre approprié pour la légende..

Créons d'abord l'objet CPTLegend. Dans notre méthode viewDidLoad, entrez le code suivant sous lequel nous créons notre graphique à secteurs:

 CPTLegend * theLegend = [CPTLegend legendWithGraph: [graphique auto]]; [theLegend setNumberOfColumns: 2]; [[self graph]] setLegend: theLegend]; [[self graphique] setLegendAnchor: CPTRectAnchorBottom]; [[graphique personnel] setLegendDisplacement: CGPointMake (0.0, 30.0)];

Cela crée une légende et l'ajoute à notre objet graphique. Le nombre de colonnes détermine la disposition des titres de légende. Nous définissons ensuite certains attributs sur l'objet graphique qui déterminent l'emplacement de la légende (en bas) et un déplacement pour garantir son affichage complet dans la vue..

Nous devons toutefois fournir à la légende des titres. Il existe une méthode spécifique à CPTPieChartDataSource qui nous permet de le faire. Accédez à la source de données du graphique à secteurs et implémentez le code suivant:

 #pragma mark - CPTPieChartDataSource - (NSString *) legendTitleForPieChart: (CPTPieChart *) pieChart recordIndex: (NSUInteger) index NSError * error = nil; NSFetchRequest * request = [[NSFetchRequest alloc] init]; NSEntityDescription * entity = [NSEntityDescription entityForName: @ "STSubject" inManagedObjectContext: [self managedObjectContext]]; NSPredicate * predicate = [NSPredicate predicateWithFormat: @ "subjectID ==% d", index]; [request setEntity: entité]; [request setResultType: NSDictionaryResultType]; [request setPredicate: predicate]; [request setReturnsDistinctResults: NO]; [request setPropertiesToFetch: [NSArray arrayWithObject: @ "subjectName"]]; NSArray * titleStrings = [[autoGenuObjetContext] executeFetchRequest: erreur de requête: & erreur]; NSDictionary * fetchedSubject = [titleStrings objectAtIndex: 0]; return [fetchedSubject objectForKey: @ "subjectName"]; 

Cette méthode obtient simplement l'index de la légende, le titre du magasin de données sous forme de chaîne et le renvoie..

Construire et exécuter et vous devriez avoir un graphique à secteurs informatif!



Emballer

Nous avons expliqué comment résumer la logique de données du contrôleur dans un objet distinct, plus facile à gérer et à étendre. Nous avons également abordé les bases de la création d'un graphique à secteurs..

Cela nous amène à la fin de la série. J'espère que vous avez trouvé ces tutoriels utiles. CorePlot peut faire beaucoup plus, mais cela devrait vous donner une base solide sur laquelle bâtir. Bonne chance pour ajouter des graphiques à vos propres projets!