1 | |
---|
2 | |
---|
3 | |
---|
4 | |
---|
5 | |
---|
6 | |
---|
7 | |
---|
8 | |
---|
9 | #import "GradientScatterPlot.h" |
---|
10 | |
---|
11 | @implementation GradientScatterPlot |
---|
12 | |
---|
13 | +(void)load |
---|
14 | { |
---|
15 | [super registerPlotItem:self]; |
---|
16 | } |
---|
17 | |
---|
18 | -(id)init |
---|
19 | { |
---|
20 | if ( (self = [super init]) ) { |
---|
21 | title = @"Gradient Scatter Plot"; |
---|
22 | } |
---|
23 | |
---|
24 | return self; |
---|
25 | } |
---|
26 | |
---|
27 | -(void)killGraph |
---|
28 | { |
---|
29 | if ( [graphs count] ) { |
---|
30 | CPTGraph *graph = [graphs objectAtIndex:0]; |
---|
31 | |
---|
32 | if ( symbolTextAnnotation ) { |
---|
33 | [graph.plotAreaFrame.plotArea removeAnnotation:symbolTextAnnotation]; |
---|
34 | [symbolTextAnnotation release]; |
---|
35 | symbolTextAnnotation = nil; |
---|
36 | } |
---|
37 | } |
---|
38 | |
---|
39 | [super killGraph]; |
---|
40 | } |
---|
41 | |
---|
42 | -(void)generateData |
---|
43 | { |
---|
44 | if ( plotData == nil ) { |
---|
45 | NSMutableArray *contentArray = [NSMutableArray arrayWithCapacity:100]; |
---|
46 | for ( NSUInteger i = 0; i < 10; i++ ) { |
---|
47 | id x = [NSDecimalNumber numberWithDouble:1.0 + i * 0.05]; |
---|
48 | id y = [NSDecimalNumber numberWithDouble:1.2 * rand() / (double)RAND_MAX + 0.5]; |
---|
49 | [contentArray addObject:[NSMutableDictionary dictionaryWithObjectsAndKeys:x, @"x", y, @"y", nil]]; |
---|
50 | } |
---|
51 | plotData = [contentArray retain]; |
---|
52 | } |
---|
53 | } |
---|
54 | |
---|
55 | -(void)renderInLayer:(CPTGraphHostingView *)layerHostingView withTheme:(CPTTheme *)theme |
---|
56 | { |
---|
57 | #if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE |
---|
58 | CGRect bounds = layerHostingView.bounds; |
---|
59 | #else |
---|
60 | CGRect bounds = NSRectToCGRect(layerHostingView.bounds); |
---|
61 | #endif |
---|
62 | |
---|
63 | CPTGraph *graph = [[[CPTXYGraph alloc] initWithFrame:bounds] autorelease]; |
---|
64 | [self addGraph:graph toHostingView:layerHostingView]; |
---|
65 | [self applyTheme:theme toGraph:graph withDefault:[CPTTheme themeNamed:kCPTSlateTheme]]; |
---|
66 | |
---|
67 | [self setTitleDefaultsForGraph:graph withBounds:bounds]; |
---|
68 | [self setPaddingDefaultsForGraph:graph withBounds:bounds]; |
---|
69 | |
---|
70 | |
---|
71 | CPTXYPlotSpace *plotSpace = (CPTXYPlotSpace *)graph.defaultPlotSpace; |
---|
72 | plotSpace.allowsUserInteraction = YES; |
---|
73 | plotSpace.delegate = self; |
---|
74 | |
---|
75 | |
---|
76 | CPTMutableLineStyle *majorGridLineStyle = [CPTMutableLineStyle lineStyle]; |
---|
77 | majorGridLineStyle.lineWidth = 0.75; |
---|
78 | majorGridLineStyle.lineColor = [[CPTColor colorWithGenericGray:0.2] colorWithAlphaComponent:0.75]; |
---|
79 | |
---|
80 | CPTMutableLineStyle *minorGridLineStyle = [CPTMutableLineStyle lineStyle]; |
---|
81 | minorGridLineStyle.lineWidth = 0.25; |
---|
82 | minorGridLineStyle.lineColor = [[CPTColor whiteColor] colorWithAlphaComponent:0.1]; |
---|
83 | |
---|
84 | |
---|
85 | |
---|
86 | CPTXYAxisSet *axisSet = (CPTXYAxisSet *)graph.axisSet; |
---|
87 | CPTXYAxis *x = axisSet.xAxis; |
---|
88 | x.majorIntervalLength = CPTDecimalFromString(@"0.5"); |
---|
89 | x.orthogonalCoordinateDecimal = CPTDecimalFromString(@"1.0"); |
---|
90 | x.minorTicksPerInterval = 2; |
---|
91 | x.majorGridLineStyle = majorGridLineStyle; |
---|
92 | x.minorGridLineStyle = minorGridLineStyle; |
---|
93 | |
---|
94 | x.title = @"X Axis"; |
---|
95 | x.titleOffset = 30.0; |
---|
96 | x.titleLocation = CPTDecimalFromString(@"1.25"); |
---|
97 | |
---|
98 | |
---|
99 | CPTXYAxis *y = axisSet.yAxis; |
---|
100 | y.labelingPolicy = CPTAxisLabelingPolicyAutomatic; |
---|
101 | y.orthogonalCoordinateDecimal = CPTDecimalFromString(@"1.0"); |
---|
102 | y.minorTicksPerInterval = 2; |
---|
103 | y.preferredNumberOfMajorTicks = 8; |
---|
104 | y.majorGridLineStyle = majorGridLineStyle; |
---|
105 | y.minorGridLineStyle = minorGridLineStyle; |
---|
106 | y.labelOffset = 10.0; |
---|
107 | |
---|
108 | y.title = @"Y Axis"; |
---|
109 | y.titleOffset = 30.0; |
---|
110 | y.titleLocation = CPTDecimalFromString(@"1.0"); |
---|
111 | |
---|
112 | |
---|
113 | CPTScatterPlot *dataSourceLinePlot = [[[CPTScatterPlot alloc] init] autorelease]; |
---|
114 | dataSourceLinePlot.identifier = @"Data Source Plot"; |
---|
115 | |
---|
116 | CPTMutableLineStyle *lineStyle = [[dataSourceLinePlot.dataLineStyle mutableCopy] autorelease]; |
---|
117 | lineStyle.lineWidth = 3.0; |
---|
118 | lineStyle.lineColor = [CPTColor greenColor]; |
---|
119 | dataSourceLinePlot.dataLineStyle = lineStyle; |
---|
120 | dataSourceLinePlot.dataSource = self; |
---|
121 | [graph addPlot:dataSourceLinePlot]; |
---|
122 | |
---|
123 | |
---|
124 | CPTColor *areaColor = [CPTColor colorWithComponentRed:0.3 green:1.0 blue:0.3 alpha:0.8]; |
---|
125 | CPTGradient *areaGradient = [CPTGradient gradientWithBeginningColor:areaColor endingColor:[CPTColor clearColor]]; |
---|
126 | areaGradient.angle = -90.0; |
---|
127 | CPTFill *areaGradientFill = [CPTFill fillWithGradient:areaGradient]; |
---|
128 | dataSourceLinePlot.areaFill = areaGradientFill; |
---|
129 | dataSourceLinePlot.areaBaseValue = CPTDecimalFromString(@"0.0"); |
---|
130 | |
---|
131 | |
---|
132 | |
---|
133 | [plotSpace scaleToFitPlots:[NSArray arrayWithObjects:dataSourceLinePlot, nil]]; |
---|
134 | CPTMutablePlotRange *xRange = [[plotSpace.xRange mutableCopy] autorelease]; |
---|
135 | CPTMutablePlotRange *yRange = [[plotSpace.yRange mutableCopy] autorelease]; |
---|
136 | [xRange expandRangeByFactor:CPTDecimalFromDouble(1.3)]; |
---|
137 | [yRange expandRangeByFactor:CPTDecimalFromDouble(1.3)]; |
---|
138 | plotSpace.xRange = xRange; |
---|
139 | plotSpace.yRange = yRange; |
---|
140 | |
---|
141 | |
---|
142 | CPTPlotRange *globalYRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(0.0f) |
---|
143 | length:CPTDecimalFromFloat(2.0f)]; |
---|
144 | plotSpace.globalYRange = globalYRange; |
---|
145 | |
---|
146 | |
---|
147 | CPTMutableLineStyle *symbolLineStyle = [CPTMutableLineStyle lineStyle]; |
---|
148 | symbolLineStyle.lineColor = [CPTColor blackColor]; |
---|
149 | CPTPlotSymbol *plotSymbol = [CPTPlotSymbol ellipsePlotSymbol]; |
---|
150 | plotSymbol.fill = [CPTFill fillWithColor:[CPTColor blueColor]]; |
---|
151 | plotSymbol.lineStyle = symbolLineStyle; |
---|
152 | plotSymbol.size = CGSizeMake(10.0, 10.0); |
---|
153 | dataSourceLinePlot.plotSymbol = plotSymbol; |
---|
154 | |
---|
155 | |
---|
156 | |
---|
157 | dataSourceLinePlot.delegate = self; |
---|
158 | dataSourceLinePlot.plotSymbolMarginForHitDetection = 5.0f; |
---|
159 | } |
---|
160 | |
---|
161 | -(void)dealloc |
---|
162 | { |
---|
163 | [plotData release]; |
---|
164 | [super dealloc]; |
---|
165 | } |
---|
166 | |
---|
167 | #pragma mark - |
---|
168 | #pragma mark Plot Data Source Methods |
---|
169 | |
---|
170 | -(NSUInteger)numberOfRecordsForPlot:(CPTPlot *)plot |
---|
171 | { |
---|
172 | return [plotData count]; |
---|
173 | } |
---|
174 | |
---|
175 | -(NSNumber *)numberForPlot:(CPTPlot *)plot field:(NSUInteger)fieldEnum recordIndex:(NSUInteger)index |
---|
176 | { |
---|
177 | NSString *key = (fieldEnum == CPTScatterPlotFieldX ? @"x" : @"y"); |
---|
178 | NSNumber *num = [[plotData objectAtIndex:index] valueForKey:key]; |
---|
179 | |
---|
180 | if ( fieldEnum == CPTScatterPlotFieldY ) { |
---|
181 | num = [NSNumber numberWithDouble:[num doubleValue]]; |
---|
182 | } |
---|
183 | |
---|
184 | return num; |
---|
185 | } |
---|
186 | |
---|
187 | #pragma mark - |
---|
188 | #pragma mark Plot Space Delegate Methods |
---|
189 | |
---|
190 | -(CPTPlotRange *)plotSpace:(CPTPlotSpace *)space willChangePlotRangeTo:(CPTPlotRange *)newRange forCoordinate:(CPTCoordinate)coordinate |
---|
191 | { |
---|
192 | |
---|
193 | if ( coordinate == CPTCoordinateX ) { |
---|
194 | CPTPlotRange *maxRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(-1.0f) length:CPTDecimalFromFloat(6.0f)]; |
---|
195 | CPTMutablePlotRange *changedRange = [[newRange mutableCopy] autorelease]; |
---|
196 | [changedRange shiftEndToFitInRange:maxRange]; |
---|
197 | [changedRange shiftLocationToFitInRange:maxRange]; |
---|
198 | newRange = changedRange; |
---|
199 | } |
---|
200 | return newRange; |
---|
201 | } |
---|
202 | |
---|
203 | #pragma mark - |
---|
204 | #pragma mark CPTScatterPlot delegate method |
---|
205 | |
---|
206 | -(void)scatterPlot:(CPTScatterPlot *)plot plotSymbolWasSelectedAtRecordIndex:(NSUInteger)index |
---|
207 | { |
---|
208 | CPTGraph *graph = [graphs objectAtIndex:0]; |
---|
209 | |
---|
210 | if ( symbolTextAnnotation ) { |
---|
211 | [graph.plotAreaFrame.plotArea removeAnnotation:symbolTextAnnotation]; |
---|
212 | symbolTextAnnotation = nil; |
---|
213 | } |
---|
214 | |
---|
215 | |
---|
216 | CPTMutableTextStyle *hitAnnotationTextStyle = [CPTMutableTextStyle textStyle]; |
---|
217 | hitAnnotationTextStyle.color = [CPTColor whiteColor]; |
---|
218 | hitAnnotationTextStyle.fontSize = 16.0f; |
---|
219 | hitAnnotationTextStyle.fontName = @"Helvetica-Bold"; |
---|
220 | |
---|
221 | |
---|
222 | NSNumber *x = [[plotData objectAtIndex:index] valueForKey:@"x"]; |
---|
223 | NSNumber *y = [[plotData objectAtIndex:index] valueForKey:@"y"]; |
---|
224 | NSArray *anchorPoint = [NSArray arrayWithObjects:x, y, nil]; |
---|
225 | |
---|
226 | |
---|
227 | |
---|
228 | NSNumberFormatter *formatter = [[[NSNumberFormatter alloc] init] autorelease]; |
---|
229 | [formatter setMaximumFractionDigits:2]; |
---|
230 | NSString *yString = [formatter stringFromNumber:y]; |
---|
231 | |
---|
232 | |
---|
233 | CPTTextLayer *textLayer = [[[CPTTextLayer alloc] initWithText:yString style:hitAnnotationTextStyle] autorelease]; |
---|
234 | symbolTextAnnotation = [[CPTPlotSpaceAnnotation alloc] initWithPlotSpace:graph.defaultPlotSpace anchorPlotPoint:anchorPoint]; |
---|
235 | symbolTextAnnotation.contentLayer = textLayer; |
---|
236 | symbolTextAnnotation.displacement = CGPointMake(0.0f, 20.0f); |
---|
237 | [graph.plotAreaFrame.plotArea addAnnotation:symbolTextAnnotation]; |
---|
238 | } |
---|
239 | |
---|
240 | @end |
---|