swift 自定义画渐变色折线图
Github上的demo下载地址:https://github.com/JayFwj/swift---/tree/master/publicVersion
============================================================================================================== ========== 以下是自定义折线图的类 ======================= ============================================================================================================== // LineGraphView.swift // publicVersion // // Created by apple on 16/3/29. // Copyright ? 2016年 Harrison. All rights reserved. //
import UIKit
class LineGraphViewController:UIView {
var graphData:LineGraphData!
//----------------------- //定义高度 //-----------------------
//标题栏高度 let titleRowHeight:CGFloat =35
//标题栏字体 let titleFont =UIFont.systemFontOfSize(12)
//标题栏字体颜色 let titleColor =UIColor.darkGrayColor()
//签收数量栏字体颜色 let signedColor =UIColor.orangeColor()
//总的数量颜色 let totalColor =UIColor.lightGrayColor()
var viewWidth:CGFloat!
func setLineGraphData(lineGraphData:LineGraphData) { self.graphData = lineGraphData
let scrollView =UIScrollView(frame:CGRectMake(0,self.titleRowHeight,CGRectGetWidth(self.frame),CGRectGetHeight(self.frame) -self.titleRowHeight))
//每一项的宽度 let dateItemWidth =self.frame.size.width /7.5
let count = lineGraphData.dataList[0].graphDataList.count
let w = (CGFloat(count ) * dateItemWidth)
let view =LineGraphView()
view.lineGraphData = lineGraphData
view.backgroundColor =UIColor.whiteColor()
view.frame =CGRectMake(0,0,w,CGRectGetHeight(self.frame) -titleRowHeight)
scrollView.addSubview(view)
scrollView.contentSize =CGSizeMake(w,CGRectGetHeight(scrollView.frame))
self.addSubview(scrollView)
}
/* // Only override drawRect: if you perform custom drawing. // An empty implementation adversely affects performance during animation. */ overridefunc drawRect(rect:CGRect) { // Drawing code
viewWidth = rect.size.width
//-------------------------------------------------------------
self.drawTitlePart() }
//画标题栏 func drawTitlePart() { let context =UIGraphicsGetCurrentContext()
//距离右面的间距 let paddingRight:CGFloat =15
var x:CGFloat =15
let y:CGFloat =0
var size =self.drawText(graphData.dateStr,font:self.titleFont,txtColor:self.titleColor,x: x,y: y)
x += size.width +10
size = self.drawText(graphData.titleStr,font: self.titleFont,y: y)
x += size.width
//右面说明标签的字符串 let rightStr =graphData.unitStr
size = SwiftUtil.measureTxt(rightStr,font:self.titleFont)
x = (viewWidth - (size.width + paddingRight))
self.drawText(rightStr,txtColor:self.totalColor,y:0)
self.drawALine(context!,y:0)
self.drawALine(context!,y:self.titleRowHeight)
}
func drawALine(context:CGContext,y:CGFloat) { let layer =CALayer()
layer.frame =CGRectMake(0,y,viewWidth,1)
layer.backgroundColor =UIColor.darkGrayColor().CGColor
self.layer.addSublayer(layer) }
func drawText(txt:NSString,font:UIFont,txtColor:UIColor,x:CGFloat,y:CGFloat) ->CGSize { let size =SwiftUtil.measureTxt(txt,font: font)
let frame =CGRectMake(x,(titleRowHeight - size.height)/2,size.width,size.height)
let attributes =SwiftUtil.getAttribute(font,textColor: txtColor)
txt.drawInRect(frame,withAttributes: attributes)
return size; }
}
class LineGraphView: UIView { //日期栏的高度 let dateRowHeight:CGFloat =35
//折线图区域的高度 var graphHeight:CGFloat!
//折线图项宽 var graphItemWidth:CGFloat!
var graphLineWidth:CGFloat =1.5
var verticalLineWidth:CGFloat =1
var dotDiameter:CGFloat =8
var numberFont:UIFont =UIFont.systemFontOfSize(14)
var dateFont:UIFont =UIFont.systemFontOfSize(14)
var graphMarginTop:CGFloat =20
//线的颜色 let lineColor =UIColor.lightGrayColor().colorWithAlphaComponent(0.6)
let dateColor =UIColor.darkGrayColor()
var lineGraphData:LineGraphData!
var itemScale:CGFloat!
overridefunc drawRect(rect:CGRect) {
let height = rect.size.height
self.graphHeight = (height -dateRowHeight)
self.graphItemWidth =SwiftUtil.ScreenWidth() /7.5
//得到数据中的最大项
var max =0
for(var i =0; i <self.lineGraphData.dataList.count; i++) { let tmax =self.lineGraphData.dataList[i].max
if(tmax > max) { max = tmax }
}
//每一项的比率所占的百分比 itemScale = (self.graphHeight -graphMarginTop) / CGFloat(max)
for(var i =0; i <self.lineGraphData.dataList.count; i++) { self.drawGraph(self.lineGraphData.dataList[i],textBelow: i % 2 == 0) }
}
func drawGraph(graphDataList:GraphDataList,textBelow:Bool) { //先画折线再画点
//完整的折线路径 let fullPath =UIBezierPath()
var lastPoint:CGPoint!
var theFirstPoint:CGPoint!
var mainColor = graphDataList.graphDataList[0].lineColor
for(var i =1; i < graphDataList.graphDataList.count; i++) { let lastOne = i -1
var item = graphDataList.graphDataList[lastOne]
var x = (CGFloat(lastOne) *self.graphItemWidth);
self.drawVerticalLine(x)
var dotX = (CGFloat(lastOne) *self.graphItemWidth) + (self.graphItemWidth) /2
var dotY = (self.graphHeight -CGFloat(item.data.floatValue) *itemScale)
let path =UIBezierPath()
//上一个点
let firstPoint =CGPointMake(dotX,dotY)
path.moveToPoint(firstPoint)
//下一个点 item = graphDataList.graphDataList[i]
x = (CGFloat(i) *self.graphItemWidth);
self.drawVerticalLine(x)
dotX = (CGFloat(i) *self.graphItemWidth) + (self.graphItemWidth) /2
dotY = (self.graphHeight -CGFloat(item.data.floatValue) *itemScale )
let secondPoint =CGPointMake(dotX,dotY)
path.addLineToPoint(secondPoint)
path.lineWidth =self.graphLineWidth
item.lineColor.setStroke()
path.stroke() }
//画第一条线和最后一条线 self.drawVerticalLine(1)
self.drawVerticalLine(CGFloat(graphDataList.graphDataList.count) * self.graphItemWidth -1)
//数字距离点的间距 let padding:CGFloat =5
//具体数字的高度 let numSize =SwiftUtil.measureTxt("22",font:self.numberFont)
let context =UIGraphicsGetCurrentContext()
//先画折线再画点
for(var i =0; i < graphDataList.graphDataList.count; i++) { let item = graphDataList.graphDataList[i]
let x = (CGFloat(i) *self.graphItemWidth)
let dotX = x + (self.graphItemWidth -self.dotDiameter) /2
let dotY = (self.graphHeight -CGFloat(item.data.floatValue) *itemScale - self.dotDiameter /2)
CGContextAddEllipseInRect(context,CGRectMake(dotX,dotY,self.dotDiameter,self.dotDiameter))
CGContextSetFillColorWithColor(context,item.dotColor.CGColor)
CGContextFillPath(context)
//画日期 let size =SwiftUtil.measureTxt(item.date,font:self.dateFont)
var y =graphHeight + (self.dateRowHeight - size.height) /2
letframe =CGRectMake(x,self.graphItemWidth,size.height)
SwiftUtil.drawText(item.date,font:self.dateFont,txtColor:self.dateColor,frame: frame)
//用于填充和渐变
let lineX = (CGFloat(i) *self.graphItemWidth) + (self.graphItemWidth) /2
let lineY = (self.graphHeight -CGFloat(item.data.floatValue) *itemScale)
//上一个点
let firstPoint =CGPointMake(lineX,lineY)
if(i ==0) { theFirstPoint = firstPoint
fullPath.moveToPoint(firstPoint) } else { fullPath.addLineToPoint(firstPoint)
lastPoint = firstPoint }
//画数字
if((graphDataList.showNumber) !=nil) { if(textBelow) { y = (dotY + self.dotDiameter + padding)
}else { y = (dotY - (size.height + padding))
if(y <0) { y = 0 }
}
let frame =CGRectMake(x,numSize.height)
SwiftUtil.drawText(item.date,font:self.numberFont,txtColor: item.lineColor,frame: frame) } }
if((graphDataList.showGradient) !=nil) { CGContextSaveGState(context)
//将渐变色的路径设置完 fullPath.addLineToPoint(CGPointMake(lastPoint.x,self.graphHeight))
//将渐变色的路径设置完 fullPath.addLineToPoint(CGPointMake(theFirstPoint.x,self.graphHeight))
CGContextAddPath(context,fullPath.CGPath)
fullPath.addClip()
//创建渐变色
let colorSpaces =CGColorSpaceCreateDeviceRGB()
let gradient =CGGradientCreateWithColors(colorSpaces,[mainColor.colorWithAlphaComponent(0.7).CGColor,mainColor.colorWithAlphaComponent(0.2).CGColor],[0,1.0])
CGContextDrawLinearGradient(context,gradient,CGPoint.zero,CGPointMake(0,self.graphHeight),CGGradientDrawingOptions.DrawsBeforeStartLocation)
CGContextRestoreGState(context) }
//画日期上的分隔线
self.drawALine(context!,y:self.graphHeight)
}
//画横线
func drawALine(context:CGContext,1)
layer.backgroundColor =UIColor.darkGrayColor().CGColor
self.layer.addSublayer(layer) }
//画竖线
func drawVerticalLine(x:CGFloat) { let lineWidth:CGFloat =1
let context =UIGraphicsGetCurrentContext()
CGContextMoveToPoint(context,(x - lineWidth /2),0)
CGContextAddLineToPoint(context,self.graphHeight)
CGContextSetStrokeColorWithColor(context,lineColor.CGColor)
CGContextSetLineWidth(context,lineWidth)
CGContextStrokePath(context)
}
}
class LineGraphData { var dateStr:NSString!
var titleStr:NSString!
var unitStr:NSString!
var dataList:[GraphDataList]!
}
class GraphDataList {
var max:Int!
var showGradient:Bool!
var showNumber:Bool!
var graphDataList:[GraphDataItem]!
}
class GraphDataItem {
var data:NSString!
var date:NSString!
var lineColor:UIColor!
var dotColor:UIColor!
}
============================================================================================================== ========== 以下调用折线图的viewController ======================= ==============================================================================================================
import UIKit
class ViewController: UIViewController {
overridefunc viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view,typically from a nib.
self.view.backgroundColor =UIColor.whiteColor()
let height:CGFloat =350
let frame =CGRectMake(0,60,SwiftUtil.ScreenWidth(),height)
let lineGraphView =LineGraphViewController()
lineGraphView.frame = frame
lineGraphView.backgroundColor =UIColor.whiteColor()
lineGraphView.setLineGraphData(self.getDataForLineGraph())
self.view.addSubview(lineGraphView)
}
func getDataForLineGraph() ->LineGraphData { let data =LineGraphData()
data.dateStr ="2016-03"
data.titleStr ="收支报表"
data.unitStr ="单位:元"
data.dataList = [GraphDataList]()
var max:Int =0
var lineColors = [UIColor.greenColor(),UIColor.blueColor()]
// var tempRandomColors = [UIColor.greenColor(),UIColor.blueColor(),UIColor.orangeColor(),UIColor.purpleColor(),UIColor.blackColor()]
for(var j =0; j < lineColors.count; j++) { let graphaDataList =GraphDataList()
graphaDataList.graphDataList = [GraphDataItem]()
for(var i =0; i <31; i++) { let item =GraphDataItem()
//随机生成的出货票数 let total =arc4random_uniform(30) +1
item.data ="(total)"
item.date ="(i +1)"
//let ri = arc4random_uniform(UInt32(tempRandomColors.count))
item.lineColor = lineColors[j]// tempRandomColors[Int(ri)] // UIColor.darkGrayColor()
item.dotColor = lineColors[j]//UIColor.orangeColor()
graphaDataList.graphDataList.append(item)
if(Int(total) > max) { max = Int(total); } }
graphaDataList.max = max;
data.dataList.append(graphaDataList)
}
return data;
}
}
//===================得到屏幕尺寸,测量文本宽度等的工具方法====================
// // SwiftUtil.swift // CRMForSwift // // Created by apple on 16/1/5. // Copyright ? 2016年 Harrison. All rights reserved. //
import UIKit
class SwiftUtil: NSObject {
classfunc ScreenWidth() ->CGFloat { returnUIScreen.mainScreen().bounds.width;
}
classfunc ScreenHeight() ->CGFloat { returnUIScreen.mainScreen().bounds.height;
}
classfunc StateBarHeight() ->CGFloat { returnUIApplication.sharedApplication().statusBarFrame.size.height;
}
classfunc getAppdelegate() ->AppDelegate { returnUIApplication.sharedApplication().delegateas!AppDelegate;
}
classfunc getAttribute(font:UIFont,textColor:UIColor) ->[String:AnyObject] { let style =NSMutableParagraphStyle()
style.alignment =NSTextAlignment.Center
let attribute = [NSFontAttributeName:font,NSForegroundColorAttributeName:textColor, NSParagraphStyleAttributeName:style]
return attribute }
classfunc measureTxt(str:NSString,font:UIFont) ->CGSize { let attributes = [NSFontAttributeName:font];
return str.sizeWithAttributes(attributes) }
classfunc drawText(txt:NSString,frame:CGRect) { let attributes =SwiftUtil.getAttribute(font,textColor: txtColor)
txt.drawInRect(frame,withAttributes: attributes)
}
} Github上的demo下载地址:https://github.com/JayFwj/swift---/tree/master/publicVersion (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |