项目需求,参考了其他绘图demo,自己绘制出来了,不过代码改得有点乱,添加了很多变量,时间关系没用太合适的命名,逻辑处理也没进行优化。

看看效果图(虚线区域都是画的,其他区域添加的都是控件),附上源码

#import <UIKit/UIKit.h>

typedef enum : NSUInteger {

CSYieldTypeWeek = 0,    //周收益

CSYieldTypeMonth = 1,   //月收益

CSYieldTypeYear = 2,    //年收益

} CSYieldType;  //收益类型

typedef enum : NSUInteger {

CSTimePointJanuary  = 0,         //一月份

CSTimePointFebruary,

CSTimePointMarch,

CSTimePointApril,

CSTimePointMay,             //.

CSTimePointJun,             //.

CSTimePointJuly,            //.

CSTimePointAugust,

CSTimePointSeptember,

CSTimePointOctober,

CSTimePointNovember,

CSTimePointDecember,        //十二月份

CSTimePointThisWeek,    //本周

CSTimePointLastWeek,        //上周

} CSTimePoint;

@interface CSYieldChartView : UIView

@property (nonatomic,assign)CSYieldType yieldType; //收益类型

@property (nonatomic,assign)CSTimePoint timePoint;  //时间点

@property (nonatomic,strong) NSArray *yields; //收益数组

@property (nonatomic,strong) NSArray *dayPoints;   //时间点数组

//刷新图表

- (void)refreshChartWithYields:(NSArray *)yields dayPoints:(NSArray *)dayPoints yieldType:(CSYieldType)yieldType timePoint:(CSTimePoint)timePoint;

@end

#define yieldLineSpace 4

#define lineLeftMargin 40

#define lineRightMargin 10

#define lineTopMargin 10

#define lineBottomMargin 30

#define lineWidth 0.5f

#define itemLeftMargin 16

#define itemRightMargin 16

#define itemSpace 6

#define itemWidthRatio (5/12.f)

#define positiveItemHexColor 0xe83846   //正收益条颜色值

#define negativeItemHexColor 0x17c7ba   //负收益条颜色值

#import "CSYieldChartView.h"

#import "UIColor+Addition.h"

@implementation CSYieldChartView

-(void)refreshChartWithYields:(NSArray *)yields dayPoints:(NSArray *)dayPoints yieldType:(CSYieldType)yieldType timePoint:(CSTimePoint)timePoint

{

self.yields = yields;

self.dayPoints = dayPoints;

self.yieldType = yieldType;

self.timePoint = timePoint;

[self setNeedsDisplay];

}

- (void)drawRect:(CGRect)rect

