Click the column in the bar chart to obtain the number of the column (from left to right, 0-n)
The Bar Width and interval between columns can be adjusted automatically.
1 //
2 // NTChartView. m
3 // chart
4 //
5 // Created by wml on 11-04-10.
6 // copy 2009 _ MyCompanyName _. All rights reserved.
7 //
8
9 # import "NTChartView. h"
10 # import "Alerter. h"
11 # import "Rectangle. h"
12
13 static int MARGIN_LEFT = 50;
14 static int MARGIN_BOTTOM = 30;
15 static int MARGIN_TOP = 20;
16 static int SHOW_SCALE_NUM = 7;
17 static int WIDTH = 300;
18 static int HEIGHT = 300;
19
20 @ interface NTChartView (private)
21-(void) drawColumn :( CGContextRef) context rect :( CGRect) _ rect;
22-(void) drawScale :( CGContextRef) context rect :( CGRect) _ rect;
23-(void) calcScales :( CGRect) _ rect;
24 @ end
25
26 @ implementation NTChartView
27 @ synthesize groupData;
28 @ synthesize groupRect;
29 @ synthesize frstTouch;
30 @ synthesize scndTouch;
31
32-(void) dealloc
33 {
34 [groupRect release];
35 [groupData release];
36 [super dealloc];
37}
38
39
40-(void) drawRect :( CGRect) _ rect {
41 WIDTH = _ rect. size. width;
42 HEIGHT = _ rect. size. height;
43 groupRect = [[NSMutableArray alloc] init];
44 MARGIN_LEFT = WIDTH/6.0;
45 MARGIN_BOTTOM = HEIGHT/10.0;
46 MARGIN_TOP = HEIGHT/15.0;
47
48 // the _ rect is the Canvas on which the bar chart shocould be painted
49
50 // drawing Context
51 CGContextRef context = UIGraphicsGetCurrentContext ();
52 // set the paint brush color
53 CGContextSetFillColorWithColor (context, [UIColor whiteColor]. CGColor );
54 // fill the rectangle with color
55 CGContextFillRect (context, _ rect );
56
57 // calculate the scale
58 [self calcScales: _ rect];
59 // draw the scale
60 [self drawScale: context rect: _ rect];
61 // bar
62 [self drawColumn: context rect: _ rect];
63
64}
65
66-(void) drawScale :( CGContextRef) context rect :( CGRect) _ rect {
67
68 // the coordinate axis
69 CGPoint points [3];
70 // the top "end" of the y-axis
71 points [0] = CGPointMake (MARGIN_LEFT-WIDTH/30, MARGIN_TOP );
72 // the coordinate center
73 points [1] = CGPointMake (MARGIN_LEFT-WIDTH/30, _ rect. size. height-MARGIN_BOTTOM + 1 );
74 // the right "end" of x-axis
75 points [2] = CGPointMake (_ rect. size. width-WIDTH/30, _ rect. size. height-MARGIN_BOTTOM + 1 );
76 CGContextSetAllowsAntialiasing (context, NO );
77 CGContextAddLines (context, points, 3 );
78 // the color of the scale number
79 CGContextSetFillColorWithColor (context, [UIColor blackColor]. CGColor );
80
81 for (int I = 1; I <SHOW_SCALE_NUM + 1; I ++ ){
82 maxScaleHeight = (_ rect. size. height-MARGIN_BOTTOM) * (I)/(SHOW_SCALE_NUM + 1 );
83 int vScal = ceil (1.0 * maxScaleValue/(SHOW_SCALE_NUM) * (I ));
84 // the y-axis value of the current scale
85 float y = (_ rect. size. height-MARGIN_BOTTOM)-maxScaleHeight;
86
87 NSString * scaleStr = [NSString stringWithFormat: @ "% d", vScal];
88
89 [scaleStr drawAtPoint: CGPointMake (MARGIN_LEFT-WIDTH/15.0-[scaleStr sizeWithFont: [UIFont systemFontOfSize: 10]. width, y-7) withFont: [UIFont systemFontOfSize: 10];
90 // the short line to the right of the scale number
91 points [0] = CGPointMake (MARGIN_LEFT-WIDTH/30.0, y); // one end of the line
92 points [1] = CGPointMake (MARGIN_LEFT-WIDTH/30.0-3, y); // another end
93 CGContextSetLineDash (context, 0, NULL, 0 );
94 CGContextAddLines (context, points, 2 );
95
96 // draw those defined before
97 CGContextSetStrokeColorWithColor (context, [UIColor redColor]. CGColor );
98 CGContextDrawPath (context, kCGPathStroke );
99
100 // the horizontal referring line
101 points [0] = CGPointMake (MARGIN_LEFT-WIDTH/30.0, y );
102 points [1] = CGPointMake (_ rect. size. width-WIDTH/30.0, y );
103 // the length of the painted line segments and unpainted
104 // {2, 3} means a dotted line with the painted segments of length 2 pixel and...
105 float partren [] = {2, 3 };
106 CGContextSetStrokeColorWithColor (context, [UIColor colorWithRed:. 9 green:. 3 blue:. 3 alpha: 1]. CGColor );
107
108 CGContextSetLineDash (context, 0, partren, 2 );
109 CGContextAddLines (context, points, 2 );
110 // draw those defined after the last drawing
111 CGContextDrawPath (context, kCGPathStroke );
112
113}
114
115 CGContextSetStrokeColorWithColor (context, [UIColor blackColor]. CGColor );
116
117 CGContextDrawPath (context, kCGPathStroke );
118 CGContextSetAllowsAntialiasing (context, YES );
119
120
121}
122
123-(void) drawColumn :( CGContextRef) context rect :( CGRect) _ rect {
124
125 int gNumber = 0, vNumber = 0;
126 int baseGroundY = HEIGHT-MARGIN_BOTTOM, baseGroundX = MARGIN_LEFT;
127 CGPoint points [4];
128
129 UIColor * columnColor = [UIColor redColor];
130 // the fill color (fill color)
131 CGContextSetFillColorWithColor (context, columnColor. CGColor );
132 // the stroke color (edge color)
133 CGContextSetStrokeColorWithColor (context, [UIColor redColor]. CGColor );
134
135 for (NSArray * g in groupData ){
136 vNumber = 0;
137 for (NSNumber * v in g ){
138
139 float columnHeight = [v floatValue]/maxScaleValue * maxScaleHeight;
140
141 // change the Compact condition between columns
142 float basex = vNumber * WIDTH/(3 * [g count]) + baseGroundX + columnWidth * vNumber;
143
144 // draw the front
145 CGContextSetFillColorWithColor (context, columnColor. CGColor );
146
147 CGRect frontRect = CGRectMake (basex
148, baseGroundY-columnHeight
149, columnWidth
150, columnHeight );
151
152 Rectangle * r = [[Rectangle alloc] initWith_Rect: frontRect];
153 [groupRect addObject: r];
154
155 CGContextAddRect (context, frontRect );
156 // draw the frontage of the rectangle
157 CGContextDrawPath (context, kCGPathFill );
158 // NSLog (@ "columnHeight: % f, (_ rect. size. height-MARGIN_TOP-MARGIN_BOTTOM): % f ", columnHeight, (_ rect. size. height-MARGIN_TOP-MARGIN_BOTTOM ));
159
160 if (columnHeight <HEIGHT/30.0) {// if the bar is too short
161 vNumber +++;
162 continue;
163}
164 // draw the right side
165 // reset the color of the side face of the rectangle, so it looks more stereoscopic
166 CGContextSetFillColorWithColor (context, [UIColor colorWithRed:. 9 green: 0 blue: 0 alpha: 1]. CGColor );
167 points [0] = CGPointMake (basex + columnWidth, baseGroundY-columnHeight-HEIGHT/30.0 );
168 points [1] = CGPointMake (basex + columnWidth + sideWidth, baseGroundY-columnHeight-HEIGHT/30.0 );
169 points [2] = CGPointMake (basex + columnWidth + sideWidth, baseGroundY-HEIGHT/30.0 );
170 points [3] = CGPointMake (basex + columnWidth, baseGroundY );
171
172 CGContextAddLines (context, points, 4 );
173 CGContextDrawPath (context, kCGPathFill );
174
175 // draw the picture above
176 CGContextSetFillColorWithColor (context, [UIColor colorWithRed: 1 green:. 4 blue:. 4 alpha: 1]. CGColor );
177 points [0] = CGPointMake (basex, baseGroundY-columnHeight );
178 points [1] = CGPointMake (basex + sideWidth, baseGroundY-columnHeight-HEIGHT/30.0 );
179 points [2] = CGPointMake (basex + columnWidth + sideWidth, baseGroundY-columnHeight-HEIGHT/30.0 );
180 points [3] = CGPointMake (basex + columnWidth, baseGroundY-columnHeight );
181
182 CGContextAddLines (context, points, 4 );
183 CGContextDrawPath (context, kCGPathFill );
184
185 vNumber +++;
186}
187 gNumber +++;
188}
189
190
191}
192
193-(void) calcScales :( CGRect) _ rect {
194 int columnCount = 0;
195 for (NSArray * g in groupData ){
196 for (NSNumber * v in g ){
197 if (maxValue <[v floatValue]) maxValue = [v floatValue];
198 if (minValue> [v floatValue]) minValue = [v floatValue];
199 columnCount +++;
200}
201}
202
203 maxScaleValue = (int) ceil (maxValue) + (SHOW_SCALE_NUM-(int) ceil (maxValue) % SHOW_SCALE_NUM ));
204
205 columnWidth = (WIDTH-MARGIN_LEFT * 2)/(columnCount + 1 );
206 sideWidth = columnWidth *. 2;
207 columnWidth * =. 8;
208}
209
210-(void) touchesBegan :( NSSet *) touches withEvent :( UIEvent *) event {
211
212 UITouch * touch = [touches anyObject];
213 frstTouch = [touch locationInView: self];
214 scndTouch = [touch locationInView: self];
215 NSInteger index = [self touchToBarIndex: touch];
216 NSLog (@ "began x: % f, y: % f, num: % d", frstTouch. x, frstTouch. y, index );
217
218 [self setNeedsDisplay];
219}
220
221-(NSInteger) touchToBarIndex :( UITouch *) touch {
222 CGPoint p = [touch locationInView: self];
223 int index = 0;
224
225 for (Rectangle * r in groupRect ){
226 if (p. x> [r. x floatValue] & p. x <[r. x floatValue] + [r. width floatValue] + WIDTH/30.0 & p. y> [r. y floatValue]-HEIGHT/30.0 & p. y <[r. y floatValue] + [r. height floatValue]) {
227 return index;
228}
229 index ++;
230}
231 return-1;
232}
233
234 @ end
Since CGRect is a struct, it cannot be placed in a container. Therefore, a Rectangle class is defined, and its implementation is as follows:
1 //
2 // Rectangle. m
3 // chart
4 //
5 // Created by user4 on 11-4-10.
6 // copy 2011 _ MyCompanyName _. All rights reserved.
7 //
8
9 # import "Rectangle. h"
10
11 @ implementation Rectangle
12 @ synthesize x;
13 @ synthesize y;
14 @ synthesize width;
15 @ synthesize height;
16
17-(id) initWith_Rect :( CGRect) r {
18 self = [super init];
19 if (self ){
20 self. x = [NSNumber numberWithFloat: r. origin. x];
21 self. y = [NSNumber numberWithFloat: r. origin. y];
22 self. width = [NSNumber numberWithFloat: r. size. width];
23 self. height = [NSNumber numberWithFloat: r. size. height];
24}
25 return self;
26}
27
28-(void) dealloc
29 {
30 [x release];
31 [y release];
32 [width release];
33 [height release];
34 [super dealloc];
35}
36 @ end