1. 程式人生 > >iOS Swift Charts 的使用(一):折線圖的實現

iOS Swift Charts 的使用(一):折線圖的實現

螢幕快照 2018-01-05 下午5.23.09.png

最近專案中遇到了需要獲取網站上的資料,然後以折線圖的方式表示出來的需求。於是發現了swift下非常強大的圖表庫-#

下面是這個系列的幾篇彙總: 1、折線圖 2、柱狀圖 3、餅狀圖

下面開始折線圖的實現 首先,我們可以通過cocoapods 的方式,方便的匯入Charts,接下來我們就可以擼程式碼了。 因為程式碼中基本每個功能後都有註釋,所以就不多做解釋,直接貼程式碼:

func test2()
{
    //let lineChartView = LineChartView()
    lineChartView.frame = CGRect(x: 20, y: 60, width: self.view.bounds.width - 40, height: 600)
    self.view.addSubview(lineChartView)
    lineChartView.delegate = self
    
    lineChartView.backgroundColor = UIColor(red: 230/255.0, green: 253/255.0, blue: 253/255.0, alpha: 1.0)
    lineChartView.noDataText = "暫無資料"
    
    //設定互動樣式
    lineChartView.scaleYEnabled = false //取消Y軸縮放
    lineChartView.doubleTapToZoomEnabled = true //雙擊縮放
    lineChartView.dragEnabled = true //啟用拖動手勢
    lineChartView.dragDecelerationEnabled = true //拖拽後是否有慣性效果
    lineChartView.dragDecelerationFrictionCoef = 0.9  //拖拽後慣性效果的摩擦係數(0~1),數值越小,慣性越不明顯
    
    //設定X軸樣式
    let xAxis = lineChartView.xAxis
    xAxis.axisLineWidth = 1.0/UIScreen.main.scale //設定X軸線寬
    xAxis.labelPosition = .bottom //X軸的顯示位置,預設是顯示在上面的
    xAxis.drawGridLinesEnabled = false;//不繪製網格線
    xAxis.spaceMin = 4;//設定label間隔
    xAxis.axisMinimum = 0
    xAxis.labelTextColor = UIColor.blue//label文字顏色
    
    //設定Y軸樣式
    lineChartView.rightAxis.enabled = false  //不繪製右邊軸
    let leftAxis = lineChartView.leftAxis
    leftAxis.labelCount = 16 //Y軸label數量,數值不一定,如果forceLabelsEnabled等於YES, 則強制繪製制定數量的label, 但是可能不平均
    leftAxis.forceLabelsEnabled = false //不強制繪製指定數量的label
    leftAxis.axisMinimum = 0 //設定Y軸的最小值
    leftAxis.drawZeroLineEnabled = true //從0開始繪製
    //leftAxis.axisMaximum = 1000 //設定Y軸的最大值
    leftAxis.inverted = false //是否將Y軸進行上下翻轉
    leftAxis.axisLineWidth = 1.0/UIScreen.main.scale //設定Y軸線寬
    leftAxis.axisLineColor = UIColor.cyan//Y軸顏色
    //leftAxis.valueFormatter = NumberFormatter()//自定義格式
    //leftAxis.s  //數字字尾單位
    leftAxis.labelPosition = .outsideChart//label位置
    leftAxis.labelTextColor = UIColor.red//文字顏色
    leftAxis.labelFont = UIFont.systemFont(ofSize: 10)//文字字型
    
    
    //設定網格樣式
    leftAxis.gridLineDashLengths = [3.0,3.0]  //設定虛線樣式的網格線
    leftAxis.gridColor = UIColor.init(red: 200/255.0, green: 200/255.0, blue: 200/255.0, alpha: 1) //網格線顏色
    leftAxis.gridAntialiasEnabled = true //開啟抗鋸齒
    
    
    //新增限制線
    let litmitLine = ChartLimitLine(limit: 260, label: "限制線")
    litmitLine.lineWidth = 2
    litmitLine.lineColor = UIColor.green
    litmitLine.lineDashLengths = [5.0,5.0] //虛線樣式
    litmitLine.labelPosition = .rightTop  // 限制線位置
    litmitLine.valueTextColor = UIColor.brown
    litmitLine.valueFont = UIFont.systemFont(ofSize: 12)
    leftAxis.addLimitLine(litmitLine)
    leftAxis.drawLimitLinesBehindDataEnabled = true  //設定限制線繪製在折線圖的後面
    
    //設定折線圖描述及圖例樣式
    lineChartView.chartDescription?.text = "折線圖" //折線圖描述
    lineChartView.chartDescription?.textColor = UIColor.cyan  //描述字型顏色
    lineChartView.legend.form = .line  // 圖例的樣式
    lineChartView.legend.formSize = 20  //圖例中線條的長度
    lineChartView.legend.textColor = UIColor.darkGray
    
    
    //設定折線圖的資料
    let xValues = ["x1","x2","x3","x4","x5","x6","x7","x8","x9","x10","x11","x12","x13","x14","x15","x16","x17","x18","x19","x20","x21","x22","x23","x24","x25","x26"]
    lineChartView.xAxis.valueFormatter = KMChartAxisValueFormatter.init(xValues as NSArray)
    //ineChartView.xAxis.labelCount = 12
    //lineChartView.leftAxis.valueFormatter = KMChartAxisValueFormatter.init()
    //在這裡如果不需要自定義x軸的資料格式,可以使用原生的格式如下:
    //`lineChartView.xAxis.valueFormatter = IndexAxisValueFormatter.init(values: xValues)`
    let leftValueFormatter = NumberFormatter()  //自定義格式
    leftValueFormatter.positiveSuffix = "億"  //數字字尾單位
    
    lineChartView.leftAxis.valueFormatter = DefaultAxisValueFormatter.init(formatter: leftValueFormatter)
    
    var yDataArray1 = [ChartDataEntry]()
    for i in 0...xValues.count-1 {
        let y = arc4random()%500
        let entry = ChartDataEntry.init(x: Double(i), y: Double(y))
        
        yDataArray1.append(entry)
    }
    
    
    let set1 = LineChartDataSet.init(values: yDataArray1, label: "test1")
    set1.colors = [UIColor.orange]
    set1.drawCirclesEnabled = false //是否繪製轉折點
    set1.lineWidth = 1
    set1.mode = .horizontalBezier  //設定曲線是否平滑
    
    var yDataArray2 = [ChartDataEntry]();
    for i in 0...(xValues.count-1) {
        let y = arc4random()%500+1
        let entry = ChartDataEntry.init(x: Double(i), y: Double(y))
        
        yDataArray2.append(entry);
    }
    let set2 = LineChartDataSet.init(values: yDataArray2, label: "test1")
    set2.colors = [UIColor.green]
    set2.drawCirclesEnabled = false
    set2.lineWidth = 1.0
    
    let data = LineChartData.init(dataSets: [set1,set2])
    
    lineChartView.data = data
    //lineChartView.animate(xAxisDuration: 1.0, yAxisDuration: 1.0, easingOption: .easeInBack)
    lineChartView.animate(xAxisDuration: 1)  //設定動畫時間
    
}

