【Swift/UIKit】Charts(DGCharts)の使い方!折れ線グラフの実装方法
この記事からわかること
- Swift/UIKitでChartsライブラリの使い方
- 折れ線グラフや円グラフ、棒グラフの実装方法
- 機能やデザインを設定するには?
- ポインタをアイコンに変更するには?
- 複数のグラフを実装する方法
index
[open]
\ アプリをリリースしました /
友達や家族の誕生日をメモ!通知も届く-みんなの誕生日-
posted withアプリーチ
環境
- Xcode:15.0.1
- iOS:17.1
- Swift:5.9
- macOS:Sonoma 14.1
Charts(DGCharts)ライブラリとは?
iOSアプリで使用できるChartsは簡単に折れ線グラフや円グラフ、棒グラフなどの図を実装することのできるライブラリです。iOS16から標準でSwift Chartsフレームワークが追加されたことでこのライブラリの正式名称はDGChartsに変更になっているようです。またimport
文もCharts
からDGCharts
に修正されたようです。
import Charts
↓こちらに変更
import DGCharts
またDGCharts
はAndroidのMPAndroidChart
と同じ開発者であり、基本的な操作やAPIなども比較的同じように実装されているようでした。
それでもまだまだ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を使用して折れ線グラフを実装してみます。どのグラフでも基本的に以下の流れでグラフを作成していきます。
DGChartsでグラフを実装する流れ
- 元データの準備
- 元データをEntry型に変換したリストを準備
- グラフ線やポインタなどの機能、デザインなどを設定
- ラベルやグラフなどの機能、デザインなどを設定
- グラフのデータに格納
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
のプロパティを操作します。
他にもデータ数が多い場合に一部分だけを最初にズームした状態にするためのsetVisibleXRangeMaximum
などがあります。※印がついている設定はchartView.data
プロパティにデータを格納した後でないと動作しないので注意してください。
// データがない場合のテキスト
chartView.noDataText = "データがありません"
// タップでの点の選択を無効
chartView.highlightPerTapEnabled = false
// ピンチでのズームを無効
chartView.pinchZoomEnabled = false
// データの最大表示範囲を制限 (データ数が多い場合横にスクロールで表示エリアを移動可能)
chartView.setVisibleXRangeMaximum(10) // ※
// データの最小表示範囲を制限 (データ数が多い場合横にスクロールで表示エリアを移動可能)
chartView.setVisibleXRangeMinimum(5) // ※
// データの表示位置を指定したX軸の値にする(インデックスではなくX軸の値を指定)
chartView.moveViewToX(Double(data.count - 1)) // ※
// 選択したX軸の位置をハイライト表示
chartView.highlightValue(x: 5, dataSetIndex: 0) // ※
// 表示されているデータの一番低い値を取得
chartView.lowestVisibleX
// 表示されているデータの一番高い値を取得
chartView.highestVisibleX
// ダブルタップでのズームを無効
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"))
一度に表示するデータ数が多い場合は非表示になってしまうのでmaxVisibleCount
で明示的に表示させたい個数を指定することができます。デフォルト値は100
です。
// 表示するデータ値数を指定
chartView.maxVisibleCount = 200
複数のグラフを表示する
先ほどは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)
// タップされた位置にあるデータを取得
print(entry.x, entry.y)
}
}
そのほかのデリゲートメソッドに関しては以下の記事を参考にしてください。
グラフをリセットする
グラフに表示しているデータをリセットしたい場合はclearValues
メソッドとclear
メソッドを使用します。これでグラフの設定も初期化されnotifyDataSetChanged
でデータの変更をUIへと反映させています。
chartView.data?.clearValues()
chartView.clear()
chartView.notifyDataSetChanged()
円グラフの実装
円グラフの実装は以下の記事を参考にしてください。
棒グラフの実装
棒グラフの実装は以下の記事を参考にしてください。
まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。
ご覧いただきありがとうございました。