{

//声明最大的收益

float maxYield = 0;

//获取最大的收益绝对值

for (NSNumber *number in _yields) {

if (maxYield < fabs([number floatValue])) {

maxYield = fabs([number floatValue]);

}

}

//若最大收益少于10,则将最大值设为10

if (maxYield < 10.0) {

maxYield = 10.0;

}

//分几段

NSInteger sectionNum = 2;

//平均每段的收益

CGFloat sectionYield = maxYield / 2;

UIColor *currentColor = [UIColor lightGrayColor];

CGContextRef contextRef = UIGraphicsGetCurrentContext();

CGContextBeginPath(contextRef);

CGContextSetLineWidth(contextRef, lineWidth); //设置线粗

CGContextSetStrokeColorWithColor(contextRef, currentColor.CGColor);   //设置画笔颜色

//中线的y坐标

CGFloat centerLineY = (self.frame.size.height - lineTopMargin - lineBottomMargin)/2.f + lineTopMargin;

//设置段落风格

NSMutableParagraphStyle *paragraph = [[NSMutableParagraphStyle alloc] init];

paragraph.alignment = NSTextAlignmentRight;

//设置字体颜色

UIColor *textColor = [UIColor lightGrayColor];

//设置字体大小

UIFont *textFont = [UIFont systemFontOfSize:10];

//0收益中线

CGContextMoveToPoint(contextRef, lineLeftMargin, centerLineY);

CGContextAddLineToPoint(contextRef, self.frame.size.width - lineRightMargin, centerLineY);

CGContextStrokePath(contextRef);

//0收益率

[@"0%" drawInRect:CGRectMake(0, centerLineY - 7, lineLeftMargin - yieldLineSpace, lineLeftMargin) withAttributes:@{NSParagraphStyleAttributeName:paragraph,NSForegroundColorAttributeName:textColor,NSFontAttributeName:textFont}];

//线与线的垂直距离

CGFloat lineSpace = (self.frame.size.height - lineTopMargin - lineBottomMargin) / 4.f;

for (int i = 0; i < sectionNum; i++) {

CGFloat topLineY = centerLineY - lineSpace * (i + 1);

CGFloat bottomLineY = centerLineY + lineSpace * (i + 1);

//虚线 线宽与空格宽

CGFloat dashes[] = {2,1};

CGContextSetLineDash(contextRef, 0.0, dashes, 2);

CGContextSetStrokeColorWithColor(contextRef, currentColor.CGColor);   //设置画笔颜色

//中线以上

CGContextMoveToPoint(contextRef, lineLeftMargin, topLineY);

CGContextAddLineToPoint(contextRef, self.frame.size.width - lineRightMargin, topLineY);

CGContextStrokePath(contextRef);

//收益率

[[NSString stringWithFormat:@"%.f%%",sectionYield * (i + 1)] drawInRect:CGRectMake(0, topLineY - 7, lineLeftMargin - yieldLineSpace, lineLeftMargin) withAttributes:@{NSParagraphStyleAttributeName:paragraph,NSForegroundColorAttributeName:textColor,NSFontAttributeName:textFont}];

CGContextSetStrokeColorWithColor(contextRef, currentColor.CGColor);   //设置画笔颜色

//中线以下

CGContextMoveToPoint(contextRef, lineLeftMargin, bottomLineY);

CGContextAddLineToPoint(contextRef, self.frame.size.width - lineRightMargin, bottomLineY);

CGContextStrokePath(contextRef);

//负收益率

[[NSString stringWithFormat:@"-%.f%%",sectionYield * (i + 1)] drawInRect:CGRectMake(0, bottomLineY - 7, lineLeftMargin - yieldLineSpace, lineLeftMargin) withAttributes:@{NSParagraphStyleAttributeName:paragraph,NSForegroundColorAttributeName:textColor,NSFontAttributeName:textFont}];

}

if (0 == _yields.count) {

paragraph.alignment = NSTextAlignmentCenter;

NSDictionary *attributes = @{NSParagraphStyleAttributeName:paragraph,NSForegroundColorAttributeName:textColor,NSFontAttributeName:[UIFont systemFontOfSize:40]};

CGSize textSize = [@"暂无数据" sizeWithAttributes:attributes];

[@"暂无数据" drawInRect:CGRectMake(lineLeftMargin + itemLeftMargin,centerLineY - textSize.height / 2.f,self.width - lineLeftMargin - itemLeftMargin - lineRightMargin - itemRightMargin,textSize.height) withAttributes:attributes];

return;

}

NSString *lastDay = [_dayPoints lastObject];

//最多有几个柱(如果是月收益,且收益数小于22,按22算,否则按收益数多少算)

NSInteger partNum = (_yields.count < 22 && _yieldType == CSYieldTypeMonth) ? 22 : _yields.count;

paragraph.alignment = NSTextAlignmentLeft;

//绘制柱状图

CGFloat averageSpace = (self.frame.size.width - lineLeftMargin - itemLeftMargin - lineRightMargin - itemRightMargin) / (partNum - 1);

//柱宽

CGFloat itemWidth = averageSpace * itemWidthRatio;

for (int i=0; i<partNum; i++) {

if (i > _yields.count - 1)  //后面暂时还没收益就不画柱状条

{

break;

}

if (i % 5 == 0) {

//绘制日期

NSString *dayStr = nil;

if (self.yieldType == CSYieldTypeMonth && 0 == i) {

dayStr = [NSString stringWithFormat:@"%@(日)",_dayPoints[0]];

}

else

{

dayStr = [NSString stringWithFormat:@"%@",_dayPoints[i]];

}

[dayStr drawInRect:CGRectMake(lineLeftMargin + itemLeftMargin - 5 + averageSpace * i, self.frame.size.height - (lineBottomMargin - 6), 50, 15)withAttributes:@{NSParagraphStyleAttributeName:paragraph,NSForegroundColorAttributeName:textColor,NSFontAttributeName:textFont}];

}

else if (i == _yields.count - 1)    //最后一个柱状图日期

{

[[NSString stringWithFormat:@"%@",lastDay]  drawInRect:CGRectMake(lineLeftMargin + itemLeftMargin - 5 + averageSpace * i, self.frame.size.height - (lineBottomMargin - 6), 50, 15)withAttributes:@{NSParagraphStyleAttributeName:paragraph,NSForegroundColorAttributeName:textColor,NSFontAttributeName:textFont}];

}

//绘制柱状图

float yield = [_yields[i] floatValue];

float radius = itemWidth/2.f;   //柱状末尾的半圆半径

//虚线 线宽与空格宽 (之前设了虚线,现在把虚线的间隙变为0)

CGFloat dashes[] = {1,0};

CGContextSetLineDash(contextRef, 0.0, dashes, 2);

CGFloat itemX = lineLeftMargin + itemLeftMargin + averageSpace * i - itemWidth/2.f;

CGFloat itemY = centerLineY - (lineSpace * sectionNum) * yield / maxYield;

//是否要画半圆(如果收益高度低于宽度,就不画半圆)

BOOL shouldDrawCircle = (fabs(itemY - centerLineY) > itemWidth/2.f) ? YES : NO;

if (yield >= 0) {

if (shouldDrawCircle) {

itemY += radius;

}

//正收益颜色

CGContextSetStrokeColorWithColor(contextRef, [UIColor colorWithHex:positiveItemHexColor].CGColor);

CGContextSetFillColorWithColor(contextRef, [UIColor colorWithHex:positiveItemHexColor].CGColor);

}

else

{

if (shouldDrawCircle) {

itemY -= radius;

}

//负收益颜色

CGContextSetStrokeColorWithColor(contextRef, [UIColor colorWithHex:negativeItemHexColor].CGColor);

CGContextSetFillColorWithColor(contextRef, [UIColor colorWithHex:negativeItemHexColor].CGColor);

}

//        CGContextSetShadow(contextRef,CGSizeMake(2, 0) , 2);  //阴影效果

CGMutablePathRef pathRef = CGPathCreateMutable();

CGPathMoveToPoint(pathRef, NULL, itemX, centerLineY);

CGPathAddLineToPoint(pathRef, NULL, itemX, itemY);

CGPathAddLineToPoint(pathRef, NULL, itemX + itemWidth, itemY);

CGPathAddLineToPoint(pathRef, NULL, itemX + itemWidth, centerLineY);

CGPathCloseSubpath(pathRef);

CGContextAddPath(contextRef, pathRef);

CGContextFillPath(contextRef);

CGContextAddPath(contextRef, pathRef);

CGContextStrokePath(contextRef);

if (shouldDrawCircle) {

//画线末圆角

CGPathMoveToPoint(pathRef, NULL, itemX + itemWidth/2.f, itemY);

if (yield >= 0) {

CGPathAddArc(pathRef, NULL, itemX + itemWidth/2.f, itemY, itemWidth/2.f, M_PI, 0, NO);

}

else

{

CGPathAddArc(pathRef, NULL, itemX + itemWidth/2.f, itemY, itemWidth/2.f, 0, M_PI, NO);

}

CGPathCloseSubpath(pathRef);

CGContextAddPath(contextRef, pathRef);

CGContextFillPath(contextRef);

CGContextAddPath(contextRef, pathRef);

CGContextStrokePath(contextRef);

}

}

}

