【Swift UI】Charts(DGCharts)でラベルをカスタマイズする方法!AxisValueFormatter

【Swift UI】Charts(DGCharts)でラベルをカスタマイズする方法!AxisValueFormatter

この記事からわかること

  • Swift/UIKitChartsライブラリ使い方
  • ラベル文言カスタマイズする方法
  • ラベルのデザインサイズカラーフォント変更方法
  • AxisValueFormatterの使い方

index

[open]

\ アプリをリリースしました /

みんなの誕生日

友達や家族の誕生日をメモ!通知も届く-みんなの誕生日-

posted withアプリーチ

環境

DGChartsでグラフのX軸とY軸に表示されるラベルのカスタマイズ方法をまとめていきます。

【Swift UI】Charts(DGCharts)でラベルをカスタマイズする方法!AxisValueFormatter

グラフの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軸(横側)に配置されるラベルは右側と左側があり、それぞれカスタマイズするにはleftAxisrightAxisから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()
【Swift UI】Charts(DGCharts)でラベルをカスタマイズする方法!AxisValueFormatter

最小値と最大値のみにラベルを付与する

グラフのラベルの最小値と最大値のみにラベルを表示したい場合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 ""
    }
}
【Swift UI】Charts(DGCharts)でラベルをカスタマイズする方法!AxisValueFormatter

X軸にタイムスタンプを持ってくる

X軸に渡せるのはDouble型のみですが、UNIX形式(自身の日付と1970年1月1日の00:00:00 UTCとの間隔)であれば日付情報を渡すことができます。日付情報をX軸に渡すとグラフ側で良い感じに横軸を時間軸に変更してくれるようです。

【Swift UI】Charts(DGCharts)でラベルをカスタマイズする方法!AxisValueFormatter

データが内部分にも時間ラベルが表示されていることがわかります。実装は以下の通りです。

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なども比較的同じように実装されているのでラベルの実装も似たような振る舞いになっています。

まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。

ご覧いただきありがとうございました。

searchbox

スポンサー

ProFile

ame

趣味:読書,プログラミング学習,サイト制作,ブログ

IT嫌いを克服するためにITパスを取得しようと勉強してからサイト制作が趣味に変わりました笑
今はCMSを使わずこのサイトを完全自作でサイト運営中〜

New Article

index