【Swift/UIKit】Charts(DGCharts)の使い方!折れ線グラフの実装方法

この記事からわかること
- Swift/UIKitでChartsライブラリの使い方
- 折れ線グラフや円グラフ、棒グラフの実装方法
- 複数のグラフを実装する方法
index
[open]
\ アプリをリリースしました /
環境
- Xcode:14.3.1
- iOS:16.4
- Swift:5.8.1
- UIKit
Charts(DGCharts)ライブラリとは?
iOSアプリで使用できるChartsは簡単に折れ線グラフや円グラフ、棒グラフなどの図を実装することのできるライブラリです。iOS16から標準でSwift Chartsフレームワークが追加されたことでこのライブラリの正式名称はDGChartsに変更になっているようです。またimport
文もCharts
からDGCharts
に修正されたようです。
import Charts
↓こちらに変更
import DGCharts
それでもまだまだDGChartsを使用しているアプリも多いと思うので導入方法と使い方をまとめていきたいと思います。
導入方法
DGChartsをアプリに組み込む方法としてCocoa Pods/Carthage/SPMどれも対応していますが今回はCocoa Podsを使用します。「PodFile」にpod 'DGCharts'
を追加してpod install
を実行します。
pod 'DGCharts'
※pod 'Charts'
は古いバージョンの際のpod 'ios-charts'
は別のライブラリのものなので注意してください。ライブラリ自体をios-chartsに間違えられていることが多いですが、正しくはCharts(DGCharts)です。
折れ線グラフの実装方法
DGChartsを使用して折れ線グラフを実装してみます。実装の詳細はコメントに残しています。

import UIKit
import DGCharts
class ViewController: UIViewController {
// チャート
var chartView: LineChartView!
// チャートデータ
var lineDataSet: LineChartDataSet!
// 折れ線グラフで表示するデータ(Y軸)
private let data: [Double] = [100.0, 65.0, 90.0, 30.0, 45.0]
override func viewDidLoad() {
super.viewDidLoad()
drawChart(y: data)
}
func drawChart(y: [Double]) {
// チャートビューのサイズと位置を定義
self.chartView = LineChartView(frame: CGRect(x: 0, y: 0, width: self.view.frame.width, height: 400))
chartView.center = self.view.center
// チャートに渡す用の配列を定義
var dataEntries: [ChartDataEntry] = []
// Y軸のデータリストからインデックスと値を取得し配列に格納
for (index, value) in y.enumerated() {
// X軸は配列のインデックス番号
let dataEntry = ChartDataEntry(x: Double(index), y: value)
dataEntries.append(dataEntry)
}
// 折れ線グラフ用のデータセット labelはグラフ名
lineDataSet = LineChartDataSet(entries: dataEntries, label: "グラフ名")
// グラフに反映
chartView.data = LineChartData(dataSet: lineDataSet)
// MARK: - ここからグラフデザイン設定
// x軸のラベルをbottomに表示
chartView.xAxis.labelPosition = .bottom
// x軸のラベル数をデータの数にする
chartView.xAxis.labelCount = dataEntries.count - 1
self.view.addSubview(self.chartView)
}
}
グラフのデザインを変更する

グラフのデザインを変更するにはLineChartDataSet
のプロパティを操作します。
// グラフの線の太さ
lineDataSet.lineWidth = 5.0
// グラフモード(曲線)
lineDataSet.mode = .cubicBezier
// グラフの色
lineDataSet.colors = [UIColor.orange]
// 点の色
lineDataSet.circleColors = [UIColor.red]
// 点の大きさ
lineDataSet.circleRadius = 5.0
// 塗りつぶし
lineDataSet.drawFilledEnabled = true
// ポインタ非表示
lineDataSet.drawCirclesEnabled = false
グラフ自体の機能を設定する
デフォルトではグラフの点をタップするとフォーカルが写ったり、ピンチやダブルタップでズームできるようになっています。これらを無効にするにはLineChartView
のプロパティを操作します。
// データがない場合のテキスト
chartView.noDataText = "データがありません"
// タップでの点の選択を無効
chartView.highlightPerTapEnabled = false
// ピンチでのズームを無効
chartView.pinchZoomEnabled = false
// ダブルタップでのズームを無効
chartView.doubleTapToZoomEnabled = false
// グラフアニメーション
chartView.animate(xAxisDuration: 1.0, yAxisDuration: 1.0)
またanimate
プロパティを設定することでグラフ描画時にアニメーションがついて描画されます。
ラベルのカスタマイズ
グラフに表示しているラベルをカスタマイズするにはLineChartView
のプロパティを操作します。
// グラフ名ラベルを非表示
chartView.legend.enabled = false
// Y軸右側ラベルを非表示
chartView.rightAxis.enabled = false
// y左軸最大値
chartView.leftAxis.axisMaximum = 100
// y左軸最小値
chartView.leftAxis.axisMinimum = 0
// y軸ラベルの表示個数
chartView.leftAxis.labelCount = 10
// 上からのオフセット
chartView.extraTopOffset = 30
データのポインタを画像(Image)にする
データのポインタを画像(Image)に変更するにはChartDataEntry(x:,y:,icon:)
を使用します。
let dataEntry = ChartDataEntry(x: Double(index), y: value, icon: UIImage(systemName: "iphone"))

