iphone自適應三維柱狀圖

來源:互聯網
上載者:User

點擊柱狀圖中的 柱 可擷取 該柱的編號(從左至右,0-n)
能自動調整 柱 的寬度以及各 柱 之間的間隔
 
  1 //
  2 //  NTChartView.m
  3 //  chart
  4 //
  5 //  Created by wml on 11-04-10.
  6 //  Copyright 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 should be painted
 49    
 50     //繪圖上下文
 51     CGContextRef context = UIGraphicsGetCurrentContext();
 52     //設定畫筆顏色
 53     CGContextSetFillColorWithColor(context, [UIColor whiteColor].CGColor);
 54     //為該矩形填充顏色
 55     CGContextFillRect(context, _rect);
 56    
 57     //計算刻度
 58     [self calcScales:_rect];
 59     //畫刻度
 60     [self drawScale:context rect:_rect];
 61     //畫柱
 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(填充色)
131     CGContextSetFillColorWithColor(context, columnColor.CGColor);
132     // the stroke 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             //改變各柱之間的緊湊狀況
142             float basex = vNumber * WIDTH/(3*[g count]) + baseGroundX + columnWidth * vNumber;
143            
144             //畫正面
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             //畫右側面
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             //畫上面
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
 
 
 
由於CGRect是struct不能被放入容器中,所以自訂了一個類Rectangle,其 實現如下:
 
 
 
1 //
2 // Rectangle.m
3 // chart
4 //
5 // Created by user4 on 11-4-10.
6 // Copyright 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

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.