GeckoGeek.fr

Paradigme d'un lézard

Vendredi 20 Octobre 2017

Installer et Utiliser CorePlot sur iPhone / iPad

Par Vinz le 28/11/2010 dans Apple, Programmation | 2 commentaires

Il est parfois utile de pouvoir afficher directement des graphiques sur iPhone / iPad. Cela peut être pour afficher beaucoup d’information dans un espace réduit, ou pour aider à visualiser des informations.

Installer CorePlot

L’installation de CorePlot est légèrement plus compliquée que pour d’autres librairies, et cela peut même parfois devenir plutôt pénible, surtout lorsqu’il faut compiler.

Télécharger CorePlot

Télécharger les sources complètes sur le projet Google Code. A l’heure de cet article le fichier à télécharger est l’Alpha Release 1. Cela risque bien évidemment de changer au cours du temps.

Configurer CorePlot pour le Projet

  • Dézippez le fichier et renommez le en “coreplot”.
  • Déplacez le dossier là où vous entreposez vos librairies. Il ne faut pas que cet endroit bouge car le lien avec le projet ne sera pas dynamique.
  • Dans le dossier “coreplot/Source/framework”, vous devriez avoir un projet “CorePlot-CocoaTouch.xcodeproj”. Déplacez ce fichier dans votre projet xCode (dans le dossier “Other Sources” par exemple).
  • Le fichier déplacé devrait contenir un “.a”. Déplacez ce dernier dans le dossier “Link Binary With Librairies” qui se trouve dans “Target/NOM-DU-PROJET/Link Binary With Librairies”.
  • Ouvrez la fenêtre “Target Info” en double-cliquant sur le projet dans Target. Allez dans l’onglet “General” (le plus à gauche en principe), et rajoutez la dépendance directe de CorePlot.
  • Maintenant ouvrez l’autre fenêtre de configuration : “Project Info” en double-cliquant sur le nom du projet tout en haut de la colonne. Vous devez passez à l’onglet “Build” et cherchez dans les configurations la clé “Header Search Paths” (en principe qui est vide de base pour un nouveau projet). Rajoutez-y le chemin vers votre librairie. Par exemple pour nous cela sera “$HOME/Library/SDKs/coreplot/Source/framework”, mais cela peut très bien être ~/Desktop/Librairies/path/to/dire/coreplot/Source/framework. Vérifiez avec un terminal que le chemin est le bon ! ATTENTION, veuillez à bien cocher le bouton “récursif” à coté du champ texte.
  • Toujours dans la même fenêtre, cherchez la clé “Other Linker Flags” et rajoutez-y “-all_load -ObjC”.
  • Dans votre controller, rajoutez la ligne d’import suivante : #import “CorePlot-CocoaTouch.h”
  • Et enfin pensez à rajouter le framework QuartzCore dans votre projet !

D’après quelques tests, il semblerait quasiment nécessaire que l’iOS cible soit au moins le 4.0. Sinon on se retrouve avec des erreurs de compilations plutôt incompréhensibles !

Utiliser CorePlot – Configurer votre Graph

CPPlotDataSource

Une fois CorePlot au chaud, on a qu’une seule envie, sortir une courbe ! Dans notre cas nous allons directement programmer dans un UIViewController (celui de base du projet que vous pouvez télécharger en fin du billet). Par ailleurs ce dernier doit intégrer le delegate CPPlotDataSource, donc veuillez bien à ce que dernier apparaisse dans votre header file ! De même nous utiliserons deux classes que je vous conseille d’ajouter dans votre .h :

CPLayerHostingView *graphView;
CPXYGraph *graph;

Les deux sont reliées à l’affichage graphique mais la seconde joue plus le rôle d’un Layer qu’autre chose. Votre Interface devrait donc ressembler à quelque chose comme :

@interface CorePlot_GeckoGeekViewController : UIViewController <CPPlotDataSource> {

	CPLayerHostingView *graphView;
	CPXYGraph *graph;

}

Ensuite, implémentons la méthode qui permettra d’afficher le graphique. Rendez-vous donc dans la méthode loadView du ViewController

- (void)loadView {
	
	// Alloc & Init Main View
	UIView *tmpView = [ [ UIView alloc ] initWithFrame:CGRectMake(0.0, 0.0, 320.0, 480.0-20.0) ];
	[ tmpView setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight ];
	[ tmpView setBackgroundColor:[ UIColor whiteColor ] ];
	
	// Alloc Graph View
	graphView = [ [ CPLayerHostingView alloc ] initWithFrame:CGRectMake(0.0, 0.0, 320.0, 480.0-20.0) ];
	[ tmpView addSubview:[ graphView autorelease ] ];
	
	// Set MainView
	[ self setView:[ tmpView autorelease ] ];
	
}

