【編者按】本文作者 Joyce Echessa 是渥合數(shù)位服務創(chuàng)辦人飞蹂,畢業(yè)于臺灣大學几苍,近年來專注于協(xié)助客戶進行 App 軟體以及網站開發(fā)。文中作者通過示例介紹用 ios-charts 庫創(chuàng)建簡易美觀的圖表妻坝,有助于開發(fā)者在應用中生動形象地向用戶展示數(shù)據。本文系 OneAPM 工程師編譯整理:
呈現(xiàn)大量數(shù)據時惊窖,比起表格中一行行枯燥的數(shù)據刽宪,使用圖表來形象地表示數(shù)據可以幫助用戶更好地理解。在圖表中界酒,不需要通讀所有數(shù)據資料圣拄,便能很容易地了解數(shù)據模式,從而獲取關鍵信息毁欣。圖表的使用在商業(yè) App 和健身 App 中非常常見庇谆。
本篇文章中岳掐,我們主要介紹由 Daniel Cohen Gindi 開發(fā)的 ios-charts library。ios-charts 是由 Philipp Jahoda 建立的饭耳,是非常流行的 Android 庫 MPAndroidChart 的 iOS 端口串述。有了這個庫,你可以方便快捷地在應用中添加不同類型的圖表哥攘。僅需寥寥幾行代碼剖煌,就可以制作出功能齊備、交互性強的圖表逝淹,并且高度可定制耕姊。
函數(shù)庫的主要特征:
- 8種不同的圖表類型;
- 兩個軸的縮放(用觸控手勢栅葡、分軸縮放或捏拉縮放)茉兰;
- 拖拽/平移(用觸控手勢);
- 圖表結合(線形圖欣簇、柱形圖规脸、離散圖、K 線圖熊咽、氣泡圖)莫鸭;
- 雙(分開的)Y 軸;
- 手指畫圖(用觸控手勢將數(shù)值畫入圖表)横殴;
- 數(shù)值突出顯示(自定義彈出視圖)被因;
- 多個/分離的軸;
- 儲存圖表到相冊/以 PNG/JPEG 格式輸出衫仑;
- 預定義顏色模板梨与;
- 圖例(可自動生成,可自定義)文狱;
- 自定義軸(包括 X 和Y 軸)粥鞋;
- 動畫(在 X 軸和 Y 軸上建立動畫);
- 界限(提供額外信息瞄崇,比如最大值等)呻粹;
- 全方位自定義(上色、字體苏研、圖例等浊、顏色、背景楣富、手勢凿掂、虛線等)伴榔。
開始吧纹蝴!
首先庄萎、下載本篇文章將會用到的初始示例——名為 iOSChartsDemo 的簡易應用。應用運行時塘安,你會看到有兩個項目的表格:條形圖和其他圖表糠涛。當點擊項目時,會得到空白的視圖兼犯。在本例中忍捡,筆者已創(chuàng)建了要用的兩個視圖控制器:BarChartViewController 和 ChartsViewController。
接著切黔,我們添加函數(shù)庫到項目中砸脊。你可以用 CocoaPods 安裝該庫,這里我們直接手動安裝纬霞。
下載 ios-charts 項目凌埂,這個 zip 文件包含了函數(shù)庫(名為 Charts 的文件夾)和一個示例項目(名為 ChartsDemo)。如果你想了解更多關于函數(shù)庫的知識诗芜,示例項目是很棒的資源瞳抓。
解壓縮已下載的文件,并將 Charts 文件復制粘貼到你項目(iOSChartsDemo)的根目錄下伏恐。在 Finder 中打開Charts文件孩哑,并將 Charts.xcodeproj 拖拽到 Xcode 項目中。結構如下圖所示翠桦。
接著從項目導航中選擇你的項目横蜒,并確保該 iOSChartsDemo 目標被選中。在右邊的常規(guī)選項卡中找到 Embedded Binaries 部分秤掌,點擊該部分的+
號添加圖表框架愁铺。從列表中選擇 Charts.framework 并點擊 Add。
如果你想在 Objective-C 中使用函數(shù)庫闻鉴,請參考使用說明茵乱。
用 Command-B 或選擇 Product > Build 來生成項目。如果不這樣做孟岛,當你導入 Charts 框架到你的項目時瓶竭,Xcode 會報錯——無法加載 Charts 底層模塊。
現(xiàn)在開始創(chuàng)建第一個圖表渠羞。
創(chuàng)建一個柱形圖
打開 BarChartViewController.swift 文件斤贰,添加以下聲明。
import Charts
打開故事板文件次询。我們需要添加用來顯示圖表的視圖荧恍。從文檔綱要中選擇 Bar Chart View Controller,并在屬性檢查器中取消 Extend Edges 的 Under Top Barsin 選項。我們不希望圖表自動延伸至導航欄下方送巡。
接著拖拽一個視圖到 Bar Chart View Controller 中摹菠,并按下圖定位邊界。該視圖為控制器中主視圖的子視圖骗爆。
視圖被選中后次氨,在識別檢查器中將它的類設為 BarChartView。再使用助理編輯器摘投,加入視圖的 outlet 到 BarChartViewController 類煮寡,并命名為 outletbarChartView。在 BarChartViewController 類中添加下列代碼犀呼。
@IBOutlet weak var barChartView: BarChartView!
運行項目幸撕,并從表格中選擇柱形圖,你可能會得到視圖提示信息:無可用的圖表數(shù)據外臂。
如果在沒有數(shù)據來產生圖表時杈帐,你想在空白狀態(tài)顯示其他的信息,這時候可以自定義這個提示信息专钉。在 viewDidLoad()函數(shù)底部挑童,加入下列代碼。
運行該項目跃须,可以看到自定義的提示信息站叼。
你可以為下面信息進一步添加描述。這可以用來向用戶解釋菇民,為什么圖表是空的尽楔,他們需要獲取數(shù)據來生成圖表。例如:健身 App 應該讓用戶知道在整理圖表分析之前第练,他們需要先記錄跑步數(shù)據阔馋。
barChartView.noDataTextDescription = "GIVE REASON"
添加下面的屬性到該類。我們用它來存儲一些圖表的模擬數(shù)據娇掏。
var months: [String]!
將下面的函數(shù)添加到該類呕寝,用以建立圖表。
func setChart(dataPoints: [String], values: [Double]) {
barChartView.noDataText = "You need to provide data for the chart."
}
請注意婴梧,我曾經在 viewDidLoad()函數(shù)中添加了聲明∠律遥現(xiàn)在從 viewDidLoad()中移除該聲明。我們將用 setChart()來自定義圖表塞蹭。
在 viewDidLoad()中孽江,添加以下內容到函數(shù)底部。
months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
let unitsSold = [20.0, 4.0, 6.0, 3.0, 12.0, 16.0, 4.0, 18.0, 2.0, 4.0, 5.0, 4.0]
setChart(months, values: unitsSold)
我們設置一些模擬數(shù)據番电,給出一些產品一年中每個月售出的單位數(shù)岗屏。然后,我們將數(shù)據傳給 setChart()。
讓一個圖表顯示數(shù)據这刷,我們還需創(chuàng)建一個 BarChartData 對象涎跨,并將其設置為 barChartView 的數(shù)據屬性。添加下面的代碼到 setChart()函數(shù)底部崭歧。
var dataEntries: [BarChartDataEntry] = []
for i in 0..<dataPoints.count {
let dataEntry = BarChartDataEntry(value: values[i], xIndex: i)
dataEntries.append(dataEntry)
}
let chartDataSet = BarChartDataSet(yVals: dataEntries, label: "Units Sold")
let chartData = BarChartData(xVals: months, dataSet: chartDataSet)
barChartView.data = chartData
以上代碼中,我們創(chuàng)建了一個 BarChartDataEntry 對象的數(shù)組撞牢。BarChartDataEntry 初始化需要每個數(shù)據項的值率碾、其對應的項目索引以及一個任意的標簽。
隨后屋彪,我們使用這個對象創(chuàng)建 BarChartDataSet所宰,主要用來傳遞 BarChartDataEntry 對象的數(shù)組,以及描述數(shù)據的標簽畜挥。
最后仔粥,我們用它來創(chuàng)建一個 BarChartData 對象,用來設定我們圖表視圖的數(shù)據蟹但。
運行該應用躯泰,可以看到如下圖所示有數(shù)據的柱形圖。
你可以為出現(xiàn)在視圖右下方的圖表設置說明华糖。默認情況下麦向,文本可用來設置「說明」,該說明會出現(xiàn)在圖片上客叉。參考 ofMPAndroidChart 文檔诵竭,你可以更改描述的位置,但看一下 iOS 的 API兼搏,這并沒有包括在內卵慰。函數(shù)庫仍在維護,所以可能會在之后添加佛呻。如果你想改變描述的位置裳朋,你可以修改 ChartViewBase 類(是 BarChartView 類的子類)中的 drawDescription(上下文)函數(shù)。
針對本應用吓著,我們移除描述文本再扭。在 setChart()函數(shù)的底部添加下列內容,將描述文本設為空字符串夜矗。
barChartView.descriptionText = ""
自定義圖表
你可以修改一些屬性來自定義圖表視圖的外觀泛范。下面我們來具體介紹,你也可以瀏覽文檔看看哪些可以自定義紊撕。
首先罢荡,我們修改柱形圖的默認顏色。添加下列設置到 setChart()函數(shù)的底部。
chartDataSet.colors = [UIColor(red: 230/255, green: 126/255, blue: 34/255, alpha: 1)]
以上代碼設置了與數(shù)據相關的顏色区赵。將該設定給 UIColor 對象數(shù)組惭缰。因此只要數(shù)組中有一種顏色,所有的實體均可用笼才。
如果你想給每一個數(shù)據對象設置不同的顏色漱受,那么你需要提供更多的顏色,本例中需要12種骡送。如果你的顏色數(shù)量少于實體總數(shù)昂羡,那么從坐到右將不同的顏色分配給柱形圖,直到顏色用完后重新開始分配摔踱。
API 中也自帶一些預定義顏色模板虐先,你可以用它來為數(shù)據項設定不同顏色,它們包括:
- ChartColorTemplates.liberty()
- ChartColorTemplates.joyful()
- ChartColorTemplates.pastel()
- ChartColorTemplates.colorful()
- ChartColorTemplates.vordiplom()
如下所示蛹批,使用 ChartColorTemplates.colorful()模板篮愉。
chartDataSet.colors = ChartColorTemplates.colorful()
如下所示修改 X 軸標簽的位置试躏。
barChartView.xAxis.labelPosition = .Bottom
現(xiàn)在標簽在圖表底部冗酿。
按照以下辦法可以修改圖表的背景色裁替。
barChartView.backgroundColor = UIColor(red: 189/255, green: 195/255, blue: 199/255, alpha: 1)
根據上述設定弱判,你會看到如下所示的界面昌腰。
動畫
你可以為圖表設定一些動畫遭商,使之更加生動活潑劫流。你可以使用三種主要的動畫類型方法丛忆,可以同時讓 XY 軸或者分別某個軸產生動畫熄诡。
- animate(xAxisDuration: NSTimeInterval, yAxisDuration: NSTimeInterval)
- animate(xAxisDuration: NSTimeInterval)
- animate(yAxisDuration: NSTimeInterval)
你可以加入任意的 ChartEasingOption 到以上函數(shù)诗力。選項如下:
- Linear
- EaseInQuad
- EaseOutQuad
- EaseInOutQuad
- EaseInCubic
- EaseOutCubic
- EaseInOutCubic
- EaseInQuart
- EaseOutQuart
- EaseInOutQuart
- EaseInQuint
- EaseOutQuint
- EaseInOutQuint
- EaseInSine
- EaseOutSine
- EaseInOutSine
- EaseInExpo
- EaseOutExpo
- EaseInOutExpo
- EaseInCirc
- EaseOutCirc
- EaseInOutCirc
- EaseInElastic
- EaseOutElastic
- EaseInOutElastic
- EaseInBack
- EaseOutBack
- EaseInOutBack
- EaseInBounce
- EaseOutBounce
- EaseInOutBounce
添加下行內容到 setChart()函數(shù)苇本。
運行應用,柱形圖以動畫的形式加入視圖。我們同時為兩個軸都設置2秒的動畫康栈。
修改上述狀態(tài)為:
barChartView.animate(xAxisDuration: 2.0, yAxisDuration: 2.0, easingOption: .EaseInBounce)
你會看到這行的特效如下。
界限
界限是針對所有線形圖悬荣、柱形圖和離散圖的附加功能氯迂。它允許在圖表中顯示額外的線條為特定軸(X 或 Y 軸)加限制嚼蚀。這額外的線用來設定數(shù)據的目標值轿曙,幫助用戶更容易了解是否達到界限导帝。
要在圖表中加入界限穿铆,可以添加以下代碼到 setData()函數(shù)中您单。
let ll = ChartLimitLine(limit: 10.0, label: "Target")
barChartView.rightAxis.addLimitLine(ll)
運行該應用,你可以看到一條紅線睹限,標記在單位10左右譬猫。上面的代碼中羡疗,我們在界限上添加了一個標簽染服。但是 ChartLimitLine 有另一個沒有添加標簽的初始化函數(shù),如果不想加的話可以省略柳刮。
觸控事件
如果運行應用,你會發(fā)現(xiàn)通過默認的捏拉縮放和雙擊來進行縮放痒钝。此外秉颗,如果某個柱形條被單擊,該柱形條會突出顯示送矩。很棒的是無需自己再編代碼就能使用該功能,除非你想添加更多的功能栋荸,比如當用戶單擊柱形條時有其他響應晌块。
為了檢測圖表內的選擇,我們將使用 ChartViewDelegate 協(xié)議钝尸。
修改該類的聲明如下珍促。
class BarChartViewController: UIViewController, ChartViewDelegate {
在調用 super.viewDidLoad()后面添加下列代碼到 viewDidLoad()。
barChartView.delegate = self
添加下面的函數(shù)到該類踢星。
func chartValueSelected(chartView: ChartViewBase, entry: ChartDataEntry, dataSetIndex: Int, highlight: ChartHighlight) {
println("\(entry.value) in \(months[entry.xIndex])")
}
當圖表視圖中的值被選中時澳叉,會調用上述函數(shù)。這里我們打印出被選中的月份和值沐悦。
保存圖表
你可以將圖表的當前狀態(tài)保存為圖像成洗。可以選擇將它保存到相機膠卷或者重新設置一個保存路徑藏否。
首先瓶殃,我們將添加一個保存按鈕到圖表視圖。打開故事板文件副签,并找到柱形圖表視圖控制器遥椿。拖動導航項目到視圖控制器的導航欄基矮,然后拖動柱形按鈕項,并將其放置于導航項目的右上角冠场。刪除屬性檢查器中的導航項目的標題屬性中的「標題」文本家浇。選擇柱形按鈕項,并設置其標識便于保存到屬性檢查器碴裙「直可以看到如下界面。
接著為按鈕創(chuàng)建一個消息響應舔株,命名為 saveChart莺琳,添加以下代碼到 BarChartViewController 類中。
@IBAction func saveChart(sender: UIBarButtonItem) {
}
按照下列代碼修改上面的方法载慈。
@IBAction func saveChart(sender: UIBarButtonItem) {
barChartView.saveToCameraRoll()
}
執(zhí)行該程序后惭等,當點擊保存按鈕時,圖表圖像講保存到相冊办铡,可用 Photos 應用瀏覽辞做。
下列代碼可以重新設置保存路徑。
barChartView.saveToPath(path: String, format: ChartViewBase.ImageFormat, compressionQuality: Double)
圖片格式可能是 .JPEG或 .PNG料扰,該 compressionQuality 是一種無損格式(JPEG)的壓縮質量凭豪。
更多圖表
現(xiàn)在我們看一下其他幾個圖表焙蹭。大部分我們都看過了晒杈,所以不再過多贅述。
首先孔厉,在故事板文件中找到圖表視圖控制器拯钻,在識別檢查器中,設定視圖的標簽為 Pie Chart View 的類為 PieChartView撰豺。
如下所示修改 ChartsViewController 類粪般。
import UIKit
import Charts
class ChartsViewController: UIViewController {
@IBOutlet weak var lineChartView: LineChartView!
@IBOutlet weak var pieChartView: PieChartView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
let months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun"]
let unitsSold = [20.0, 4.0, 6.0, 3.0, 12.0, 16.0]
setChart(months, values: unitsSold)
}
func setChart(dataPoints: [String], values: [Double]) {
var dataEntries: [ChartDataEntry] = []
for i in 0..<dataPoints.count {
let dataEntry = ChartDataEntry(value: values[i], xIndex: i)
dataEntries.append(dataEntry)
}
let pieChartDataSet = PieChartDataSet(yVals: dataEntries, label: "Units Sold")
let pieChartData = PieChartData(xVals: dataPoints, dataSet: pieChartDataSet)
pieChartView.data = pieChartData
var colors: [UIColor] = []
for i in 0..<dataPoints.count {
let red = Double(arc4random_uniform(256))
let green = Double(arc4random_uniform(256))
let blue = Double(arc4random_uniform(256))
let color = UIColor(red: CGFloat(red/255), green: CGFloat(green/255), blue: CGFloat(blue/255), alpha: 1)
colors.append(color)
}
pieChartDataSet.colors = colors
let lineChartDataSet = LineChartDataSet(yVals: dataEntries, label: "Units Sold")
let lineChartData = LineChartData(xVals: dataPoints, dataSet: lineChartDataSet)
lineChartView.data = lineChartData
}
}
以上代碼中,我們將 Charts 框架導入類中污桦,像之前創(chuàng)建柱形圖那樣亩歹,創(chuàng)建一個餅狀圖和一個線形圖。但需要注意的是凡橱,在柱形圖表例中我們使用的是 BarChartDataEntry小作,而現(xiàn)在使用父類 ChartDataEntry 創(chuàng)建數(shù)據項。
運行應用稼钩,選擇表格視圖中的其他圖表顾稀,可以看見一個線形圖和有顏色的餅狀圖。你的應用可能跟下圖不完全相同坝撑,因為餅狀圖的顏色是隨機的静秆。
結束語
本篇文章大致介紹了使用 ios-charts 庫創(chuàng)建的一些圖表類型粮揉,大概涉及了自定義圖表的一些內容肛循。如果你想知道這個庫的其他功能冕茅,你可以參考這個下載庫自帶的 ChartsDemo 項目的代碼亡笑,也可以看看該項目的維基百科虑绵。這個鏈接到 Wiki 頁面會引導至 MPAndroidChart 項目文檔只怎。作者在寫這篇文章時阵翎,還沒有庫的 iOS 版本的文檔說明轻绞,但其實 API 跟 Android 版本約95%都相同抱怔,當你百思不得其解時蛀柴,Android 文檔仍然可以派上用場螃概。
你可以在這里下載完整項目。
下面列出可創(chuàng)建的圖表類型鸽疾。
線形圖(圖例吊洼、簡單的設計)
線形圖(圖例、簡單的設計)
線圖(立方線)
線圖(單數(shù)據組)
復合圖(柱形圖和線圖)
柱形圖(圖例制肮、簡單設計)
柱形圖(分組數(shù)據集)
水平柱形圖
餅狀圖(有選让扒稀)
散點圖(以方形、三角形豺鼻、圓形等圖例)
K線圖(針對財經數(shù)據)
氣泡圖(由氣泡區(qū)域覆蓋來表示值)
雷達圖(蛛網圖)
本文系 OneAPM 工程師編譯整理综液。OneAPM 是應用性能管理領域的新興領軍企業(yè),能幫助企業(yè)用戶和開發(fā)者輕松實現(xiàn):緩慢的程序代碼和 SQL 語句的實時抓取儒飒。想閱讀更多技術文章谬莹,請訪問 OneAPM 官方博客。