@end

iOS绘制收益柱状图的更多相关文章

  1. C# 绘制统计图(柱状图, 折线图, 扇形图)【转载】

    统计图形种类繁多, 有柱状图, 折线图, 扇形图等等, 而统计图形的绘制方法也有很多, 有Flash制作的统计图形, 有水晶报表生成统计图形, 有专门制图软件制作, 也有编程语言自己制作的:这里我们用 ...

  2. C# 绘制统计图(柱状图, 折线图, 扇形图)

    统计图形种类繁多, 有柱状图, 折线图, 扇形图等等, 而统计图形的绘制方法也有很多, 有Flash制作的统计图形, 有水晶报表生成统计图形, 有专门制图软件制作, 也有编程语言自己制作的:这里我们用 ...

  3. ASP.NET Core +Highchart+ajax绘制动态柱状图

    一.项目介绍利用前端Highchart,以及ajax向后台获取数据,绘制动态柱状图.hightchart其他实例可查看官网文档.[Highchart](https://www.highcharts.c ...

  4. echarts —— 绘制横向柱状图(圆角、无坐标轴)

    UI给了设计图,看了一眼觉得简单,不就是无序列表布局嘛(ul,li),后来才知道那是echarts图,好吧,样式如下: 代码如下:(渐变色没做) <!DOCTYPE html> <h ...

  5. 【转】使用DevExpress的WebChartControl控件绘制图表(柱状图、折线图、饼图)

    第一次写博,没什么经验,主要是把最近自己对Dev的一些研究贴出来大家共同探讨,有不足之处望大家帮忙斧正. WebChartControl是DevExpress控件群下的一个Web图表控件,它使用非常的 ...

  6. ios 绘制wav波形图

    最近研究了如何在iOS上绘制wav波形图.查了很多资料,都没能找到一个很完整的介绍,我这里总结一下一些经验. 首先需要了解wav的这3个重要指标:采样率.采样位数.声道数.下面以16KHz, 16Bi ...

  7. iOS绘制坐标图,折线图-Swift

    坐标图,经常会在各种各样的App中使用,最常用的一种坐标图就是折线图,根据给定的点绘制出对应的坐标图是最基本的需求.由于本人的项目需要使用折线图,第一反应就是搜索已经存在的解决方案,因为这种需求应该很 ...

  8. 转:iOS绘制一个UIView

    绘制一个UIView 绘制一个UIVIew最灵活的方式就是由它自己完成绘制.实际上你不是绘制一个UIView,你只是子类化了UIView并赋予子类绘制自己的能力.当一个UIVIew需要执行绘图操作的时 ...

  9. iOS 绘制1像素的线

    一.Point Vs Pixel iOS中当我们使用Quartz,UIKit,CoreAnimation等框架时,所有的坐标系统采用Point来衡量.系统在实际渲染到设置时会帮助我们处理Point到P ...

随机推荐

  1. $.type 怎么精确判断对象类型的 --(源码学习2)

    目标:  var a = [1,2,3];     console.log(typeof a); //->object     console.log($.type(a)); //->ar ...

  2. ASP.NET MVC5+EF6+EasyUI 后台管理系统(74)-微信公众平台开发-自定义菜单

    系列目录 引言 1.如果不借用Senparc.Weixin SDK自定义菜单,编码起来,工作量是非常之大 2.但是借助SDK似乎一切都是简单得不要不要的 3.自定义菜单无需要建立数据库表 4.自定义菜 ...

  3. [C#] 剖析 AssemblyInfo.cs - 了解常用的特性 Attribute

    剖析 AssemblyInfo.cs - 了解常用的特性 Attribute [博主]反骨仔 [原文]http://www.cnblogs.com/liqingwen/p/5944391.html 序 ...

  4. 【干货分享】流程DEMO-合同会审表

    流程名: 合同会审表  业务描述: 合同的审批及签订  流程相关文件: 流程包.xml 事务呈批表业务服务.xml 事务呈批表主数据.xml  流程说明: 1.此流程必须先进行事务呈批表流程的配置才可 ...

  5. 编译器开发系列--Ocelot语言7.中间代码

    Ocelot的中间代码是仿照国外编译器相关图书Modern Compiler Implementation 中所使用的名为Tree 的中间代码设计的.顾名思义,Tree 是一种树形结构,其特征是简单, ...

  6. RunLoop 总结:RunLoop的应用场景(一)

    参考资料 好的书籍都是值得反复看的,那好的文章,好的资料也值得我们反复看.我们在不同的阶段来相同的文章或资料或书籍都能有不同的收获,那它就是好文章,好书籍,好资料.关于iOS 中的RunLoop资料非 ...

  7. 把int*传值给char*,打印出错误的数字

    首先进入debug模式查看i的地址也就是ptr的值 以16进制位小端模式存储(一个整型四个字节,8位16进制数)(根据系统位数情况) 紧接着因为ptr是char*型指针变量,读取数据时按照一个字节一个 ...

  8. 检验你的前端基础——Sit the test

    前端小学生向大家推荐一个网站:Sit the test.如果你是一名前端工程师或者立志于此,不妨试试此网站上面的测验题. 发现 十几天前,我在奇舞周刊的一篇文章中,发现了一个国外的技能测试网站:Sit ...

  9. Fedora 22中的DNF软件包管理工具

    Introduction DNF is the The Fedora Project package manager that is able to query for information abo ...

  10. 在 Ubuntu 15.04 中使用 ubuntu-make、Eclipse 4.4、Java 8 以及 WTP

    Ubuntu 今天发布新版本了 其实昨天(2015-04-23)我就看到了 Ubuntu 发布新版本的新闻,下班后回家的第一件事就是访问 Ubuntu 的官网,很可惜,没有提供下载.今天(2015-0 ...