Pour l’instant rien de très compliqué. On créé la vue qui se chargera d’afficher les données (CPLayerHostingView) et on l’ajoute en SubView à la vue principale.

Initialisation des préférences de CorePlot

Passons maintenant à la méthode viewDidLoad où nous allons initialiser l’allure des courbes. On commence par créer l’objet CPXYGraph qui va contenir nos courbes :

// Alloc CPXYGraph
graph = [ [ CPXYGraph alloc ] initWithFrame: self.view.bounds ];
// Link between the view and the Layer
graphView.hostedLayer = graph;
// Init Padding to 0
graph.paddingLeft = 0.0;
graph.paddingTop = 0.0;
graph.paddingRight = 0.0;
graph.paddingBottom = 0.0;

Notez qu’on remet les “padding” (espace interne) à 0 pour éviter d’avoir des marges blanches internes dans notre graphique. Là encore, rien de très compliqué. Passons maintenant aux courbes que vous souhaitez voir apparaître. Il faut les déclarer une à une et par ailleurs (de préférence) les personnaliser. Voici un exemple pour UNE courbe.

// Alloc
CPScatterPlot *plot1 = [[[CPScatterPlot alloc]initWithFrame:self.view.bounds] autorelease];
// Set ID
plot1.identifier = @"Plot 1";
// Set Line Width
plot1.dataLineStyle.lineWidth = 1.0f;
// Set Line Color
plot1.dataLineStyle.lineColor = [CPColor colorWithComponentRed:255.0/255.0 green:0.0 blue:0.0 alpha:1.0];
// Set Data Source Object
plot1.dataSource = self;
// Add Plot to the graph layer
[graph addPlot:plot1];

En principe les commentaires sont assez nombreux pour vous expliquer ce que font les lignes. Il existe probablement d’autres paramètres de personnalisation. Mais pour un graphique de base, vous n’avez pas vraiment besoin d’en écrire plus. Prenez une attention particulière au paramètre “identifier” qui vous permettra d’attribuer les valeurs Y de la courbe dans une méthode “data source”. On en parle plus bas ! Répétez la même chose pour le nombre de courbe dont vous avez besoin. Ici on en créera juste une seconde afin de vous montrer un graphique avec 2 courbes.

Plages de données

On passe maintenant à une configuration un peu plus poussée qui concerne les limites d’affichage sur les axes X et Y. Il vous faut définir les plages sur lesquelles vous souhaitez voir vos courbes d’afficher. Ce n’est en effet pas dynamique selon les données que vous indiquerez. Ici on donne des valeurs fixes, mais de manière générale il est conseillé d’effectuer des min/max/moy sur vos données.

// X & Y Range
// Get Default Plot Space
CPXYPlotSpace *plotSpace = (CPXYPlotSpace *)graph.defaultPlotSpace;
// Set X Range from -10 to 10 (length = 20)
plotSpace.xRange = [CPPlotRange plotRangeWithLocation:CPDecimalFromInteger(-10) length:CPDecimalFromInteger(20)];
// Set Y Range from -5 to 5 (length = 10)
plotSpace.yRange = [CPPlotRange plotRangeWithLocation:CPDecimalFromFloat(-5.0) length:CPDecimalFromFloat(10.0)];

Préférences des axes X & Y

Il ne reste plus qu’à indiquer les préférences de chaque axe. C’est probablement le passage le plus délicat est sur lequel on revient le plus souvent au début lorsque l’on souhaite configurer l’allure de son graphique. On vous explique ligne par ligne ce que fait chaque fonction dans le code suivant.

// Line Style
CPLineStyle *lineStyle = [CPLineStyle lineStyle];
lineStyle.lineColor = [CPColor blackColor];
lineStyle.lineWidth = 1.0f;

// Axis X Prefs
CPXYAxisSet *axisSet = (CPXYAxisSet *)graph.axisSet;
// Set the "major" interval length
axisSet.xAxis.majorIntervalLength = [ [ NSDecimalNumber decimalNumberWithString:@"5.0" ] decimalValue ];
// Set the number of ticks per interval
axisSet.xAxis.minorTicksPerInterval = 4;
// Set major & minor line style
axisSet.xAxis.majorTickLineStyle = lineStyle;
axisSet.xAxis.minorTickLineStyle = lineStyle;
// Set axis line style
axisSet.xAxis.axisLineStyle = lineStyle;
// Set length of the minor tick
axisSet.xAxis.minorTickLength = 5.0f;
// Set length of the major tick
axisSet.xAxis.majorTickLength = 10.0f;
// Set the offset of the label (beside the X axis)
axisSet.xAxis.labelOffset = 3.0f;