複数のグラフを表示する

先ほどは1つのグラフのみを表示していましたが複数のグラフを表示させることも可能です。例えば2つの折れ線グラフを表示させる場合は以下のように実装することができます。
import UIKit
import DGCharts
class ViewController: UIViewController {
// 折れ線グラフで表示するデータ(Y軸)
private let data: [Double] = [100.0, 65.0, 90.0, 30.0, 45.0]
// 折れ線グラフで表示するデータ(Y軸)
private let data2: [Double] = [30.0, 34.0, 45.0, 20.0, 10.0]
override func viewDidLoad() {
super.viewDidLoad()
let dataSet = [data,data2]
drawChart(dataSet: dataSet)
}
func drawChart(dataSet: [[Double]]) {
// チャートビューのサイズと位置を定義
let chartView = LineChartView(frame: CGRect(x: 0, y: 0, width: self.view.frame.width, height: 400))
chartView.center = self.view.center
// 複数のグラフデータを保持
var chartDataEntries: [LineChartDataSet] = []
for data in dataSet {
// チャートに渡す用の配列を定義
var dataEntries: [ChartDataEntry] = []
// Y軸のデータリストからインデックスと値を取得し配列に格納
for (index, value) in data.enumerated() {
// X軸は配列のインデックス番号
let dataEntry = ChartDataEntry(x: Double(index), y: value)
dataEntries.append(dataEntry)
}
// 折れ線グラフ用のデータセット
let lineDataSet = LineChartDataSet(entries: dataEntries, label: "Test")
// グラフの線の太さ
lineDataSet.lineWidth = 3.0
// グラフモード(曲線)
lineDataSet.mode = .cubicBezier
// グラフの色
lineDataSet.colors = [UIColor.orange]
// 点の色
lineDataSet.circleColors = [UIColor.red]
// 点の大きさ
lineDataSet.circleRadius = 5.0
chartDataEntries.append(lineDataSet)
}
// グラフに反映
chartView.data = LineChartData(dataSets: chartDataEntries)
// x軸のラベルをbottomに表示
chartView.xAxis.labelPosition = .bottom
// タップでの点の選択を無効
chartView.highlightPerTapEnabled = false
// ピンチでのズームを無効
chartView.pinchZoomEnabled = false
// ダブルタップでのズームを無効
chartView.doubleTapToZoomEnabled = false
// グラフアニメーション
chartView.animate(xAxisDuration: 1.0, yAxisDuration: 1.0)
// データの説明ラベルを非表示
chartView.legend.enabled = false
// Y軸右側ラベルを非表示
chartView.rightAxis.enabled = false
// y左軸最大値
chartView.leftAxis.axisMaximum = 100
// y左軸最小値
chartView.leftAxis.axisMinimum = 0
// y軸ラベルの表示個数
chartView.leftAxis.labelCount = 10
// 上からのオフセット
chartView.extraTopOffset = 30
// 描画
self.view.addSubview(chartView)
}
}
タップした際にデータを取得する
表示されているグラフでタップした箇所のデータを取得するにはChartViewDelegate
に準拠させ、chartValueSelected
メソッドからタップ(パン)されたグラフ、データ、位置を取得することが可能になります。
extension ViewController: ChartViewDelegate {
// タップ(パン)されたグラフ、データ、位置を取得
func chartValueSelected(_ chartView: ChartViewBase, entry: ChartDataEntry, highlight: Highlight) {
// グラフ内でのタップされた座標
print(highlight.xPx, highlight.yPx)
if let dataSet = chartView.data?.dataSets[highlight.dataSetIndex] {
let dataIndex: Int = dataSet.entryIndex(entry: entry)
let data = dataSet.entryForIndex(dataIndex)
print(data.x) // X軸のデータ
print(data.y) // y軸のデータ
}
}
}
デリゲートを設定するためにchartView
のdelegate
プロパティにself
を渡すのを忘れないようにしてください。
chartView.delegate = self
また設定でhighlightPerTapEnabled
にfalse
を渡している場合はタップできなくなっているのでパン(スライド)操作のみ検知するようになります。
// タップでの点の選択を無効
chartView.highlightPerTapEnabled = false
また複数のグラフを表示している際は先にappend(lineDataSet)
した方が上になり下に表示されるグラフと重なってしまっている部分はタップイベントが取得しにくくなるので注意してください。実際にはタップでは取得できずタップできるところからパンすることで取得できました。
chartDataEntries.append(lineDataSet)
グラフをリセットする
グラフに表示しているデータをリセットしたい場合はclearValues
メソッドとclear
メソッドを使用します。これでグラフの設定も初期化されnotifyDataSetChanged
でデータの変更をUIへと反映させています。
chartView.data?.clearValues()
chartView.clear()
chartView.notifyDataSetChanged()
円グラフの実装

円グラフの実装は以下の記事を参考にしてください。
棒グラフの実装

棒グラフの実装は以下の記事を参考にしてください。
まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。
ご覧いただきありがとうございました。
個人開発に限界を感じたらiOSに特化したプログラミングスクール「iOSアカデミア」も検討してみてください!無料相談可能で「最短・最速」でiOSエンジニアになれるように手助けしてくれます。