如何在饼图(或)饼图切片中心分配文本? [英] How to Alligned text on Piechart (or) piechart slice center?
问题描述
我想在饼图中添加文字。
UIGraphicsPushContext(上下文);
CGContextMoveToPoint(context,newCenterX,newCenterY);
CGContextAddArc(context,newCenterX,newCenterY,radius,arcOffset-(myAngle / 2),arcOffset +(myAngle / 2),0);
UIColor * color = [PIECHART_COLORS objectAtIndex:i%6];
CGContextSetFillColorWithColor(context,color.CGColor);
CGContextClosePath(context);
CGContextFillPath(context);
CGMutablePathRef arcPath = CGPathCreateMutable();
CGPathAddArc(arcPath,NULL,self.frame.size.width / 2,self.frame.size.height / 2,radius,arcOffset-(myAngle / 2),arcOffset +(myAngle / 2),0);
CGRect rect = CGPathGetBoundingBox(arcPath);
rect = CGRectMake(rect.origin.x + rect.size.width / 2,rect.origin.y + rect.size.height / 2,80,20);
//对于InnerCircle清空
CGContextMoveToPoint(context,newCenterX,newCenterY);
float innercircleRadius = IS_IPAD? 70:40;
CGContextAddArc(context,newCenterX,newCenterY,radius-innercircleRadius,arcOffset-(myAngle / 2),arcOffset +(myAngle / 2),0);
CGContextSetFillColorWithColor(context,[UIColor blackColor] .CGColor);
CGContextClosePath(context);
CGContextFillPath(context);
从上面我可以用内部部分空白区域绘制PieChart,但我无法添加文字特别的饼图切片。任何人都可以提供一些好的例子吗?
我的饼图显示完美但文字对齐方式不正确。
//对于文本我将尝试此代码
NSString * text = [NSString stringWithFormat:@%。2f %%,[[[myArray objectAtIndex:i] objectForKey:@Count] floatValue]];
[text drawInRect:rect withAttributes:@ {NSFontAttributeName:[UIFont systemFontOfSize:16],NSForegroundColorAttributeName:[UIColor redColor]}];
虽然你的问题还不清楚你究竟想要什么将标签
置于饼图
中心。我尝试了解你在上面发布的问题中所理解的内容。
首先使用 UIBezierPath
而不是 CGContext上
。我使用
我试过如果还有什么不清楚请覆盖我答案中的所有内容请随时发表评论。我还附上我的示例项目,以节省时间。
希望它有所帮助!
I want add Text in Piechart.
UIGraphicsPushContext(context);
CGContextMoveToPoint(context, newCenterX, newCenterY);
CGContextAddArc(context, newCenterX, newCenterY, radius,arcOffset-(myAngle/2),arcOffset+(myAngle/2), 0);
UIColor *color = [PIECHART_COLORS objectAtIndex:i%6];
CGContextSetFillColorWithColor(context, color.CGColor);
CGContextClosePath(context);
CGContextFillPath(context);
CGMutablePathRef arcPath = CGPathCreateMutable();
CGPathAddArc(arcPath, NULL, self.frame.size.width/2, self.frame.size.height/2, radius, arcOffset-(myAngle/2), arcOffset+(myAngle/2),0);
CGRect rect =CGPathGetBoundingBox(arcPath);
rect = CGRectMake(rect.origin.x+rect.size.width/2, rect.origin.y+rect.size.height/2, 80, 20);
// For InnerCircle Empty
CGContextMoveToPoint(context, newCenterX, newCenterY);
float innercircleRadius = IS_IPAD ? 70 : 40;
CGContextAddArc(context, newCenterX, newCenterY, radius-innercircleRadius,arcOffset-(myAngle/2),arcOffset+(myAngle/2), 0);
CGContextSetFillColorWithColor(context, [UIColor blackColor].CGColor);
CGContextClosePath(context);
CGContextFillPath(context);
From above I will able to draw PieChart with Inner part White space but I am unable to add text in particular piechart slice. Can anyone help with some good example?
My pie chart is displaying perfectly but text align is not coming in proper way.
//For Text I will Try This Code
NSString *text = [NSString stringWithFormat:@"%.2f %%",[[[myArray objectAtIndex:i] objectForKey:@"Count"] floatValue]];
[text drawInRect: rect withAttributes:@{NSFontAttributeName:[UIFont systemFontOfSize:16], NSForegroundColorAttributeName:[UIColor redColor]} ];
Although your question is quite unclear that how exactly you want to center the label
to pie slice
. I tried with what I understand from the question you posted above.
First thing is use UIBezierPath
instead of CGContext
. I used Parametric equaction of circle to calculate the boundary points of my circle.
CGPoint newPoints = CGPointMake(a + r * cos(theta), b + r * sin(theta));
// theta = angle
// r = radius
// a = centerX
// b = centerY
It will give you the points where you need to show your label. Now you just need to calculate the correct angle (center of slice) to achieve your goal.
UIBezierPath
has a method [bezierPath addArcWithCenter:center radius:radius startAngle:startAngle endAngle:endAngle clockwise:YES];
which creates an arc.
Now I'm going to share the code step by step:
Two macros:
#define TO_DEGREE(x) (x * 180.0)/M_PI
#define TO_RADIAN(x) (x * M_PI)/180.0
viewDidLoad: method to initialize the dummy data for my chart.
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
chartView.backgroundColor = [UIColor clearColor];
/// Assuming dummy data for our chartView
NSArray *gendersData = @[@{@"color": [UIColor redColor], @"title": @"Boys", @"percentage": @40},
@{@"color": [UIColor greenColor], @"title": @"Girls", @"percentage": @45},
@{@"color": [UIColor purpleColor], @"title": @"Unknown", @"percentage": @15}];
[self preparePieChartForData:gendersData];
}
preparePieChartForData: method
- (void)preparePieChartForData:(NSArray *)data {
/// We will use Parametric equaction of circle to get the boundary of circle
/*
* Parametric equation of circle
* x = a + r cos t
* y = b + r sin t
* a, b are center of circle
* t (theta) is angle
* x and y will be points which are on circumference of circle
*
270
|
_ | _
|
180 -------o------- 360
|
+ | +
|
90
*
*/
/// Thats why starting from 270.0
CGFloat lastAngle = 270.0;
for (NSDictionary *genderData in data) {
/// Getting data from dictionary
CGFloat percentage = [genderData[@"percentage"] floatValue];
UIColor *color = genderData[@"color"];
NSString *title = genderData[@"title"];
/// Calculating the angle from percentage, 360 is full circle.
CGFloat angle = lastAngle + (360 * percentage)/100.0;
[self makeSliceStartFrom:lastAngle endAt:angle radius:80.0 color: color title:title];
/// Updating lastAngle so that next angle can start just after this
lastAngle = angle;
}
}
Making pie slice method
- (void)makeSliceStartFrom:(CGFloat)startAngle
endAt:(CGFloat)endAngle
radius:(CGFloat)radius
color:(UIColor *)color
title:(NSString *)title {
/// Converting degree to radians as bezierPath accept angle in radians
CGFloat endAngleInRadians = TO_RADIAN(endAngle);
CGFloat startAngleInRadians = TO_RADIAN(startAngle);
if (endAngle >= -180.0 && endAngle < -90.0) {
/// This is because of above diagram
startAngleInRadians = TO_RADIAN(-90);
}
/// This is the center of chartView
CGPoint center = CGPointMake(chartView.bounds.size.width/2.0, chartView.bounds.size.height/2.0);
/// Initializing Bezeir path
UIBezierPath *bezierPath = [UIBezierPath bezierPath];
[bezierPath addArcWithCenter:center radius:radius startAngle:startAngleInRadians endAngle:endAngleInRadians clockwise:YES];
/// Line width of pie chart
CGFloat lineWidth = 30.0;
CGPathRef slicePath = bezierPath.CGPath;
/// Making shape layer from the path
CAShapeLayer *sliceLayer = [CAShapeLayer layer];
sliceLayer.path = slicePath;
sliceLayer.strokeColor = color.CGColor;
sliceLayer.lineWidth = lineWidth;
sliceLayer.fillColor = [UIColor clearColor].CGColor;
[chartView.layer addSublayer:sliceLayer];
/*
* ------------- LABEL PART -------------
* Adding label at center of the slice
*/
/// Creating an empty label
UILabel *lbl = [[UILabel alloc] init];
lbl.font = [UIFont systemFontOfSize:10.0];
lbl.text = title;
[lbl sizeToFit];
/// theta is the center (middle) angle of this slice
CGFloat theta = startAngleInRadians + (endAngleInRadians - startAngleInRadians)/2.0;
/// Adding lineWith and 10.0 extra in radius so that label can visible outside of the circle
CGFloat r = radius + lineWidth + 10.0;
CGFloat a = center.x;
CGFloat b = center.y;
/// Calculating points from theta and angle by using parametric equation of cricle
CGPoint newPoints = CGPointMake(a + r * cos(theta), b + r * sin(theta));
CGRect frame = lbl.frame;
/// Recalculating the origin so that label can be exact center of slice. newPoints are (0, 0) position of label.
frame.origin = CGPointMake(newPoints.x - frame.size.width/2.0, newPoints.y - frame.size.height/2.0);
lbl.frame = frame;
[chartView addSubview:lbl];
}
chartView
is a UIView
adding on self.view
in storyboard. Its size is (300.0, 300.0) and placed at center of the screen. Below is the output:
I tried to cover everything in my answer if still anything is unclear please feel free to comment. I'm also attaching my sample project for time saving.
Hope it helps!
这篇关于如何在饼图(或)饼图切片中心分配文本?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!