andi

pie chart label

@@ -27,6 +27,14 @@ typedef NS_ENUM(NSUInteger, PNLegendItemStyle) { @@ -27,6 +27,14 @@ typedef NS_ENUM(NSUInteger, PNLegendItemStyle) {
27 @property (assign, nonatomic) PNLegendItemStyle legendStyle; 27 @property (assign, nonatomic) PNLegendItemStyle legendStyle;
28 @property (assign, nonatomic) CGFloat legendFontSize; 28 @property (assign, nonatomic) CGFloat legendFontSize;
29 29
30 -- (UIView*) drawLegend; 30 +/**
  31 + * returns the Legend View, or nil if no chart data is present.
  32 + * The origin of the legend frame is 0,0 but you can set it with setFrame:(CGRect)
  33 + *
  34 + * @param mWidth Maximum width of legend. Height will depend on this and font size
  35 + *
  36 + * @return UIView of Legend
  37 + */
  38 +- (UIView*) getLegendWithMaxWidth:(CGFloat)mWidth;
31 39
32 @end 40 @end
@@ -57,4 +57,16 @@ @@ -57,4 +57,16 @@
57 self.legendStyle = PNLegendItemStyleStacked; 57 self.legendStyle = PNLegendItemStyleStacked;
58 } 58 }
59 59
  60 +
  61 +
  62 +/**
  63 + * to be implemented in subclass
  64 + */
  65 +- (UIView*) getLegendWithMaxWidth:(CGFloat)mWidth{
  66 + [self doesNotRecognizeSelector:_cmd];
  67 + return nil;
  68 +}
  69 +
  70 +
  71 +
60 @end 72 @end
@@ -81,4 +81,7 @@ @@ -81,4 +81,7 @@
81 * @return UIView of Legend 81 * @return UIView of Legend
82 */ 82 */
83 - (UIView*) getLegendWithMaxWidth:(CGFloat)mWidth; 83 - (UIView*) getLegendWithMaxWidth:(CGFloat)mWidth;
  84 +
  85 +
  86 ++ (CGSize)sizeOfString:(NSString *)text withWidth:(float)width font:(UIFont *)font;
84 @end 87 @end
@@ -7,6 +7,8 @@ @@ -7,6 +7,8 @@
7 // 7 //
8 8
9 #import "PNPieChart.h" 9 #import "PNPieChart.h"
  10 +//needed for the expected label size
  11 +#import "PNLineChart.h"
