Når du arbeider med dataintensive applikasjoner, må en utvikler ofte gjøre mer enn bare å vise lister over dataposter i en tabellvisning. CorePlot-biblioteket lar deg legge til fantastiske datavisualiseringer i dine applikasjoner. Finn ut hvordan i denne Tuts + Premium-serien!
Sist gang vi introduserte CorePlot-rammeverket og diskutert hva det kan gjøre og hvordan vi kan bruke det til å forbedre datavisualisering i våre applikasjoner. Vi har også undersøkt prøveapplikasjonen vi skal lage i serien og hvordan du legger til CorePlot i applikasjonen vår. For et kodesnitt av hvor vi sluttet sist, last ned kildekoden for denne opplæringen (ellers kan du gjerne bruke din eksisterende kodebase og lagre nedlastningstiden!).
Før vi kan lage en graf, trenger vi en visning for å gjøre det. Vi skal tillate brukeren å klikke på en UIBarButtonItem i "Student" -fanen som vil hente et handlingsbilde med en liste over grafer for bruker å velge. Når et valg er gjort, vil en modal visning vise en graf med relevante data på den.
Vi skal lage en ny gruppe kalt "Grafering" under "StudentTracker" -gruppen. Opprett en gruppe 'Visninger' og 'Kontrollører' under dette som i 'Studentoppføring' og 'Emneoppføring'.
Opprett en ny klasse kalt 'STLineGraphViewController' (underklasse UIViewController) i 'View Controllers' gruppen. Når du velger hvor du skal legge til filene, er det beste stedet å sette dem i mappen 'Klasser / Grafer / View Controllers' (Du må opprette katalogen 'Grafer / View Controllers').
Vi kommer til å komme tilbake og jobbe med å tilpasse dette senere. Akkurat nå skal vi implementere den koden som lar brukeren velge en graf for å se på.
Først åpne STStudentListViewController.h og legg til 'UIActionSheetDelegate' og 'STLineGraphViewControllerDelegate' protokolldeklarasjoner. Denne protokollen eksisterer ikke ennå, men vi vil lage den senere (Sørg også for at du importerer filen 'STLineGraphViewController.h').
@interface STStudentListViewController: UIViewController
Deretter åpner du .m filen og implementerer 'actionSheet: clickedButtonAtIndex:' metoden med følgende kode:
- (void) actionSheet: (UIActionSheet *) actionSheet klikketButtonAtIndex: (NSInteger) buttonIndex if (buttonIndex == 0) STLineGraphViewController * lineGraphVC = [[STLineGraphViewController alloc] init]; [lineGraphVC setModalTransitionStyle: UIModalTransitionStyleFlipHorizontal]; [lineGraphVC setDelegate: self]; [lineGraphVC setManagedObjectContext: [self managedObjectContext]]; [self presentModalViewController: lineGraphVC animert: JA]; [lineGraphVC release];
Denne koden skal ikke ha for mye forklaring. Vi oppretter bare en LineGraph View Controller og presenterer den modelt. Vi setter oss som representant, slik at vi vet når vi skal avvise den modale visningen. Vi gir også visningscontrolleren en administrert objektkontekst til å jobbe med, så det kan grensesnittet med kjerne data. Disse to siste metodene vil skape en advarsel (eller feil hvis du bruker ARC) fordi egenskapene ikke eksisterer ennå, men vi vil skape dem senere.
Deretter skal vi opprette en metode for å ringe til handlingsarket og legge til et UITabBarItem for å ringe det fra. Legg til en metoden deklarasjon i .m grensesnittet kalles 'graphButtonWasSelected:':
@interface STStudentListViewController () @property (nonatomic, strong) NSArray * studentArray; - (void) addStudent: (id) avsender; - (void) graphButtonWasSelected: (id) avsender; @slutt
Deretter legger du til implementeringsmetoden:
- (ugyldig) graphButtonWasSelected: (id) avsender UIActionSheet * graphSelectionActionSheet = [[[UIActionSheet alloc] initWithTitle: @ "Velg en graf" delegert: self cancelButtonTitle: @ "Cancel" destructiveButtonTitle: nil otherButtonTitles: @ "Registrering over tid" ] autorelease]; [graphSelectionActionSheet showInView: [[UIApplication sharedApplication] keyWindow]];
Deretter må vi legge til en UIBarButtonItem for brukeren å velge når de vil vise grafen. Vi gjør dette i viewDidLoad-metoden under der vi lager den rette linjepunktet:
[[self navigationItem] setLeftBarButtonItem: [[[UIBarButtonItem alloc] initWithTitle: @ "Grafer" stil: UIBarButtonItemStylePlain mål: selv handling: @selector (graphButtonWasSelected :)] autorelease] animated: NO];
Til slutt må vi implementere en STLineGraphViewController protokollmetode som vil fortelle kontrolleren å avvise modalvisningen når brukeren er ferdig med å se på grafen:
- (ugyldig) doneButtonWasTapped: (id) avsender [self dismissModalViewControllerAnimated: YES];
Nå er vi klare til å begynne å lage grafen!
Først må vi lage en egendefinert visningsklasse for vår LineGraphViewController. I Grafering> Visningsgruppe oppretter du en ny klasse som strekker UIView kalt 'STLineGraphView' (Pass på at du legger den i riktig mappe når du velger hvor den er lagret på filsystemet).
Vi skal sette de grafiske aspektene av visningen opp i visningsklassen. Gå først til .h-filen og (etter import av "CorePlot-CocoaTouch.h" -filen) og legg til følgende eiendomserklæring:
@property (nonatomic, strong) CPTGraphHostingView * chartHostingView;
CPTGraphHostingView er rett og slett en UIView som er ansvarlig for å inneholde grafen og tillater brukerinteraksjon (som vi dekker i en senere opplæring).
Synthesize chartHostingView og opprett diagrammet hosting visning i initWithFrame metoden:
[self setChartHostingView: [[[CPTGraphHostingView alloc] initWithFrame: CGRectZero] autorelease]]; [self addSubview: chartHostingView];
Ovenstående skal være ganske selvforklarende. Vi lager en CPTGraphHostingView og angir den som vår egenskap for chartHostingVIew. Vi legger det til som et undervisning.
Deretter må vi sette graphViews-rammemålene i metoden "layoutundervisninger":
[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: [selvsenter]];
Igjen, alle de ovennevnte bør være enkle ting. Før vi begynner å jobbe med kontrolleren, må du sørge for at du frigjør egenskapen 'chartHostingView' i visningen dealloc-metoden hvis du ikke allerede har.
Det meste av arbeidet vi skal gjøre nå, kommer til å være i kontrolleren. Åpne STLineGraphViewController.h og legg til følgende eiendomserklæringer:
@interface STLineGraphViewController: UIViewController@property (nonatomic, strong) CPTGraph * graf; @property (nonatomic, assign) id delegat; @property (nonatomic, strong) NSManagedObjectContext * managedObjectContext;
CPTGraph er en abstrakt klasse som er ansvarlig for å tegne grafelementene og administrere de forskjellige tomter. Det er også ansvarlig for å bruke temaer, laste opp grafdataene og mye mer! Vi indikerer også at vi vil overholde CPTScatterPlotDataSource og CPTScatterPlotDelegate protokollene.
Vi må også legge til en egen protokoll slik at modalvisningen kan avvises. Sett følgende kode over grensesnittdeklarasjonen:
@protocol STLineGraphViewControllerDelegate @required - (void) doneButtonWasTapped: (id) avsender; @slutt
Bytt til * .m filen og syntetiser grafen og deleger egenskaper. Når dette er gjort, legg til følgende kode før 'viewDidLoad'-metoden:
[self setView: [[[STLineGraphView alloc] initWithFrame: self.view.frame] autorelease]]; CPTTheme * defaultTheme = [CPTTheme themeNamed: kCPTPlainWhiteTheme]; [self setGraph: (CPTGraph *) [defaultTheme newGraph]]; [defaultTheme release];
Det er noen ting som skjer i denne delen. Først oppretter vi og setter oppsynet til kontrolleren som vår egendefinerte STLineGraphView. Deretter oppretter vi et "CPTTheme" -objekt. CPTTheme-objektet administrerer stilen til en graf med linjestiler, tekststil og eventuelle fyllinger som kreves. En enkel måte å få en CPTGraph på forhånd konfigurert med en base CPTTheme er å lage CPTTheme med et av de forhåndsdefinerte tema navnene og deretter bruke metoden 'newGraph' for å gi oss en graf som er utformet med den.
Deretter skal vi sette følgende kode i "viewDidLoad" Metoden:
[super viewDidLoad]; STLineGraphView * graphView = (STLineGraphView *) [selvvisning]; [[selvgrafikk] setDelegate: self]; [[graphView chartHostingView] setHostedGraph: [selvgrafikk]]; CPTScatterPlot * studentScatterPlot = [[CPTScatterPlot-allokering] initWithFrame: [graph bounds]]; [studentScatterPlot setIdentifier: @ "studentEnrollment"]; [studentScatterPlot setDelegate: self]; [studentScatterPlot setDataSource: self]; [[selvgrafikk] addPlot: studentScatterPlot]; UINavigationItem * navigationItem = [[UINavigationItem alloc] initWithTitle: self.title]; [navigasjonItem setHidesBackButton: JA]; UINavigationBar * navigationBar = [[[UINavigationBar alloc] initWithFrame: CGRectMake (0, 0, self.view.frame.size.width, 44.0f)] autorelease]; [navigasjonBar pushNavigationItem: navigasjonItem animert: NEI]; [self.view addSubview: navigasjonBar]; [navigasjonItem setRightBarButtonItem: [[[UIBarButtonItem alloc] initWithTitle: @ "Ferdig" stil: UIBarButtonItemStyleDone mål: [self delegate] handling: @selector (doneButtonWasTapped :)] autorelease] animated: NO];
I den ovennevnte koden får vi vår visning og innstiller den vertsgrensen for visningsdiagrammet vertsvisning til vårt grafobjekt. Vi lager da en "plot" for å sette på grafen. Vi bruker 'CPTScatterPlot' når vi vil lage en linjediagram. Identifikatoren er noe vi kan bruke til å identifisere plottet senere. Vi setter deretter delegat og datakilde til kontrollerklassen, da det vil være ansvarlig for å gi dataene for grafen. Til slutt legger vi til det nyopprettede plottet i grafen.
Etter at vi jobber med grafen, oppretter vi et navigasjonselement og en bar for modalvisningskontrollen for å vise en tittel og en ferdig knapp som tar dem tilbake til den opprinnelige visningen.
Prøv å kjøre prosjektet nå og gå til linjediagrammet. Du bør se noe som følger:
Vi har begynnelsen på en graf! Nå for å legge til noen data:
Plotter i CorePlot bruker to hoveddatakildemetoder for å skaffe data, 'numberOfRecordsForPlot' og 'numberForPlot: field: recordIndex:'. Det ligner veldig på hvordan tabellvisninger fungerer. Først vil vi spesifisere antall poster for plottet:
- (NSUInteger) numberOfRecordsForPlot: (CPTPlot *) plot return 8;
Vi viser hvor mange innmeldinger som skjedde på hver dag i uken. Siden det er 7 mulige dager hvor studenten kunne ha registrert, har vi 8 totale poster (fordi vi starter ved 0).
Nå vil vi spesifisere hva x- og y-verdien skal være for hver plate:
- (NSNummer *) numberForPlot: (CPTPlot *) plottfelt: (NSUInteger) -feltEn recordIndex: (NSUInteger) indeks NSUInteger x = index; NSUInteger y = 0; NSError * feil; NSFetchRequest * fetchRequest = [[NSFetchRequest alloker] init]; NSEntityDescription * entity = [NSEntityDescription entityForName: @ "STStudent" inManagedObjectContext: managedObjectContext]; NSPredicate * predicate = [NSPredicate predicateWithFormat: @ "dayEnrolled ==% d", indeks]; [fetchRequest setEntity: entity]; [fetchRequest setPredicate: predicate]; y = [managedObjectContext countForFetchRequest: fetchRequest error: & error]; [fetchRequest release]; bytte (fieldEnum) tilfelle CPTScatterPlotFieldX: NSLog (@ "x-verdi for% d er% d", indeks, x); returnere [NSNummer nummer medInt: x]; gå i stykker; saken CPTScatterPlotFieldY: NSLog (@ "y-verdien for% d er% d", indeksen, y); returnere [NSNummer nummer medIt: y]; gå i stykker; standard: break; returner null;
Det er en god del å foregå over. Denne metoden må spesifisere en x- og y-verdi for en gitt indeks og hvilken verdi den returnerer er basert på "fieldEnum" -verdien (som i vårt tilfelle er enten CPTScatterPlotFieldX eller CPTScatterPlotFieldY). Indeksen indikerer platen den skal plotte på grafen, og plottet refererer til selve plottet som viser dataene. Når vi har en kontroller som styrer mer enn 1 tomt, kan vi se på plottidentifikatoren for å bestemme hvilket sett av data som skal leveres (vi dekker denne prosessen i en senere opplæring).
Jeg finner det enklest å spesifisere en 'x' og 'y' -verdi i begynnelsen av metoden, utarbeide begge verdiene, og deretter basert på feltet returnerer den riktige i form av en NSNummer (som er formatet som corePlot krever det i).
X-verdien er lett å finne ut. Da den viser inntidsdager, er x lik den nåværende indeksen. Y-verdien kommer til å være en telling av alle studenter som er innmeldt på den dagen. Vi kan få dette ved å ringe til vår kjerne datalager og se etter alle STStudent-poster med en 'dayEnrolled' -verdi av indeksen. Hvis du ikke er kjent med kjernedata og ikke forstår alt som skjer, ikke vær så bekymret, for nå er det ok at det fungerer. Fokus på å lære en ting av gangen!
Hvis du lagrer og kjører programmet nå, vil du fortsatt ikke se noe som vises på grafen, men du bør se følgende utgang i konsollen:
Dette betyr at grafen får de riktige verdiene for x og y (sørg for at den er den samme eller lik produksjonen i bildet. Det vises fortsatt ikke på grafen. Det er fordi hvis du ser på grafen, visningsområdet er feil. Vi ser på -1,0 til 0 på både x- og y-aksen. Vi må stille rekkevidden til å se på før vi kan se datapunktene.
Plottfeltet bestemmer mye om hvordan grafen blir sett og formatert. Vi vil dekke litt i denne opplæringen og vil gå inn i mye større detalj i den neste.
For å angi x- og y-området som brukeren ser på, må vi jobbe med objektet 'CPTXYPlotSpace'. Dette objektet lar oss sette et visbart område for grafen.
Gå til viewDidLoad-metoden og legg til følgende kode rett under der vi legger til plottet i grafen vår:
CPTXYPlotSpace * studentPlotSpace = (CPTXYPlotSpace *) [graph defaultPlotSpace]; [studentPlotSpace setXRange: [CPTPlotRange plotRangeWithLocation: CPTDecimalFromInt (0) lengde: CPTDecimalFromInt (7)]]; [studentPlotSpace setYRange: [CPTPlotRange plotRangeWithLocation: CPTDecimalFromInt (0) lengde: CPTDecimalFromInt (10)]];
Først får vi et CPTXYPlotSpace-objekt fra grafene som standard tomtrom (noe avstøpning kreves). Da setter vi bare x- og y-serien. Området er et CPTPlotRange-objekt som vi lager statisk ved hjelp av metoden 'plotRangeWithLocation: length:'. Denne metoden tar NSDecimals, men corePlot gir oss en funksjon vi kan bruke til å få et desimal fra en int-kalt 'CPTDecimalFromInt' (Det er også en for float hvis det er nødvendig).
Lagre og kjør nå programmet, og du bør se starten på den første grafen din!
Vi har begynnelsen på en graf, men det trenger litt mer arbeid før det kan være veldig nyttig. Neste gang skal vi diskutere hvordan du skal angi og formatere akseetiketter, markere linjer og inkrementer. Vi skal også diskutere hvordan du skal tilpasse utseendet på grafen, og til slutt hvordan du legger til og administrerer flere tomter på en enkelt graf. Ser deg neste gang!