func showMarkerView(value:String)
{
    let marker = MarkerView.init(frame: CGRect(x: 20, y: 20, width: 60, height: 20))
    marker.chartView = self.lineChartView
    let label = UILabel(frame: CGRect(x: 0, y: 0, width: 60, height: 20))
    label.text = value
    label.textColor = UIColor.white
    label.font = UIFont.systemFont(ofSize: 12)
    label.backgroundColor = UIColor.gray
    label.textAlignment = .center
    marker.addSubview(label)
    self.lineChartView.marker = marker
}

func chartValueSelected(_ chartView: ChartViewBase, entry: ChartDataEntry, highlight: Highlight)
{
    self.showMarkerView(value: "\(entry.y)")
}

在文中提到的 KMChartAxisValueFormatter 這是我自定義的一個類,用於處理x軸的資料格式。實現程式碼如下:

import Foundation

class KMChartAxisValueFormatter: NSObject,IAxisValueFormatter,IValueFormatter
{
    func stringForValue(_ value: Double, entry: ChartDataEntry, dataSetIndex: Int, viewPortHandler: ViewPortHandler?) -> String
    {
//print("======\(value)") return String(format:"%.2f%%",value) } var values:NSArray? override init() { super.init() } init(_ values: NSArray) { super.init() self.values = values } func stringForValue
(_ value: Double, axis: AxisBase?) -> String { //此處的value指的是x軸上的第幾個資料 if values == nil { return "\(value)" } //print("\(Int(value))") return self.values![Int(value)] as! String; } }

由於作者水平有限,對於文中出現的錯誤,歡迎批評、指正。