绘制柱状统计图
把 SSTMonthColumnChart 添加到 View 上
@property (nonatomic, strong) SSTMonthColumnChart *knownColumnChart;
self.knownColumnChart = [self createColumnView];
self.knownColumnChart.valueArr = @[chineseDataArr,mathDataArr,englishDataArr];
[self.knownColumnChart showAnimation];
//柱状图
- (SSTMonthColumnChart *)createColumnView{
SSTMonthColumnChart *column = [[SSTMonthColumnChart alloc] initWithFrame:CGRectMake(0, -20, kFullScreenWidth, 125 + 20)];
/* Create an array of data sources, each array is a module data. For example, the first array can represent the average score of a class of different subjects, the next array represents the average score of different subjects in another class */
// column.valueArr = @[
// @[@[@15,@10]],//第一组元素 如果有多个元素,往该组添加,每一组只有一个元素,表示是单列柱状图| | | | |
// @[@[@15,@20]],//第二组元素
// @[@[@10,@5]],//第三组元素
// @[@[@21,@12]],
// @[@19],
// @[@12],
// @[@15],
// @[@9],
// @[@8],
// @[@6],
// @[@9],
// @[@18],
// @[@11],
// ];
/* This point represents the distance from the lower left corner of the origin. */
column.originSize = CGPointMake(50, 20);
/* The first column of the distance from the starting point */
column.drawFromOriginX = 30;
// column.backgroundColor = [UIColor purpleColor];
column.typeSpace = (kFullScreenWidth - 100 - 60 - 120)/2; //25;
column.isShowYLine = NO;
column.contentInsets = UIEdgeInsetsMake(0, 0, 0, 0);
/* Column width */
column.columnWidth = 10;
/* Column backgroundColor */
column.bgVewBackgoundColor = [UIColor clearColor]; // UIColorFromHex(COLOR_F1F3FA); //
/* X, Y axis font color */
column.drawTextColorForX_Y = [UIColor xy_createWithLightColor:UIColorFromHex(COLOR_393939) darkColor:UIColorFromHex(COLOR_FFFFFF)];
/* X, Y axis line color */
column.colorForXYLine = [UIColor xy_createWithLightColor:UIColorFromHex(COLOR_D0D5E6) darkColor:UIColorFromHex(COLOR_494F57)];
/* Each module of the color array, such as the A class of the language performance of the color is red, the color of the math achievement is green */
// column.columnBGcolorsArr = @[@[[UIColor redColor],[UIColor greenColor]],@[[UIColor blueColor],[UIColor blueColor]],@[[UIColor yellowColor],[UIColor brownColor]]];//如果为复合型柱状图 即每个柱状图分段 需要传入如上颜色数组 达到同时指定复合型柱状图分段颜色的效果
// column.columnBGcolorsArr = @[@[[UIColor redColor]],@[[UIColor blueColor]],@[[UIColor yellowColor]]];//如果为复合型柱状图 即每个柱状图分段 需要传入如上颜色数组 达到同时指定复合型柱状图分段颜色的效果
//column.xDescTextFontSize = 12;
column.columnBGcolorsArr = @[_dotColorArr,_dotColorArr,_dotColorArr];//@[[UIColor redColor],[UIColor blueColor],[UIColor yellowColor]];//如果为复合型柱状图 即每个柱状图分段 需要传入如上颜色数组 达到同时指定复合型柱状图分段颜色的效果
/* Module prompt */
column.xShowInfoText = @[@"语文",@"数学",@"英语"];
column.isShowLineChart = NO;
// column.lineValueArray = @[
// @6,
// @12,
// @10,
// @1,
// @9,
// @5,
// @9,
// @9,
// @5,
// @6,
// @4,
// @8,
// @11
// ];
// column.delegate = self;
/* Start animation */
// [column showAnimation];
[self.chartBgView addSubview:column];
return column;
}
自定义柱状统计图 SSTMonthColumnChart
//设置数据
-(void)setValueArr:(NSArray<NSArray *> *)valueArr{
_valueArr = valueArr;
CGFloat max = 0;
for (NSArray *arr in _valueArr) {
for (id number in arr) {
CGFloat currentNumber = 0;
if ([number isKindOfClass:[NSArray class]]) {
for (id sub in number) {
currentNumber += [NSString stringWithFormat:@"%@",sub].floatValue;
};
}else{
currentNumber = [NSString stringWithFormat:@"%@",number].floatValue;
}
if (currentNumber>max) {
max = currentNumber;
}
}
}
//找出数据中的最大值,重新设定最大值;当次max为3的倍数的时候,就是当前max;当不是的时候,取把max加到3的倍数就是新的max值;
int maxInt = ceilf(max*1.0);
int remNum = maxInt%3; // 1
if (remNum == 0) {
_maxHeight = maxInt;
}else {
_maxHeight = max+3-remNum;
}
_perHeight = (CGRectGetHeight(self.frame) - 30 - _originSize.y - self.contentInsets.top)/_maxHeight;
}
//显示动画
-(void)showAnimation{
[self clear];
_columnWidth = (_columnWidth<=0?30:_columnWidth); // 每个柱状图的宽度;
_columnSpace = (_columnSpace<=0?5:_columnSpace); // 每个柱状图之间的间隔;
NSInteger count = _valueArr.count * [_valueArr[0] count]; // 总共有9个柱状图
_typeSpace = (_typeSpace<=0?15:_typeSpace); // 两个类型数组之间的距离
if (count > _valueArr.count) { // 一个类型有多个数据的情况;drawFromOriginX 从x点开始绘制图;_maxWidth最大的绘制区域;
_maxWidth = count * _columnWidth + (_valueArr.count - 1) * _typeSpace + _drawFromOriginX * 2 + (count - _valueArr.count) * _columnSpace + self.originSize.x * 2;
}else {
_maxWidth = count * _columnWidth + (_valueArr.count - 1) * _typeSpace + _drawFromOriginX * 2 + self.originSize.x * 2;
}
self.BGScrollView.contentSize = CGSizeMake(_maxWidth, 0); // 图表绘制背景;
self.BGScrollView.backgroundColor = _bgVewBackgoundColor;
/* 绘制X、Y轴 可以在此改动X、Y轴字体大小 */
if (_needXandYLine) {
CAShapeLayer *layer = [CAShapeLayer layer];
[self.layerArr addObject:layer];
UIBezierPath *bezier = [UIBezierPath bezierPath];
if (self.isShowYLine) {
[bezier moveToPoint:CGPointMake(self.originSize.x, CGRectGetHeight(self.frame) - self.originSize.y)]; // 开始绘制线的地方 Y轴;
[bezier addLineToPoint:P_M(self.originSize.x, 20)];
}
[bezier moveToPoint:CGPointMake(self.originSize.x, CGRectGetHeight(self.frame) - self.originSize.y)];
[bezier addLineToPoint:P_M(_maxWidth - self.originSize.x, CGRectGetHeight(self.frame) - self.originSize.y)]; // X 轴
layer.lineWidth = 0.5;
[layer setLineDashPattern:@[@(3),@(3)]]; // 绘制虚线
layer.path = bezier.CGPath;
//layer.strokeColor = (_colorForXYLine==nil?([UIColor blackColor].CGColor):_colorForXYLine.CGColor);
layer.strokeColor = (_dashColor==nil?([UIColor darkGrayColor].CGColor):_dashColor.CGColor);
CABasicAnimation *basic = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
basic.duration = self.isShowYLine?1.5:0.75;
basic.fromValue = @(0);
basic.toValue = @(1);
basic.autoreverses = NO;
basic.fillMode = kCAFillModeForwards;
[layer addAnimation:basic forKey:nil];
[self.BGScrollView.layer addSublayer:layer];
/* 设置虚线辅助线 */ // _maxHeight += 4;
UIBezierPath *second = [UIBezierPath bezierPath];
NSInteger dottedLineNum = 3; //虚线的条数
for (NSInteger i = 0; i<dottedLineNum; i++) {
NSInteger pace = (_maxHeight) / dottedLineNum;
CGFloat height = _perHeight * (i+1)*pace; // 每个刻度之间的高度;
[second moveToPoint:P_M(_originSize.x, CGRectGetHeight(self.frame) - _originSize.y - height)]; // 是从下往上画的
[second addLineToPoint:P_M(_maxWidth - _originSize.x, CGRectGetHeight(self.frame) - _originSize.y - height)]; // 绘制虚线
CATextLayer *textLayer = [CATextLayer layer]; // Y 刻度值
textLayer.contentsScale = [UIScreen mainScreen].scale;
NSString *text =[NSString stringWithFormat:@"%ld",(i + 1) * pace];
CGFloat be = [self sizeOfStringWithMaxSize:XORYLINEMAXSIZE textFont:self.yDescTextFontSize aimString:text].width;
textLayer.frame = CGRectMake(self.originSize.x - be - 3, CGRectGetHeight(self.frame) - _originSize.y -height - 5, be, 15);
UIFont *font = [UIFont systemFontOfSize:self.yDescTextFontSize];
CFStringRef fontName = (__bridge CFStringRef)font.fontName;
CGFontRef fontRef = CGFontCreateWithFontName(fontName);
textLayer.font = fontRef;
textLayer.fontSize = font.pointSize;
CGFontRelease(fontRef);
// Y 轴刻度,暂时不用了;
//textLayer.string = text;
textLayer.foregroundColor = (_drawTextColorForX_Y==nil?[UIColor blackColor].CGColor:_drawTextColorForX_Y.CGColor);
[_BGScrollView.layer addSublayer:textLayer];
[self.layerArr addObject:textLayer];
}
CAShapeLayer *shapeLayer = [CAShapeLayer layer];
shapeLayer.path = second.CGPath; // 绘制虚线
shapeLayer.strokeColor = (_dashColor==nil?([UIColor darkGrayColor].CGColor):_dashColor.CGColor);
shapeLayer.lineWidth = 0.5;
[shapeLayer setLineDashPattern:@[@(3),@(3)]];
CABasicAnimation *basic2 = [CABasicAnimation animationWithKeyPath:@"strokeEnd"]; // 添加动画;
basic2.duration = 1.5;
basic2.fromValue = @(0);
basic2.toValue = @(1);
basic2.autoreverses = NO;
basic2.fillMode = kCAFillModeForwards;
[shapeLayer addAnimation:basic2 forKey:nil];
[self.BGScrollView.layer addSublayer:shapeLayer];
[self.layerArr addObject:shapeLayer];
}
/* 绘制X轴提示语 不管是否设置了是否绘制X、Y轴 提示语都应有 */
if (_xShowInfoText.count == _valueArr.count && _xShowInfoText.count > 0) {
NSInteger count = [_valueArr[0] count];
for (NSInteger i = 0; i<_xShowInfoText.count; i++) {
CATextLayer *textLayer = [CATextLayer layer];
CGFloat wid = count * _columnWidth + (count-1)*_columnSpace; // 整个数据模块的宽度;
CGSize size = [_xShowInfoText[i] boundingRectWithSize:CGSizeMake(wid, MAXFLOAT) options:NSStringDrawingUsesFontLeading|NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingTruncatesLastVisibleLine attributes:@{NSFontAttributeName:FONTBOLD(self.xDescTextFontSize)} context:nil].size;
textLayer.frame = CGRectMake( wid*i + i*_typeSpace + _originSize.x + _drawFromOriginX + wid/2 - size.width/2, CGRectGetHeight(self.frame) - _originSize.y+5,size.width,size.height);
textLayer.string = _xShowInfoText[i]; // 显示X轴的提示
textLayer.contentsScale = [UIScreen mainScreen].scale;
textLayer.backgroundColor = [UIColor clearColor].CGColor;
UIFont *font = FONTBOLD(self.xDescTextFontSize);
textLayer.fontSize = font.pointSize;
textLayer.foregroundColor = UIColorFromHex(0x7C819C).CGColor;
textLayer.alignmentMode = kCAAlignmentCenter;
[_BGScrollView.layer addSublayer:textLayer];
[self.layerArr addObject:textLayer];
}
}
/* 动画展示 */
for (NSInteger i = 0; i<_valueArr.count; i++) {
// valueArr 每个柱形图具体的值;
NSArray *arr = _valueArr[i];
for (NSInteger j = 0; j<arr.count; j++) { // j代表某个柱形图中的第几个值
CGFloat height = 0; // 柱状图的高度;
id colors = nil;
if ([arr[j] isKindOfClass:[NSArray class]]) { // 这个是一个柱形图有多个数据的;
NSAssert([_columnBGcolorsArr[j] isKindOfClass:[NSArray class]] &&_columnBGcolorsArr.count >= arr.count , @"when current columnItem is component,you must offer a NSArray type for item's color");
id colorssArr = _columnBGcolorsArr[i];
if ([colorssArr isKindOfClass:[NSArray class]]) {
NSArray *colorItemArr = (NSArray *)colorssArr;
colors = [colorItemArr objectOrNilAtIndex:j];
}
for (id obj in arr[j]) {
height += [obj floatValue];
}
height = height * _perHeight;
}else{ // 一个X只有一个柱形图的
height =[arr[j] floatValue] *_perHeight;
colors = (_columnBGcolorsArr.count<arr.count?[UIColor greenColor]:_columnBGcolorsArr[i]); //要用i来获取颜色才对;
NSArray *colorArr = (NSArray *)colors;
if ([colors isKindOfClass:[NSArray class]] && [colorArr count] > 0) {
colors = colors[0];
}
}
//colors 柱形图的颜色
id valueTempArr = arr[j]; // 这个已经取到了一个类型数据里的某一个元素;
id valueToArr;
if ([valueTempArr isKindOfClass:[NSArray class]]) {
NSArray *tempArr = (NSArray *)valueTempArr;
valueToArr = [tempArr objectOrNilAtIndex:0]; // 取到具体的值
}else {
valueToArr = arr[j];
}
__block CGRect columnItemRect = CGRectMake((i * arr.count + j)*(_columnWidth+_columnSpace) + i*_typeSpace + _originSize.x + _drawFromOriginX - i*_columnSpace, CGRectGetHeight(self.frame) - height - _originSize.y - 1, _columnWidth, height);
JHColumnItem *itemsView = [[JHColumnItem alloc] initWithFrame:columnItemRect perHeight:_perHeight valueArray:valueToArr colors:colors];
itemsView.clipsToBounds = YES;
//itemsView.delegate = self;
NSIndexPath *path = [NSIndexPath indexPathForRow:j inSection:i];
itemsView.index = path;
[self.showViewArr addObject:itemsView];
itemsView.frame = CGRectMake(columnItemRect.origin.x, columnItemRect.origin.y, _columnWidth, 0);
if (_isShowLineChart) { // 绘制折线
NSString *value = [NSString stringWithFormat:@"%@",_lineValueArray[i]];
float valueFloat =[value floatValue];
NSValue *lineValue = [NSValue valueWithCGPoint:P_M(CGRectGetMaxX(itemsView.frame) - _columnWidth / 2, CGRectGetHeight(self.frame) - valueFloat * _perHeight - _originSize.y -1)];
[self.drawLineValue addObject:lineValue];
}
[self.BGScrollView addSubview:itemsView];
WS(weakSelf); // weakSelf.columnSpace
[UIView animateWithDuration:1 animations:^{
itemsView.frame = CGRectMake(columnItemRect.origin.x, columnItemRect.origin.y, weakSelf.columnWidth, height);
} completion:^(BOOL finished) {
/* 动画结束后添加提示文字 */
if (finished) {
CATextLayer *textLayer = [CATextLayer layer];
[self.layerArr addObject:textLayer];
NSString *str = [NSString stringWithFormat:@"%0.0f",height / weakSelf.perHeight];
CGSize size = [str boundingRectWithSize:CGSizeMake(MAXFLOAT, 20) options:NSStringDrawingUsesFontLeading|NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingTruncatesLastVisibleLine attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:9]} context:nil].size;
textLayer.frame = CGRectMake(CGRectGetMinX(itemsView.frame), CGRectGetMinY(itemsView.frame) - size.height - 5,size.width, size.height);
CGPoint center = textLayer.position;
center.x = itemsView.center.x;
textLayer.position = center;
textLayer.string = str;
textLayer.fontSize = 9.0;
textLayer.alignmentMode = kCAAlignmentCenter;
textLayer.contentsScale = [UIScreen mainScreen].scale;
//textLayer.foregroundColor = itemsView.backgroundColor.CGColor;
textLayer.foregroundColor = weakSelf.drawTextColorForX_Y.CGColor;
[weakSelf.BGScrollView.layer addSublayer:textLayer];
//添加折线图
if (i==weakSelf.valueArr.count - 1&&j == arr.count-1 && weakSelf.isShowLineChart) {
UIBezierPath *path = [UIBezierPath bezierPath];
for (int32_t m=0;m<weakSelf.lineValueArray.count;m++) { // _lineValueArray NSArray * nil 0x0000000000000000
NSLog(@"%@",weakSelf.drawLineValue[m]);
if (m==0) {
[path moveToPoint:[weakSelf.drawLineValue[m] CGPointValue]];
}else{
[path addLineToPoint:[weakSelf.drawLineValue[m] CGPointValue]];
[path moveToPoint:[weakSelf.drawLineValue[m] CGPointValue]];
}
}
CAShapeLayer *shaper = [CAShapeLayer layer];
shaper.path = path.CGPath;
shaper.frame = self.bounds;
shaper.lineWidth = 2.5;
shaper.strokeColor = weakSelf.lineChartPathColor.CGColor;
[self.layerArr addObject:shaper];
CABasicAnimation *basic = [CABasicAnimation animationWithKeyPath:NSStringFromSelector(@selector(strokeEnd))];
basic.fromValue = @0;
basic.toValue = @1;
basic.duration = 1;
basic.delegate = self;
[shaper addAnimation:basic forKey:@"stokentoend"];
[self.BGScrollView.layer addSublayer:shaper];
}
}
}];
}
}
}
绘制圆环比例图
把 SSTRingChart 添加到 View 上
@property (strong, nonatomic)SSTRingChart *ring; /** 圆环图*/
[self.ring removeFromSuperview];
self.ring.backgroundColor = [UIColor generateDynamicColor:UIColorFromHex(COLOR_FFFFFF) darkColor:UIColorFromHex(COLOR_000000)];
self.ring.desColor = [UIColor generateDynamicColor:UIColorFromHex(COLOR_393939) darkColor:UIColorFromHex(COLOR_FFFFFF)];
self.ring.desDataArr = [knowledgeNameArr copy];
self.ring.ringWidth = 20.0;
self.ring.fillColorArray = [fillCorlorArr copy];
self.ring.valueDataArr = [valueArr copy];
self.ring.desNumArr = [knowNumArr copy];
[self.ring showAnimation];
[self.trainRingBackView addSubview: self.ring];
-(SSTRingChart *)ring{
if (!_ring) {
_ring = [[SSTRingChart alloc] initWithFrame:CGRectMake(0,0,200,200)];
_ring.xl_centerX = kFullScreenWidth/2;
_ring.xl_centerY = 125/2;
_ring.canClick = NO;
}
return _ring;
}
自定义圆环统计图 SSTRingChart
//开始动画
- (void)showAnimation {
[self.layer.sublayers makeObjectsPerformSelector:@selector(removeFromSuperlayer)]; // 清除
[pieShapeLayerArray removeAllObjects];
CGFloat lastBegin = -M_PI/2; // -0.7 从X轴上方,顺时针绘制;
CGFloat totloL = 0; // 百分比的累加
NSInteger i = 0;
//_valueDataArr = @[@(0.73),@(0.04),@(0.04),@(0.04),@(0.04),@(0.04),@(0.04),@(0.03)];
for (id obj in _valueDataArr) {
//初始化Layer
CustomShapeLayer *layer = [CustomShapeLayer layer];
//CAShapeLayer *layer = [CAShapeLayer layer] ;
UIBezierPath *path = [UIBezierPath bezierPath];
layer.strokeColor = [UIColor clearColor].CGColor;
CGFloat cuttentpace = [obj floatValue] / _totolCount * (M_PI * 2 - _itemsSpace * _valueDataArr.count); // itemsSpace 空隙的大小
totloL += [obj floatValue] / _totolCount;
[path moveToPoint:self.chartOrigin];
//圆弧 默认最右端为0,YES时为顺时针。NO时为逆时针。
[path addArcWithCenter:self.chartOrigin radius:_redius startAngle:lastBegin endAngle:lastBegin + cuttentpace clockwise:YES];
[path addArcWithCenter:self.chartOrigin radius:_redius-_ringWidth startAngle:lastBegin + cuttentpace endAngle:lastBegin clockwise:NO];
//添加到圆心直线
[path addLineToPoint:self.chartOrigin];
//路径闭合
[path closePath];
layer.centerPoint = self.chartOrigin;
layer.startAngle = lastBegin;
layer.endAngle = lastBegin+cuttentpace;
layer.radius = _redius;
layer.innerRadius = _redius-_ringWidth;
layer.innerColor = [UIColor whiteColor];
layer.path = path.CGPath;
[pieShapeLayerArray addObject:layer];
[self.layer addSublayer:layer]; // 一个一个比例模块的添加;
layer.lineWidth = _ringWidth;
if (i<_fillColorArray.count) {
layer.fillColor =[_fillColorArray[i] CGColor];
}else{
layer.fillColor =[k_COLOR_STOCK[i%k_COLOR_STOCK.count] CGColor];
}
CABasicAnimation *basic = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
basic.fromValue = @(0);
basic.toValue = @(1);
basic.duration = 0.25;
basic.fillMode = kCAFillModeForwards;
[layer addAnimation:basic forKey:@"basic"];
lastBegin += (cuttentpace+_itemsSpace);
i++;
}
}
//绘制方法
-(void)drawRect:(CGRect)rect{ // 绘制线条和文字;
CGContextRef contex = UIGraphicsGetCurrentContext();
CGFloat lastBegin = 0; // -0.7
CGFloat longLen = _redius +15; // *k_Width_Scale 30
for (NSInteger i = 0; i<_valueDataArr.count; i++) {
id obj = _valueDataArr[i];
CGFloat currentSpace = [obj floatValue] / _totolCount * (M_PI * 2 - _itemsSpace * _valueDataArr.count); // _totolCount CGFloat 1.0000000298023224
NSLog(@"%f",currentSpace); //3.4906585664064949
CGFloat midSpace = lastBegin + currentSpace / 2; // sin(midSpace) 0.98480774759283585 po cos(midSpace) -0.17364820840171452
CGPoint begin = CGPointMake(self.chartOrigin.x + sin(midSpace) * _redius, self.chartOrigin.y - cos(midSpace)*_redius);
CGPoint endx = CGPointMake(self.chartOrigin.x + sin(midSpace) * longLen, self.chartOrigin.y - cos(midSpace)*longLen);
NSLog(@"%@%@",NSStringFromCGPoint(begin),NSStringFromCGPoint(endx));
lastBegin += _itemsSpace + currentSpace;
UIColor *color;
if (_fillColorArray.count<_valueDataArr.count) {
color = k_COLOR_STOCK[i%k_COLOR_STOCK.count];
}else{
color = _fillColorArray[i];
}
[self drawLineWithContext:contex andStarPoint:begin andEndPoint:endx andIsDottedLine:NO andColor:color];
CGPoint secondP = CGPointZero;
CGFloat secondP_W = 40;
NSString *desText = (NSString *)_desDataArr[i];
NSString *desNumText = (NSString *)[self.desNumArr objectOrNilAtIndex:i];
CGSize size = [desText boundingRectWithSize:CGSizeMake(200, 100) options:NSStringDrawingUsesFontLeading attributes:@{NSFontAttributeName:FONTBOLD(9)} context:nil].size;
CGSize sizeNum = [desNumText boundingRectWithSize:CGSizeMake(200, 100) options:NSStringDrawingUsesFontLeading attributes:@{NSFontAttributeName:FONTBOLD(11)} context:nil].size;
if (midSpace<M_PI) { // 右边的文字
secondP =CGPointMake(endx.x + secondP_W, endx.y); // *k_Width_Scale
NSMutableAttributedString *attributeDesStr = [[NSMutableAttributedString alloc] initWithString:desText];
NSDictionary *attributeDesDic = @{NSFontAttributeName:FONTBOLD(9)};
[attributeDesStr addAttributes:attributeDesDic range:NSMakeRange(0,desText.length)];
[attributeDesStr addAttribute:NSForegroundColorAttributeName value:self.desColor range:NSMakeRange(0,desText.length)];
CGFloat w;
if (secondP.x + 3 + size.width > [UIScreen mainScreen].bounds.size.width) {
w = [UIScreen mainScreen].bounds.size.width - secondP.x + 3;
}else{
w = size.width;
}
CGFloat des_X = secondP.x - w; // secondP.x + 3
CGFloat des_Y = secondP.y + size.height / 2; // secondP.y - size.height / 2
[attributeDesStr drawInRect:CGRectMake(des_X, des_Y, w, size.height)];
// 知识点个数
if (desNumText.length > 0) {
NSMutableAttributedString *attributeNumStr = [[NSMutableAttributedString alloc] initWithString:desNumText];
NSDictionary *attributeNumDic = @{NSFontAttributeName:FONTBOLD(11)};
[attributeNumStr addAttributes:attributeNumDic range:NSMakeRange(0,desNumText.length-1)];
NSDictionary *attributeNumDic1 = @{NSFontAttributeName:FONTBOLD(9)};
[attributeNumStr addAttributes:attributeNumDic1 range:NSMakeRange(desNumText.length-1,1)];
[attributeNumStr addAttribute:NSForegroundColorAttributeName value:self.desColor range:NSMakeRange(0,desNumText.length)];
CGFloat desN_X = secondP.x - sizeNum.width; // secondP.x + 3
CGFloat desN_Y = secondP.y - sizeNum.height - 3; // secondP.y - size.height / 2
[attributeNumStr drawInRect:CGRectMake(desN_X, desN_Y, sizeNum.width, sizeNum.height)];
}
}else{ //左边的文字
secondP =CGPointMake(endx.x - secondP_W, endx.y);
NSMutableAttributedString *attributeDesStr = [[NSMutableAttributedString alloc] initWithString:desText];
NSDictionary *attributeDesDic = @{NSFontAttributeName:FONTBOLD(9)};
[attributeDesStr addAttributes:attributeDesDic range:NSMakeRange(0,desText.length)];
[attributeDesStr addAttribute:NSForegroundColorAttributeName value:self.desColor range:NSMakeRange(0,desText.length)];
CGFloat w = size.width;
CGFloat des_X = secondP.x + 3; // secondP.x + 3
CGFloat des_Y = secondP.y + size.height / 2; // secondP.y - size.height / 2
[attributeDesStr drawInRect:CGRectMake(des_X, des_Y,w, size.height)];
// 知识点个数
if (desNumText.length > 0) {
NSMutableAttributedString *attributeNumStr = [[NSMutableAttributedString alloc] initWithString:desNumText];
NSDictionary *attributeNumDic = @{NSFontAttributeName:FONTBOLD(11)};
[attributeNumStr addAttributes:attributeNumDic range:NSMakeRange(0,desNumText.length-1)];
NSDictionary *attributeNumDic1 = @{NSFontAttributeName:FONTBOLD(9)};
[attributeNumStr addAttributes:attributeNumDic1 range:NSMakeRange(desNumText.length-1,1)];
[attributeNumStr addAttribute:NSForegroundColorAttributeName value:self.desColor range:NSMakeRange(0,desNumText.length)];
CGFloat desN_X = secondP.x + 3; // secondP.x + 3
CGFloat desN_Y = secondP.y - sizeNum.height - 3; // secondP.y - size.height / 2
[attributeNumStr drawInRect:CGRectMake(desN_X, desN_Y, sizeNum.width, sizeNum.height)];
}
}
[self drawLineWithContext:contex andStarPoint:endx andEndPoint:secondP andIsDottedLine:NO andColor:color];
[self drawPointWithRedius:3*k_Width_Scale andColor:color andPoint:secondP andContext:contex];
}
}
部分方法实现
//触摸事件处理
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
//不能点击则不做处理了
if (!self.canClick) {
return;
}
CGPoint touchPoint = [[touches anyObject] locationInView:self];
for (CustomShapeLayer *shapeLayer in pieShapeLayerArray) {
//如果只有一个模块,那么动画就要变化了,不是简单的偏移了
if (self.valueDataArr.count == 1) {
shapeLayer.isOneSection = YES;
}
//判断选择区域
shapeLayer.clickOffset = [self preferGetUserSetValue:self.clickOffsetSpace withDefaultValue:15];
if (CGPathContainsPoint(shapeLayer.path, 0, touchPoint, YES)) {
//修改选中状态
if (shapeLayer.isSelected) {
shapeLayer.isSelected = NO;
}else{
shapeLayer.isSelected = YES;
}
NSInteger index = [pieShapeLayerArray indexOfObject:shapeLayer];
if (shapeLayer.isSelected) {
self.isExpand = YES;
}else{
self.isExpand = NO;
}
if (self.clickBlock) {
self.clickBlock(index,self.isExpand);
}
NSLog(@"点击了第几个 --- %zd\n选中 --- %d",index,self.isExpand);
} else {
shapeLayer.isSelected = NO;
}
}
}
//点击处理
-(void)setIsSelected:(BOOL)isSelected
{
_isSelected = isSelected;
CGPoint newCenterPoint = _centerPoint;
CGFloat offset = [self preferGetUserSetValue:self.clickOffset withDefaultValue:15];
if (self.isOneSection) {
[self dealOneSectionWithSelected:isSelected withOffset:offset];
return;
}
if (isSelected) {
//center 往外围移动一点 使用cosf跟sinf函数
newCenterPoint = CGPointMake(_centerPoint.x + cosf((_startAngle + _endAngle) / 2) * offset, _centerPoint.y + sinf((_startAngle + _endAngle) / 2) * offset);
}
//创建一个path
UIBezierPath *path = [UIBezierPath bezierPath];
//起始中心点改一下
[path moveToPoint:newCenterPoint];
[path addArcWithCenter:newCenterPoint radius:_radius startAngle:_startAngle endAngle:_endAngle clockwise:YES];
[path addArcWithCenter:newCenterPoint radius:_innerRadius startAngle:_endAngle endAngle:_startAngle clockwise:NO];
[path closePath];
self.path = path.CGPath;
//添加动画
CABasicAnimation *animation = [CABasicAnimation animation];
//keyPath内容是对象的哪个属性需要动画
animation.keyPath = @"path";
//所改变属性的结束时的值
animation.toValue = path;
//动画时长
animation.duration = 0.25;
//添加动画
[self addAnimation:animation forKey:nil];
}
//单个圆饼的处理
- (void)dealOneSectionWithSelected:(BOOL)isSelected withOffset:(CGFloat)offset
{
//创建一个path
UIBezierPath *originPath = [UIBezierPath bezierPath];
//起始中心点改一下
[originPath moveToPoint:_centerPoint];
[originPath addArcWithCenter:_centerPoint radius:_radius startAngle:_startAngle endAngle:_endAngle clockwise:YES];
[originPath addArcWithCenter:_centerPoint radius:_innerRadius startAngle:_endAngle endAngle:_startAngle clockwise:NO];
[originPath closePath];
//再创建一个path
UIBezierPath *path = [UIBezierPath bezierPath]; // 把圆放大就行了;
//起始中心点改一下
[path moveToPoint:_centerPoint];
[path addArcWithCenter:_centerPoint radius:_radius+offset startAngle:_startAngle endAngle:_endAngle clockwise:YES];
[path addArcWithCenter:_centerPoint radius:_innerRadius startAngle:_endAngle endAngle:_startAngle clockwise:NO];
[path closePath];
if (!isSelected) {
self.path = originPath.CGPath;
//添加动画
CABasicAnimation *animation = [CABasicAnimation animation];
//keyPath内容是对象的哪个属性需要动画
animation.keyPath = @"path";
animation.fromValue = path;
//所改变属性的结束时的值
animation.toValue = originPath;
//动画时长
animation.duration = 0.25;
//添加动画
[self addAnimation:animation forKey:nil];
}else{
self.path = path.CGPath;
//添加动画
CABasicAnimation *animation = [CABasicAnimation animation];
//keyPath内容是对象的哪个属性需要动画
animation.keyPath = @"path";
animation.fromValue = originPath;
//所改变属性的结束时的值
animation.toValue = path;
//动画时长
animation.duration = 0.25;
//添加动画
[self addAnimation:animation forKey:nil];
}
}
//绘制直线或虚线
- (void)drawLineWithContext:(CGContextRef )context andStarPoint:(CGPoint )start andEndPoint:(CGPoint)end andIsDottedLine:(BOOL)isDotted andColor:(UIColor *)color{
CGContextMoveToPoint(context, start.x, start.y);
CGContextAddLineToPoint(context, end.x, end.y);
CGContextSetLineWidth(context, 0.3);
[color setStroke];
if (isDotted) {
CGFloat ss[] = {1.5,2};
CGContextSetLineDash(context, 0, ss, 2);
}
CGContextMoveToPoint(context, end.x, end.y);
CGContextDrawPath(context, kCGPathStroke);
}
//绘制圆圈
- (void)drawPointWithRedius:(CGFloat)redius andColor:(UIColor *)color andPoint:(CGPoint)p andContext:(CGContextRef)contex{
CGContextAddArc(contex, p.x, p.y, redius, 0, M_PI * 2, YES);
[color setFill];
CGContextDrawPath(contex, kCGPathFill);
}