10 12
11 @interface PNPieChart() 13 @interface PNPieChart()
12 14
@@ -224,4 +226,98 @@ @@ -224,4 +226,98 @@
224 }]; 226 }];
225 }]; 227 }];
226 } 228 }
  229 +
  230 +- (UIView*) getLegendWithMaxWidth:(CGFloat)mWidth{
  231 + if ([self.items count] < 1) {
  232 + return nil;
  233 + }
  234 +
  235 + /* This is a small circle that refers to the chart data */
  236 + CGFloat legendCircle = 10;
  237 +
  238 + /* x and y are the coordinates of the starting point of each legend item */
  239 + CGFloat x = 0;
  240 + CGFloat y = 0;
  241 +
  242 + /* accumulated width and height */
  243 + CGFloat totalWidth = 0;
  244 + CGFloat totalHeight = 0;
  245 +
  246 + NSMutableArray *legendViews = [[NSMutableArray alloc] init];
  247 +
  248 +
  249 + /* Determine the max width of each legend item */
  250 + CGFloat maxLabelWidth = self.legendStyle == PNLegendItemStyleStacked ? (mWidth - legendCircle) : (mWidth / [self.items count] - legendCircle);
  251 +
  252 + /* this is used when labels wrap text and the line
  253 + * should be in the middle of the first row */
  254 + CGFloat singleRowHeight = [PNLineChart sizeOfString:@"Test"
  255 + withWidth:MAXFLOAT
  256 + font:[UIFont systemFontOfSize:self.legendFontSize]].height;
  257 +
  258 + for (PNPieChartDataItem *pdata in self.items) {
  259 + /* Expected label size*/
  260 + CGSize labelsize = [PNLineChart sizeOfString:pdata.textDescription
  261 + withWidth:maxLabelWidth
  262 + font:[UIFont systemFontOfSize:self.legendFontSize]];
  263 +
  264 +
  265 + // Add inflexion type
  266 + [legendViews addObject:[self drawInflexion:legendCircle * .8
  267 + center:CGPointMake(x + legendCircle / 2, y + singleRowHeight / 2)
  268 + andColor:pdata.color]];
  269 +
  270 + UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(x + legendCircle, y, maxLabelWidth, labelsize.height)];
  271 + label.text = pdata.textDescription;
  272 + label.font = [UIFont systemFontOfSize:self.legendFontSize];
  273 + label.lineBreakMode = NSLineBreakByWordWrapping;
  274 + label.numberOfLines = 0;
  275 + x += self.legendStyle == PNLegendItemStyleStacked ? 0 : labelsize.width + legendCircle;
  276 + y += self.legendStyle == PNLegendItemStyleStacked ? labelsize.height : 0;
  277 +
  278 + totalWidth = self.legendStyle == PNLegendItemStyleStacked ? fmaxf(totalWidth, labelsize.width + legendCircle) : totalWidth + labelsize.width + legendCircle;
  279 + totalHeight = self.legendStyle == PNLegendItemStyleStacked ? fmaxf(totalHeight, labelsize.height) : totalHeight + labelsize.height;
  280 + [legendViews addObject:label];
  281 + }
  282 +
  283 + UIView *legend = [[UIView alloc] initWithFrame:CGRectMake(0, 0, totalWidth, totalHeight)];
  284 +
  285 + for (UIView* v in legendViews) {
  286 + [legend addSubview:v];
  287 + }
  288 + return legend;
  289 +}
  290 +
  291 +
  292 +- (UIImageView*)drawInflexion:(CGFloat)size center:(CGPoint)center andColor:(UIColor*)color
  293 +{
  294 + //Make the size a little bigger so it includes also border stroke
  295 + CGSize aSize = CGSizeMake(size, size);
  296 +
  297 +
  298 + UIGraphicsBeginImageContextWithOptions(aSize, NO, 0.0);
  299 + CGContextRef context = UIGraphicsGetCurrentContext();
  300 +
  301 + CGContextAddArc(context, size/2, size/ 2, size/2, 0, M_PI*2, YES);
  302 +
  303 +
  304 + //Set some fill color
  305 + CGContextSetFillColorWithColor(context, color.CGColor);
  306 +
  307 + //Finally draw
  308 + CGContextDrawPath(context, kCGPathFill);
  309 +
  310 + //now get the image from the context
  311 + UIImage *squareImage = UIGraphicsGetImageFromCurrentImageContext();
  312 +
  313 + UIGraphicsEndImageContext();
  314 +
  315 + //// Translate origin
  316 + CGFloat originX = center.x - (size) / 2.0;
  317 + CGFloat originY = center.y - (size) / 2.0;
  318 +
  319 + UIImageView *squareImageView = [[UIImageView alloc]initWithImage:squareImage];
  320 + [squareImageView setFrame:CGRectMake(originX, originY, size, size)];
  321 + return squareImageView;
  322 +}
227 @end 323 @end
@@ -128,6 +128,13 @@ @@ -128,6 +128,13 @@
128 self.pieChart.descriptionTextShadowColor = [UIColor clearColor]; 128 self.pieChart.descriptionTextShadowColor = [UIColor clearColor];
129 [self.pieChart strokeChart]; 129 [self.pieChart strokeChart];
130 130
  131 +
  132 + self.pieChart.legendStyle = PNLegendItemStyleStacked;
  133 + self.pieChart.legendFontSize = 12.0;
  134 +
  135 + UIView *legend = [self.pieChart getLegendWithMaxWidth:200];
  136 + [legend setFrame:CGRectMake(100, 400, legend.frame.size.width, legend.frame.size.width)];
  137 + [self.view addSubview:legend];
131 138
132 [self.view addSubview:self.pieChart]; 139 [self.view addSubview:self.pieChart];
133 self.changeValueButton.hidden = YES; 140 self.changeValueButton.hidden = YES;