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, txtColor:self.titleColor, x: x, y: y)

        

        x += size.width

        

        

        //右面说明标签的字符串

        let rightStr =graphData.unitStr

        

        size = SwiftUtil.measureTxt(rightStr, font:self.titleFont)

        

        x = (viewWidth - (size.width + paddingRight))

        

        self.drawText(rightStr, font:self.titleFont, txtColor:self.totalColor, x: x, 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, y,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, y,self.graphItemWidth, 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, y:CGFloat)

    {

        let layer =CALayer()

        

        layer.frame =CGRectMake(0, y,CGRectGetWidth(self.frame),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, (x - lineWidth /2),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, font:UIFont, txtColor:UIColor, frame:CGRect)

    {

        let attributes =SwiftUtil.getAttribute(font, textColor: txtColor)

        

        txt.drawInRect(frame, withAttributes: attributes)

        

    }

    

    

    

}


Github上的demo下载地址:https://github.com/JayFwj/swift---/tree/master/publicVersion




 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值