【Swift UI】Charts(DGCharts)でラベルをカスタマイズする方法!AxisValueFormatter
この記事からわかること
- Swift/UIKitでChartsライブラリの使い方
- ラベルの文言をカスタマイズする方法
- ラベルのデザインやサイズ、カラー、フォントの変更方法
- AxisValueFormatterの使い方
index
[open]
\ アプリをリリースしました /
友達や家族の誕生日をメモ!通知も届く-みんなの誕生日-
posted withアプリーチ
環境
- Xcode:15.0.1
- iOS:17.1
- Swift:5.9
- macOS:Sonoma 14.1
DGChartsでグラフのX軸とY軸に表示されるラベルのカスタマイズ方法をまとめていきます。
グラフのX軸のカスタマイズ
X軸(縦側)に配置されるラベルをカスタマイズするにはxAxis
からXAxis
型を参照して設定していきます。
// MARK: - X軸
// x軸のラベルをbottomに表示
chartView.xAxis.labelPosition = .bottom
// X軸最大値
chartView.xAxis.axisMaximum = 4
// X軸最小値
chartView.xAxis.axisMinimum = 0
// X軸ラベルの表示個数
chartView.xAxis.labelCount = 5
// X軸ラベルを表示(デフォルト)
chartView.xAxis.enabled = true
// X軸ラベルカラー
chartView.xAxis.labelTextColor = .white
// X軸ラベル間隔
chartView.xAxis.granularity = 1.0
// X軸ラベルフォント
chartView.xAxis.labelFont = .boldSystemFont(ofSize: 12)
グラフのY軸のカスタマイズ
Y軸(横側)に配置されるラベルは右側と左側があり、それぞれカスタマイズするにはleftAxis
とrightAxis
からYAxis
型を参照して設定していきます。
// MARK: - Y軸
// Y左軸最大値
chartView.leftAxis.axisMaximum = 100
// Y左軸最小値
chartView.leftAxis.axisMinimum = 0
// Y軸ラベルの表示個数
chartView.leftAxis.labelCount = 10
// Y軸右側ラベルを非表示
chartView.rightAxis.enabled = false
// Y軸左側ラベルを表示(デフォルト)
chartView.leftAxis.enabled = true
// Y軸右側ラベルカラー
chartView.rightAxis.labelTextColor = .white
// Y軸左側ラベルカラー
chartView.leftAxis.labelTextColor = .white
// Y軸右側ラベル間隔
chartView.rightAxis.granularity = 10.0
// Y軸左側ラベル間隔
chartView.leftAxis.granularity = 10.0
// Y軸右側ラベルフォント
chartView.rightAxis.labelFont = .boldSystemFont(ofSize: 12)
// Y軸左側ラベルフォント
chartView.leftAxis.labelFont = .boldSystemFont(ofSize: 12)
ラベルの値を自由に変更するには?
グラフのX軸とY軸に配置されるラベルはグラフデータに基づいて自動的に表示されます。しかし例えば横軸を時間などにしたい場合など、任意の値に変更したい場合に対応できるようにDGChartsではAxisValueFormatter
プロトコルが用意されています。
使用方法は簡単でAxisValueFormatter
プロトコルに準拠したクラスを作成しvalueFormatter
プロパティにセットするだけです。AxisValueFormatter
プロトコルではstringForValue
メソッドの実装が必要で、この返り値がラベルに表示される文字列になります。
class AxisXChartFormatter: NSObject, AxisValueFormatter {
public func stringForValue(_ value: Double, axis: AxisBase?) -> String {
return "\(Int(value))日"
}
}
// X軸ラベルのフォーマッター
chartView.xAxis.valueFormatter = AxisXChartFormatter()
最小値と最大値のみにラベルを付与する
グラフのラベルの最小値と最大値のみにラベルを表示したい場合はstringForValue
の引数AxisBase
からグラフに適応されている最小値と最大値を取得できるのでその値と一致する時のみラベル文字列を返すようにすればOKです。
class AxisXChartFormatter: NSObject, AxisValueFormatter {
public func stringForValue(_ value: Double, axis: AxisBase?) -> String {
if value == axis?.axisMinimum {
return "開始"
} else if value == axis?.axisMaximum {
return "終了"
}
return ""
}
}
X軸にタイムスタンプを持ってくる
X軸に渡せるのはDouble
型のみですが、UNIX形式(自身の日付と1970年1月1日の00:00:00 UTCとの間隔)であれば日付情報を渡すことができます。日付情報をX軸に渡すとグラフ側で良い感じに横軸を時間軸に変更してくれるようです。
データが内部分にも時間ラベルが表示されていることがわかります。実装は以下の通りです。
struct MyLineChartView: UIViewRepresentable {
private let list: [Double: Int] = [
1735689600.0: 10, // 2024-07-01 00:00:00
1735693200.0: 15, // 2024-07-01 01:00:00
1735696800.0: 20, // 2024-07-01 02:00:00
1735700400.0: 25, // 2024-07-01 03:00:00
1735704000.0: 30, // 2024-07-01 04:00:00
1735707600.0: 35, // 2024-07-01 05:00:00
1735711200.0: 40, // 2024-07-01 06:00:00
1735714800.0: 45, // 2024-07-01 07:00:00
1735718400.0: 50, // 2024-07-01 08:00:00
1735722000.0: 55, // 2024-07-01 09:00:00
1735725600.0: 60, // 2024-07-01 10:00:00
1735729200.0: 65, // 2024-07-01 11:00:00
1735732800.0: 70, // 2024-07-01 12:00:00
1735736400.0: 75, // 2024-07-01 13:00:00
1735740000.0: 80, // 2024-07-01 14:00:00
1735743600.0: 85, // 2024-07-01 15:00:00
1735747200.0: 90, // 2024-07-01 16:00:00
1735750800.0: 95, // 2024-07-01 17:00:00
1735754400.0: 100, // 2024-07-01 18:00:00
1735758000.0: 105, // 2024-07-01 19:00:00
1735761600.0: 110, // 2024-07-01 20:00:00
1735765200.0: 115, // 2024-07-01 21:00:00
1735768800.0: 120, // 2024-07-01 22:00:00
1735772400.0: 125, // 2024-07-01 23:00:00
]
func makeUIView(context: Context) -> LineChartView {
let chartView = LineChartView(frame: CGRect(x: 0, y: 0, width: 0, height: 0))
let entries = list.sorted(by: { $0.key < $1.key }).map { key, value in
return ChartDataEntry(x: Double(key), y: Double(value))
}
let dataSet = LineChartDataSet(entries: entries, label: "グラフ名")
chartView.data = LineChartData(dataSet: dataSet)
dataSet.drawValuesEnabled = true
chartView.legend.horizontalAlignment = .center
// グラフ名ラベルを非表示
chartView.legend.enabled = false
// Y軸右側ラベルを非表示
chartView.rightAxis.enabled = false
// x軸のラベルをbottomに表示
chartView.xAxis.labelPosition = .bottom
// y軸ラベルの表示個数
chartView.xAxis.setLabelCount(8, force: true)
// X軸ラベルのフォーマッター
chartView.xAxis.valueFormatter = AxisXChartFormatter()
// 表示エリア指定(3600秒 = 1時間)
chartView.setVisibleXRangeMaximum(3600)
chartView.setVisibleXRangeMinimum(3600)
return chartView
}
func updateUIView(_ uiView: LineChartView, context: Context) {}
class AxisXChartFormatter: NSObject, AxisValueFormatter {
public func stringForValue(_ value: Double, axis: AxisBase?) -> String {
let date = Date(timeIntervalSince1970: TimeInterval(value))
let df = DateFormatter()
df.locale = Locale(identifier: "ja_JP")
df.calendar = Calendar(identifier: .japanese)
df.dateFormat = "HH時mm分"
return df.string(from: date)
}
}
}
DGCharts
はAndroidのMPAndroidChart
と同じ開発者であり、基本的な操作やAPIなども比較的同じように実装されているのでラベルの実装も似たような振る舞いになっています。
まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。
ご覧いただきありがとうございました。