【Swift/DGCharts】ChartViewDelegateで取得できるジェスチャーイベント
この記事からわかること
- SwiftのDGChartsライブラリの使い方
- ChartViewDelegateで取得できるジェスチャーイベントの種類
- タップやパン、スワイプなどを検知する方法
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
ChartViewDelegateプロトコル
DGCharts
ではグラフをタップやパン、スワイプされたことを検知して処理を実装するためのデリゲートメソッドがChartViewDelegate
プロトコルから提供されています。
@objc
public protocol ChartViewDelegate
{
/// チャート内で値が選択されたときに呼び出される
@objc optional func chartValueSelected(_ chartView: ChartViewBase, entry: ChartDataEntry, highlight: Highlight)
/// チャートでパンを停止したときに呼び出される
@objc optional func chartViewDidEndPanning(_ chartView: ChartViewBase)
/// 「何も選択されていない場合」、または「選択解除」が行われたときに呼び出される
@objc optional func chartValueNothingSelected(_ chartView: ChartViewBase)
/// ピンチ/ズームジェスチャによってチャートが拡大縮小/ズームされるときに呼び出される
@objc optional func chartScaled(_ chartView: ChartViewBase, scaleX: CGFloat, scaleY: CGFloat)
/// スワイプジェスチャによってチャートが移動/変換されたときに呼び出される
@objc optional func chartTranslated(_ chartView: ChartViewBase, dX: CGFloat, dY: CGFloat)
/// アニメーションが停止するときに呼び出される
@objc optional func chartView(_ chartView: ChartViewBase, animatorDidStop animator: Animator)
}
ChartViewDelegateを準拠させる
それぞれのデリゲートメソッドを使用するためにはChartViewDelegate
プロトコルをViewController
に準拠させて、実装しているグラフビューのdelegate
プロパティに自身を設定するだけです。
extension ViewController: ChartViewDelegate {
// 必要なデリゲートメソッドを定義
}
chartView.delegate = self
値が選択されたことを検知する
値が選択(タップやパン)されたことを検知するには以下のメソッドを使用します。このデリゲートメソッド内では引数entry
からタップされた位置にあるデータを取得することが可能になります。
func chartValueSelected(_ chartView: ChartViewBase, entry: ChartDataEntry, highlight: Highlight) {
// グラフ内でのタップされた座標
print(highlight.xPx, highlight.yPx)
// タップされた位置にあるデータを取得
print(entry.x, entry.y)
// データセットから取得する場合
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軸のデータ
}
}
また設定でhighlightPerTapEnabled
にfalse
を渡している場合はタップできなくなっているのでパン(スライド)操作のみ検知するようになります。
// タップでの点の選択を無効
chartView.highlightPerTapEnabled = false
また複数のグラフを表示している際は先にappend(lineDataSet)
した方が上になり下に表示されるグラフと重なってしまっている部分はタップイベントが取得しにくくなるので注意してください。実際には下の階層にあるグラフはタップでは取得できずタップできるところからパンすることで取得できました。
パンが停止したことを検知する
パンが停止したことを検知するには以下のメソッドを使用します。
func chartViewDidEndPanning(_ chartView: ChartViewBase) {
print("パンが停止")
}
「何も選択されていない場合」または「選択解除」されたことを検知する
「何も選択されていない場合」または「選択解除」されたことを検知するには以下のメソッドを使用します。
func chartValueNothingSelected(_ chartView: ChartViewBase) {
print("「選択されていない状態」または「選択解除」")
}
ピンチ/ズームジェスチャでスケールが変更したことを検知する
ピンチ/ズームジェスチャでスケールが変更したことを検知するには以下のメソッドを使用します。
func chartScaled(_ chartView: ChartViewBase, scaleX: CGFloat, scaleY: CGFloat) {
print("ピンチ/ズームジェスチャが行われた")
print("スケールの変更 - X: \(scaleX), Y: \(scaleY)")
}
スワイプを検知する
スワイプしたことを検知するには以下のメソッドを使用します。
func chartTranslated(_ chartView: ChartViewBase, dX: CGFloat, dY: CGFloat) {
print("スワイプで移動した距離 - X: \(dX), Y: \(dY)")
}
アニメーションの終了を検知する
アニメーションが終了したことを検知するには以下のメソッドを使用します。
func chartView(_ chartView: ChartViewBase, animatorDidStop animator: Animator) {
print("アニメーションが終了したよ")
}
まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。
ご覧いただきありがとうございました。