// Axis Y Prefs (same things)
axisSet.yAxis.majorIntervalLength = [ [ NSDecimalNumber decimalNumberWithString:@"2.0" ] decimalValue ];
axisSet.yAxis.minorTicksPerInterval = 1;
axisSet.yAxis.majorTickLineStyle = lineStyle;
axisSet.yAxis.minorTickLineStyle = lineStyle;
axisSet.yAxis.axisLineStyle = lineStyle;
axisSet.yAxis.minorTickLength = 5.0f;
axisSet.yAxis.majorTickLength = 10.0f;
axisSet.yAxis.labelOffset = 3.0f;

Utiliser CorePlot – Attribuer les valeurs

Maintenant il ne reste plus qu’à indiquer les valeurs de chaque variable grâce au dataSource que nous avons attribué au départ. Pour cela nous allons utiliser les deux méthodes delegate suivantes :

- (NSUInteger)numberOfRecordsForPlot:(CPPlot *)plot {
	
}

- (NSNumber *)numberForPlot:(CPPlot *)plot field:(NSUInteger)fieldEnum recordIndex:(NSUInteger)index {

}

Nombre de données à afficher

Dans un premier temps il faut indiquer le nombre de donnée que contient une courbe. Pour cela nous implémentons la méthode “numberOfRecordsForPlot:” qui nous indique en paramètre la courbe concernée.

- (NSUInteger)numberOfRecordsForPlot:(CPPlot *)plot {
	
	// If Plot 1
	if (plot.identifier == @"Plot 1")
		return 20;
	
	// If Plot 2
	return 10;
	
}

Pour la première courbe nommée “Plot 1″ nous déclarons qu’il y a 21 valeurs. Et pour la deuxième 11 valeurs. En général les données sont stockées dans un tableau. Ici nous enlevons cette contrainte. En cas de tableau vous pouvez directement faire un [ array count ].

Nombre à afficher en fonction de la courbe et de l’index

Et enfin il ne reste plus qu’à indiquer les données. Nous utilisons alors la deuxième méthode delegate “numberForPlot:::”.

- (NSNumber *)numberForPlot:(CPPlot *)plot field:(NSUInteger)fieldEnum recordIndex:(NSUInteger)index {
	
	// Number of the X axis asked
	if (fieldEnum == CPScatterPlotFieldX) {
		
		// Return -10, -9, -8, ... 8, 9, 10
		if (plot.identifier == @"Plot 1")
			return [ NSNumber numberWithInteger:-10.0+index ];
		// Return -5, -4, ..., 4, 5
		else if (plot.identifier == @"Plot 2")
			return [ NSNumber numberWithInteger:-5.0+index ];
		
	// Number of the Y axis asked
	} else if (fieldEnum == CPScatterPlotFieldY) { 
		
		// Return -10, -9, -8, ... 8, 9, 10
		if (plot.identifier == @"Plot 1")
			return [ NSNumber numberWithFloat:(-10.0+index)/2.0 ];
		// Return -5, -4, ..., 4, 5
		else if (plot.identifier == @"Plot 2")
			return [ NSNumber numberWithInteger:-5.0+index ];
		
	}
	
	// Return a default value, shouldn't be returned
	return [ NSNumber numberWithFloat:0.0 ];
	
}

Avec une condition on fait la différence entre a donnée pour l’axe X ou Y, puis une autre condition selon la courbe souhaitée. Attention à bien retourner des NSNumber !

Ceci nous retourne le résultat suivant :

Sources du projet Coreplot

Voici les sources de ce tutorial. Nous avons inclus en passant les sources de coreplot pour que vous puissiez compiler directement :
http://www.geckogeek.fr/static/files/Coreplot-Geckogeek.zip
Attention, n’oubliez pas d’installer le reste de coreplot comme il se doit. Le coreplot inclut dans le projet n’est que le wrapper iPhone / iPad.

Commentaires (2)
  1. ciwol le 6 Dec 2010 à 11:05

    Très bonne explication, je me suis lancé dans core-plot il y a peu, il manquerait peu être quelques infos sur comment afficher les données souhaitées, par exemple à partir d’un NSArray ou NSNumber.

    Merci @+

  2. Romain le 5 Apr 2012 à 13:53

    Merci beaucoup pour ce beau tutorial.
    Comment puis je faire pour que le graffe ne prenne pas toute la place ou que cette vue soit intégrée à l’intérieur d’une autre ?


Laisser un commentaire