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

相关文章

软件简介:蓝湖辅助工具,减少移动端开发中控件属性的复制和粘...
现实生活中,我们听到的声音都是时间连续的,我们称为这种信...
前言最近在B站上看到一个漂亮的仙女姐姐跳舞视频,循环看了亿...
【Android App】实战项目之仿抖音的短视频分享App(附源码和...
前言这一篇博客应该是我花时间最多的一次了,从2022年1月底至...
因为我既对接过session、cookie,也对接过JWT,今年因为工作...